diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2023-10-03 15:02:38 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2023-10-03 16:04:35 +0300 |
commit | 5478b8f55cc7055a4861c4030e0c401b5c72714c (patch) | |
tree | 3d003e5b4c1800297fcc491faffc9a006d174289 /contrib/tools | |
parent | ca778ad9bfb31839b0f05a4995753bc61db648ad (diff) | |
download | ydb-5478b8f55cc7055a4861c4030e0c401b5c72714c.tar.gz |
Intermediate changes
Diffstat (limited to 'contrib/tools')
174 files changed, 0 insertions, 150383 deletions
diff --git a/contrib/tools/swig/CHANGES b/contrib/tools/swig/CHANGES deleted file mode 100644 index 9001d018130..00000000000 --- a/contrib/tools/swig/CHANGES +++ /dev/null @@ -1,27992 +0,0 @@ -SWIG (Simplified Wrapper and Interface Generator) - -See the CHANGES.current file for changes in the current version. -See the RELEASENOTES file for a summary of changes in each release. -Issue # numbers mentioned below can be found on Github. For more details, add -the issue number to the end of the URL: https://github.com/swig/swig/issues/ - -Version 4.1.0 (24 Oct 2022) -=========================== - -2022-10-24: wsfulton, AndLLA - [R] #2386 Fix problems in shared_ptr wrappers where the class names - were not consistent when using the shared_ptr template or the actual - underlying type. - -2022-10-24: wsfulton - [R] Add support for special variable replacement in the $typemap() - special variable macro for R specific typemaps (rtype, rtypecheck, - scoercein, scoereout). - -2022-10-24: wsfulton - [R] Polymorphism in the wrappers was only working for C++ classes, - now this works for C++ structs too. - -2022-10-19: olly - [Lua] #2126 Fix type resolution between multiple SWIG-wrapped - modules. - -2022-10-17: wsfulton - [R] #2385 Add support for std::vector<std::vector<std::string>>. - -2022-10-14: murillo128 - [Javascript] #2109 Tweak unsigned long and unsigned long long typemaps - to create a v8::Number instead of v8::Integer if the value exceeds - the size of v8::Integer. Note that the v8::Number value will be - imprecise if the value is > MAX_SAFE_INTEGER. - -2022-10-14: olly - [R] Arrange that destructors of local C++ objects in the wrapper - function get run on SWIG_fail (which calls Rf_error() which calls - longjmp()). - -2022-10-14: olly - [Lua] Arrange that destructors of local C++ objects in the wrapper - function get run on SWIG_fail (which calls lua_error() which calls - longjmp()). - -2022-10-13: wsfulton - [R] Add missing SWIGTYPE *const& typemaps for supporting pointers - by const reference. - -2022-10-10: wsfulton - #2160 Fix compile error when using templates with more than one template - parameter and used as an input parameter in a virtual method in a - director class (problem affecting most of the scripting languages). - -2022-10-10: treitmayr, wsfulton - [Python, Ruby] #1811 #1823 Fix invalid code generated in some cases when - returning a pointer or reference to a director-enabled class instance. - This previously only worked in very simple cases, now return types are - resolved to fix. A bug in template instantiations using pointers also - works now. - -2022-10-06: wsfulton - [CFFI] #1966 #2200 Remove code for Common Lisp CFFI. We dropped support - for it in SWIG 4.0.0 by disabling it as the first stage. This is the - final stage for complete removal as there has been no meaningful - progress to revive it to the status of experimental language. - -2022-10-06: olly - [Python] #2390 Remove deprecated and apparently useless defarg.swg - - The only documentation is in the file itself and describes a Python - wrapper around the C function defined here, but digging though the - git history this Python wrapper doesn't seem to have ever actually - been generated by SWIG. - - This file was also marked as deprecated in 2005. - -2022-10-06: wsfulton - [Java] #2048 Fix quoting for doxygen \image command to quote the output - file name generated into the html src attribute. - -2022-10-05: benjamin-sch - [Python] added an interpreter counter to fix deinitialization - issues if multiple subinterpreters are used - -2022-10-05: olly, wsfulton - #672 Add support for parsing C++11 final classes such as: - - class X final {}; - - This no longer gives a syntax error. - -2022-10-05: wsfulton - [OCaml] Fix %rename for enum items. Previously the rename had no effect. - -2022-10-05: olly - #1465 Report errors in preprocessor expressions by default - - Until now SWIG quietly ignored such errors unless -Wextra (or -Wall - which implies -Wextra) was passed, but this is unhelpful as it tends - to hide genuine problems. To illustrate this point, enabling this - warning by default revealed a typo in the preproc_defined.i - testcase in SWIG's own testsuite. - - If you really don't want to see this warning, you can suppress it - with command line option -w202 or by using this in your interface - file: - - %warnfilter(SWIGWARN_PP_EVALUATION); - - Both will work with older versions of SWIG too. - -2022-10-04: olly - #1050 Consistently define SWIG_VERSION both at SWIG-time and in - the generated wrapper. Best practice remains to check at SWIG-time - where possible because that results in smaller generated wrapper - sources. - - SWIGGO and SWIGJAVASCRIPT are now defined in the generated wrappers - to match behaviour for all other target languages. - - The undocumented SWIGVERSION macro is no longer defined. - -2022-09-29: olly - #2303 SWIG's internal hash tables now use a better hash function. - - The old hash function only considerd the last five characters - plus the least significant bit of the last-but-sixth character, - which as you might guess generated a lot of many-way collisions. - - This change seems to give about a 4% reduction in wallclock time - for processing li_std_list_wrap.i from the testsuite for Python. - The hash collision rate for this example drops from 39% to 0! - -2022-09-29: wsfulton - #2303 Type tables are now output in a fixed order whereas previously - the order may change with any minor input code change. This shouldn't - affect users except SWIG_TypePrettyName may output a different C/C++ - typedef to a type - it's used mostly for showing errors when the type - passed to a function is wrong. - -2022-09-29: olly - [PHP] Dynamic class properties are no longer supported by default. - - Historically PHP has supported dynamic class properties and SWIG - has implemented them too (because we implement the magic __get(), - __set() and __isset() methods we need to include explicit - handling). - - PHP 8.2 deprecates dynamic class properties - initially they'll - warn, and apparently they'll not work by default in PHP 9.0: - https://wiki.php.net/rfc/deprecate_dynamic_properties - - In PHP code dynamic properties can be enabled for a class by - marking that class with the attribute `#[AllowDynamicProperties]`. - - To follow this PHP change, in SWIG you now need to specify - `%feature("php:allowdynamicproperties", 1) Foo;` (or - `%feature("php:allowdynamicproperties", 1)` to enable it for - all wrapped classes). Unknown features are ignored, so you can add - it unconditionally and it'll work with older SWIG too. - - *** POTENTIAL INCOMPATIBILITY *** - -2022-09-19: wsfulton - #1484 Fixes for class inheritance with the same name in different namespaces - such as: - - namespace A { class Bar {}; } - namespace B { template<typename T, typename U> class Bar : public A::Bar {}; } - -2022-09-19: wsfulton - #2316 Remove swig.spec file and srcrpm makefile target. These are very out of date - and don't seem to be used by RPM based Linux distributions which have their - own version of swig.spec. - -2022-09-17: wsfulton - [Go, Guile, Racket, Scilab] Add throws typemaps for std::string so that thrown - string exception messages can be seen. - -2022-09-17: wsfulton - [Racket] Add throws typemaps for char * so that thrown string exception - messages can be seen from Racket. - -2022-09-17: wsfulton - [Javascript, Octave, R] Improve exceptions for %catches and exception - specifications for native types. String exception messages are shown as - the exception message instead of just the type of the exception. - -2022-09-17: wsfulton - Add missing typecheck typemaps for std::auto_ptr and std::unique_ptr to - fix overloading when using these types. - -2022-09-17: wsfulton - [Guile] Add error checking to SWIGTYPE and SWIGTYPE & in typemaps to prevent - seg faults when passing #nil to these parameter types. - -2022-09-16: wsfulton - #999 Provide SWIGTYPE MOVE typemaps in swigmove.i for implementing full - move semantics when passing parameters by value. - -2022-08-31: wsfulton - #999 Improve move semantics when using rvalue references. - The SWIGTYPE && input typemaps now assume the object has been moved. - - These typemaps have been changed assuming that after the function call, - the rvalue reference parameter has been moved. The parameter's proxy class - that owns the C++ object thus has the underlying pointer set to null - so that the (moved from, but still valid) C++ object cannot be used again - and the object is additionally deleted. - - *** POTENTIAL INCOMPATIBILITY *** - -2022-08-28: wsfulton - [Octave] SWIG now marshals a C/C++ NULL pointer into the null matrix, []. - SWIG has always marshalled the null matrix into a NULL pointer; this remains - and now we have consistency in representing a NULL pointer. - -2022-08-26: wsfulton - [Racket] SWIG now marshals a C/C++ NULL pointer into a null value by calling - scheme_make_null(), so that scheme's null? is true for a NULL C/C++ pointer value. - -2022-08-18: wsfulton - [Racket] Add support for std::unique_ptr in std_unique_ptr.i. - Add support for std::auto_ptr in std_auto_ptr.i. - -2022-08-13: wsfulton - [Guile] Add support for std::unique_ptr in std_unique_ptr.i. - Add support for std::auto_ptr in std_auto_ptr.i. - -2022-08-11: wsfulton - [Lua] Add support for std::unique_ptr in std_unique_ptr.i. - Add support for std::auto_ptr in std_auto_ptr.i. - -2022-08-05: wsfulton - [D] Fix occasional undefined behaviour with inheritance hierarchies, particularly - when using virtual inheritance as the pointers weren't correctly upcast from derived - class to base class when stored in the base's proxy class. - -2022-08-05: wsfulton - [D] Add support for std::unique_ptr in std_unique_ptr.i. - Add support for std::auto_ptr in std_auto_ptr.i. - -2022-08-03: wsfulton - [Javascript] Add support for std::unique_ptr in std_unique_ptr.i. - Add support for std::auto_ptr in std_auto_ptr.i. - -2022-08-02: wsfulton - [Octave] Add support for std::unique_ptr in std_unique_ptr.i. - Add support for std::auto_ptr in std_auto_ptr.i. - -2022-08-01: wsfulton - [Python] Add initialisers for additional members in PyHeapTypeObject - (builtin mode) for Python-3.11 - _ht_tpname, _spec_cache. - -2022-07-30: wsfulton - C++20 has deprecated std::basic_string<>::reserve() and the C++11 method - std::basic_string<>::shrink_to_fit() is a replacement that can be used. - std_string.i and std_wstring.i provided wrappers for reserve with the following - template instantiations: - - %template(string) std::basic_string<char>; - %template(wstring) std::basic_string<wchar_t>; - - The reserve method is no longer wrapped, however the shrink_to_fit() method - can be used as an alternative from the target language (the generated wrappers - call reserve() instead if C++<=20). - - Note that std::basic_string<>::reserve(size_t n) is still wrapped unchanged. - - *** POTENTIAL INCOMPATIBILITY *** - -2022-07-30: wsfulton - [Tcl] Add support for std::unique_ptr in std_unique_ptr.i. - Add support for std::auto_ptr in std_auto_ptr.i. - -2022-07-27: ZackerySpytz, olly - #1678 Support parsing C++20 templated lambdas. - -2022-07-27: ZackerySpytz, olly - #1622 Add support for the C++20 spaceship operator (<=>). - -2022-07-26: olly - [Tcl] https://sourceforge.net/p/swig/bugs/977/ - Fix handling of long long on 32-bit platforms. This fix raises - SWIG's minimum supported Tcl version to 8.4.0 (which was released - just under 20 years ago). - -2022-07-26: olly - Fix incorrect operator precedence in preprocessor expressions. - -2022-07-25: olly - Support for C++14 binary integer literals in preprocessor expressions. - -2022-07-20: wsfulton - [C#, Java] Ensure the order of interfaces generated in proxy interfaces for the - %interface family of macros is the same as that parsed from the bases in C++. - -2022-07-20: jicks, Ingener74, olly - #422 [Python] Fix mishandling of a Python class inheriting from - multiple SWIG-wrapped director classes. - -2022-07-19: wsfulton - #692 [C#, Java, Perl, Python, Ruby] std::unique_ptr and std::auto_ptr typemaps - provided for inputs types in std_unique_ptr.i and std_auto_ptr.i. - - Now these smart pointers can be used as input parameters to functions. A proxy - class instance transfers memory ownership of the underlying C++ object from the - proxy class to a smart pointer instance passed to the wrapped function. - -2022-07-19: jschueller - [Python] #2314 Drop support for Python 3.2. - -2022-07-19: olly - Remove remaining support code for classic macos, which has not been - supported by Apple for over 20 years now. - -2022-07-12: wsfulton - #999 Performance optimisation for parameters passed by value that are C++11 movable. - The C++ wrappers create a temporary variable for a parameter to be passed to a - function. This is initially default constructed and then copy assigned from the - instance being passed in from the target language. This is unchanged, however, - when the temporary variable is passed to the wrapped function, it is now done using - std::move. If the type is move constructible, the move constructor will be used - instead of the copy constructor. - -2022-07-12: wsfulton - [Perl] Add std::auto_ptr support in std_auto_ptr.i library file. - -2022-07-12: erezgeva - [Perl] Add std::unique_ptr support in std_unique_ptr.i library file. - -2022-07-07: jmarrec - #1158 #2286 Add basic support for C++11 attributes. These are now - crudely ignored by SWIG's parser's tokeniser, which is better that - failing with a parse error. - -2022-07-05: ianlancetaylor - [Go] #2245 Handle NULL pointers for string* conversions. - Rearrange generation of director methods and rename - receiver argument from p to swig_p. - -2022-07-03: wsfulton - #999 Performance optimisation for directors for classes passed by value. The directorin - typemaps in the director methods now use std::move on the input parameter when - copying the object from the stack to the heap prior to the callback into the target - language, thereby taking advantage of move semantics if available. - -2022-07-02: wsfulton - #1722 [C#, Java, Python, Ruby] Add std::unique_ptr support. Ported from std::auto_ptr. - Use the %unique_ptr(T) macro as follows for usage std::unique_ptr<T>. For example, for - a class called Klass: - - %include "std_unique_ptr.i" - %unique_ptr(Klass) - - Support is currently limited to only returning a std::unique_ptr from a function. - -2022-06-29: wsfulton - #999 #1044 Enhance SWIGTYPE "out" typemaps to use std::move when copying - objects, thereby making use of move semantics when wrapping a function returning - by value if the returned type supports move semantics. - - Wrapping functions that return move only types 'by value' now work out the box - without having to provide custom typemaps. - - The implementation removed all casts in the "out" typemaps to allow the compiler to - appropriately choose calling a move constructor, where possible, otherwise a copy - constructor. The implementation also required modifying SwigValueWrapper to - change a cast operator from: - - SwigValueWrapper::operator T&() const; - - to - - #if __cplusplus >=201103L - SwigValueWrapper::operator T&&() const; - #else - SwigValueWrapper::operator T&() const; - #endif - - This is not backwards compatible for C++11 and later when using the valuewrapper feature - if a cast is explicitly being made in user supplied "out" typemaps. Suggested change - in custom "out" typemaps for C++11 and later code: - - 1. Try remove the cast altogether to let the compiler use an appropriate implicit cast. - 2. Change the cast, for example, from static_cast<X &> to static_cast<X &&>, using the - __cplusplus macro if all versions of C++ need to be supported. - - *** POTENTIAL INCOMPATIBILITY *** - -2022-06-15: wsfulton - #2039 Add move assignment operator to SwigValueWrapper used by the - valuewrapper feature. - -2022-06-04: sethrj - Enhance $typemap to support typemap attributes. - - $typemap(method:attribute, typepattern) - - For example: - - %typemap(cstype, out="object") XClass "XClass" - %typemap(cscode) BarClass %{ - $typemap(cstype:out, XClass) bar() { - return null; - } - - which expands to - - object bar() { - return null; - } - -2022-05-30: wsfulton - [C#, D] Add new special variable expansion: $imfuncname. - Expands to the function name called in the intermediary class. - -2022-05-30: LindleyF - [Java] #2042 Add new special variable expansion: $imfuncname. - Expands to the function name called in the intermediary class. - -2022-05-28: jkuebart - [Java] On some versions of Android, specifically Android 6, - detaching the current thread from the JVM after every invocation - causes a memory leak. - - Offer SWIG_JAVA_DETACH_ON_THREAD_END to configure a behaviour - where the JVM is only detached in the thread destructor. - - See https://developer.android.com/training/articles/perf-jni#threads. - -2022-05-27: xypron - [Python] #2277 Define PY_SSIZE_T_CLEAN macro before #include "Python.h" as - recommended in Python 3.7 and later. - - To avoid this macro definition, add the following to your interface file so - that SWIG_NO_PY_SSIZE_T_CLEAN is defined at the beginning of the C++ wrappers: - - %begin %{ - #define SWIG_NO_PY_SSIZE_T_CLEAN - %} - -2022-05-26: rokups - [C#] #1323 Modify SwigDerivedClassHasMethod for a more efficient director - implementation when calling virtual methods that are not overridden. - -2022-05-15: erezgeva, eiselekd - [Lua, Perl, Octave, PHP, Tcl] #2275 #2276 #2283 Add argcargv.i library containing - (int ARGC, char **ARGV) multi-argument typemaps. - - Document this library in Typemaps.html. - -2022-05-07: KrisThielemans - [Python] Fix "too many initializers for 'PyHeapTypeObject'" errors - using PyPy 3.8 and later. - -2022-05-04: wsfulton - [C#] Add C# wchar_t * director typemaps - -2022-04-20: cminyard - Fix an issue where newlines were not properly generated - for godirectorin typemaps. If you have a virtual function - not assigned to zero, in some cases it won't generate a - newline and you will see errors: - example.go:1508:3: expected ';', found swig_r - when compiling the go code. - - Also add an example of using goin and godirectorin and add - a test for this situation. - -2022-04-29: jason-daly, JerryJoyce, wsfulton - [C#] #1233 Add wchar_t * and std::wstring Unicode string support on Linux. - -2022-04-11: robinst - #2257 Fix new Ruby 3.2 warning "undefining the allocator of T_DATA - class swig_runtime_data". - -2022-04-07: olly - #1750 SWIG now recognises and ignores Doxygen group commands `@{` and `@}`. - -2022-04-06: wsfulton - ./configure now enables C++11 and later C++ standards testing by default (when - running: 'make check'). - - The options to control this testing are the same: - - ./configure --enable-cpp11-testing - ./configure --disable-cpp11-testing - - But the former is now the default and the latter can be used to turn off C++11 and - later C++ standards testing. - -2022-04-06: wsfulton - [Python] #1635 The "autodoc" feature no longer overrides Doxygen comments - in the generated docstring. - - If a "docstring" feature is present it will still override a Doxygen comment. - If the "autodoc" feature is also present, the combined "autodoc" and "docstring" - will override the Doxygen comment. If no "docstring" is present then the - "autodoc" feature will not be generated when there is a Doxygen comment. - - This way the "autodoc" feature can be specified and used to provide documentation - for 'missing' Doxygen comments. - - *** POTENTIAL INCOMPATIBILITY *** - -2022-04-01: olly - Remove undocumented and non-functional -browse command line option. - -2022-03-26: eltoder - [Python] #1684 Use different capsule names with and without -builtin - - Types generated with and without -builtin are not compatible. Mixing - them in a common type list leads to crashes. Avoid this by using - different capsule names: "type_pointer_capsule" without -builtin and - "type_pointer_capsule_builtin" with. - -2022-03-25: wsfulton - The debug command line options that display parse tree nodes - (-debug-module, -debug-top, -debug-symtabs) now display previously hidden - linked list pointers which are useful for debugging parse trees. - - Added new command line option -debug-quiet. This suppresses the display - of most linked list pointers and symbol table pointers in the parse tree nodes. - - The keys in the parse tree node are now shown in alphabetical order. - -2022-03-24: wsfulton - #2244 Fix using declaration in derived class bugs when all the base - class's overloaded methods were overridden in the derived class - - fixes "multiply defined" errors. - -2022-03-23: wsfulton - [Python] #1779 The -py3 option is deprecated and now has no effect on the - code generated. Use of this option results in a deprecated warning. - The related SWIGPYTHON_PY3 macro that this option defined is no longer generated. - - Note that %pythonnondynamic feature generates a metaclass that works on both - Python 2 and Python 3. - -2022-03-21: wsfulton - [Python] #1779 pyabc.i for abstract base classes now supports versions of - Python prior to 3.3 by using the collection module for these older versions. - Python-3.3 and later continue to use the collections.abc module. - The -py3 option no longer has any effect on the %pythonabc feature. - -2022-03-21: jschueller, jim-easterbrook, wsfulton - [Python] #2137 C++ static member functions no longer generate a "flattened" - name in the Python module. For example: - - s = example.Spam() - s.foo() # Spam::foo() via an instance - example.Spam.foo() # Spam::foo() using class method - example.Spam_foo() # Spam::foo() "flattened" name - - The "flattened" name is no longer generated, but can be generated - by using the new -flatstaticmethod option. - - *** POTENTIAL INCOMPATIBILITY *** - -2022-03-18: ianlancetaylor - [Go] #337 Implement %extend base methods in child classes. - -2022-03-17: olly - [Python] #1779 SWIG's Python test-suite and examples are now - run with Python 3 by default. To run them with Python 2, set - PY2 to a non-empty value, e.g.: - - make check-python-test-suite PY2=1 - -2022-03-16: olly - [Go] #683 -intgosize is now optional - if not specified the - generated C/C++ wrapper code will use ptrdiff_t for intgo and - size_t for uintgo. - -2022-03-15: ianlancetaylor - [Go] Add typemaps for std::string*. - -2022-03-15: ianlancetaylor - [Go] Don't convert arrays to pointers if there is a "gotype" - typemap entry. - -2022-03-15: ianlancetaylor - [Go] Add documentation note about Go and C++ exceptions. - -2022-03-12: wsfulton - #1524 %interface family of macros no longer contain the getter/setter - methods for wrapping variables. The interface only contains - virtual and non-virtual instance methods, that is, no static methods. - Enums are also no longer added to the interface (affects Java only where - they were missing from the proxy class, C# never had them in the interface). - - *** POTENTIAL INCOMPATIBILITY *** - -2022-03-12: wsfulton - #1277 Fixes for the family of %interface macros, %interface, - %interface_impl and %interface_custom fixes for overloaded methods - in an inheritance chain. - - When C++ methods are not able to be overloaded in a derived class, - such as when they differ by just const, or the target language - parameters types are identical even when the C++ parameter types - are different, SWIG will ignore one of the overloaded methods with - a warning. A %ignore is required to explicitly ignore one of the - overloaded methods to avoid the warning message. Methods added - in the derived classes due to one of the %interface macros are now - similarly ignored/not added to the derived class. - - The methods added to the derived classes can now also be modified - via %feature and %rename. - -2022-03-08: ianlancetaylor - [Go] Treat a nil argument as a NULL pointer. - -2022-03-08: ianlancetaylor - [Go] Add documentation notes about thread local storage. - -2022-03-08: olly - #1006 SWIG now copes with an interface filename specified on the - command line which contains a closing parenthesis `)`, and more - generally with attributes to `%include` and `%import` which - are quoted and contain parentheses. - -2022-03-07: Omar Medina - [Tcl] https://sourceforge.net/p/swig/bugs/1290/ - Fix SWIG_AsWCharPtrAndSize() to actually assign to result - variable. It looks like SWIG/Tcl wide character handling is - currently fundamentally broken except on systems which use wide - characters as the system encoding, but this should fix wrapping - functions which take a wide string as a parameter on Microsoft - Windows. - -2022-03-07: olly - [Javascript] #682 Fix handling of functions which take void*. - -2022-03-06: olly - SWIG should now reliably exit with status 0 if the run was - successful and status 1 if there was an error (or a warning and - -Werror was in effect). - - Previously in some situations SWIG would try to exit with the - status set to the number of errors encountered, but that's - problematic - for example if there were 256 errors this would - result in exit status 0 on most platforms. Also some error - statuses have special meanings e.g. those defined by <sysexits.h>. - Also SWIG/Javascript tried to exit with status -1 in a few places - (which typically results in exit status 255). - -2022-03-05: wsfulton - #1441 Fix using declaration in derived class incorrectly introducing a method - from a base class when the using declaration is declared before the method - declaration. Problem occurred when within a namespace and the parameter types - in the method signatures were not fully qualified. -2022-03-05: ianlancetaylor - [Go] Treat non-const references as pointers. - -2022-03-05: ianlancetaylor - In SWIG Go testsuite, fail test if "go build" fails. - -2022-03-03: olly - #1901 #2223 SWIG should now always exit cleanly if memory - allocation fails, including removing any output files created - during the current run. - - Previously most places in the code didn't check for a NULL return - from malloc()/realloc()/calloc() at all, typically resulting in - undefined behaviour; some places used assert() to check for a NULL - return (which is a misuse of assert() and such checks disappear if - built with NDEBUG defined leaving us back with undefined - behaviour). - -2022-03-03: olly - #891 Report errors for typemap attributes without a value - (previously SWIG segfaulted) and for typemap types with a value - (previously the value was quietly ignored). - - The old way of specifying a language name in the typemap attributes - is no longer supported (it has been deprecated for 16 years). - -2022-03-02: geographika, wsfulton - [Python] #1951 Add Python variable annotations support. - - Both function annotations and variable annotations are turned on using the - "python:annotations" feature. Example: - - %feature("python:annotations", "c"); - - struct V { - float val; - }; - - The generated code contains a variable annotation containing the C float type: - - class V(object): - val: "float" = property(_example.V_val_get, _example.V_val_set) - ... - - Python 3.5 and earlier do not support variable annotations, so variable - annotations can be turned off with a "python:annotations:novar" feature flag. - Example turning on function annotations but not variable annotations globally: - - %feature("python:annotations", "c"); - %feature("python:annotations:novar"); - - or via the command line: - - -features python:annotations=c,python:annotations:novar - - *** POTENTIAL INCOMPATIBILITY *** - -2022-02-27: wsfulton - [Python] #735 #1561 Function annotations containing C/C++ types are no longer - generated when using the -py3 option. Function annotations support has been - moved to a feature to provide finer grained control. It can be turned on - globally by adding: - - %feature("python:annotations", "c"); - - or by using the command line argument: - - -features python:annotations=c - - Also see entry dated 2022-03-02, regarding variable annotations. - - *** POTENTIAL INCOMPATIBILITY *** - -2022-02-26: wsfulton - #655 #1840 Add new warning WARN_LANG_USING_NAME_DIFFERENT to warn when a - method introduced by a using declaration in a derived class cannot - be used due to a conflict in names. - -2022-02-24: olly - #1465 An invalid preprocessor expression is reported as a pair of - warnings with the second giving a more detailed message from the - expression evaluator. Previously SWIG prefixed the second message - with "Error:" - that was confusing as it's actually only a warning - by default so we've now dropped this prefix. - - Before: - - x.i:1: Warning 202: Could not evaluate expression '1.2' - x.i:1: Warning 202: Error: 'Floating point constant in preprocessor expression' - - Now: - - x.i:1: Warning 202: Could not evaluate expression '1.2' - x.i:1: Warning 202: Floating point constant in preprocessor expression - -2022-02-23: olly - #1384 Fix a preprocessor expression evaluation bug. A - subexpression in parentheses lost its string/int type flag and - instead used whatever type was left in the stack entry from - previous use. In practice we mostly got away with this because - most preprocessor expressions are integer, but it could have - resulted in a preprocessor expression incorrectly evaluating as - zero. If -Wextra was in use you got a warning: - - Warning 202: Error: 'Can't mix strings and integers in expression' - -2022-02-21: davidcl - [Scilab] Improve 5.5.2, 6.0.0 and 6.1.0 support. - - For Scilab 5, long names are reduced to small names preserving the - class prefix and accessor suffix (get or set). - - For Scilab 6, long names with the class prefix and accessor suffix - should be used on the user code. - - The `-targetversion` option has been removed as the generated code - now detects the Scilab version in loader.sce or builder.sce. - - *** POTENTIAL INCOMPATIBILITY *** - -2022-02-20: wsfulton - Fix %warnfilter warning suppress for warning 315 SWIGWARN_PARSE_USING_UNDEF. - -2022-02-17: olly - [PHP] https://sourceforge.net/p/swig/bugs/1211/ - Fix to call cleanup code in exception situations and not to invoke - the freearg typemap twice in certain situations. - -2022-02-15: olly - #300 #368 Improve parser handling of % followed immediately by - an identifier. If it's not a recognised directive the scanner - now emits MODULO and then rescans what follows, and if the parser - then gives a syntax error we report it as an unknown directive. - This means that `a%b` is now allowed in an expression, and that - things like `%std::vector<std::string>` now give an error rather - than being quietly ignored. - -2022-02-11: adr26 - [Python] #2154 Fix memory leak. - - SWIG python objects were being freed after the corresponding SWIG - module information was destroyed in Python 3, causing leaks when as - a result the object destructor could not be invoked. To prevent this - misordering, SWIG python objects now obtain a reference to the - Python capsule wrapping the module information, so that the module - information is correctly destroyed after all SWIG python objects - have been freed (and corresponding destructors invoked). - -2022-02-10: olly - [Tcl] https://sourceforge.net/p/swig/bugs/1207/ - https://sourceforge.net/p/swig/bugs/1213/ - - Fix Tcl generic input typemap for std::vector. - -2022-02-07: sethrj - #2196 Add alternative syntax for specifying fragments in typemaps. - - New syntax: - %typemap("in", fragment="frag1", fragment="frag2", fragment="frag3") {...} - which is equivalent to: - %typemap(in, fragment="frag1,frag2,frag3") {...} - - -2022-02-07: olly - #1806 Remove support for the "command" encoder, which was mostly - intended for use in `%rename` - most uses can be achieved using - the "regex" encoder, so we recommend using that instead. - - The "command" encoder suffers from a number of issues - as the - documentation for it admitted, "[it] is extremely slow compared to - all the other [encoders] as it involves spawning a separate process - and using it for many declarations is not recommended" and that it - "should generally be avoided because of performance - considerations". - - But it's also not portable. The design assumes that `/bin/sh` - supports `<<<` but that's a bash-specific feature so it doesn't - work on platforms where `/bin/sh` is not bash - it fails on - Debian, Ubuntu and probably some other Linux distros, plus most - non-Linux platforms. Microsoft Windows doesn't even have a - /bin/sh as standard. - - Finally, no escaping of the passed string is done, so it has - potential security issues (though at least with %rename the input - is limited to valid C/C++ symbol names). - -2022-02-06: olly - #2193 -DFOO on the SWIG command line now sets FOO to 1 for - consistency with C/C++ compiler preprocessors. Previously - SWIG set FOO to an empty value. - - Existing invocations of SWIG with `-DFOO` where the empty value - matters can be updated to `-DFOO=` which should work with both - old and new releases of SWIG. - - *** POTENTIAL INCOMPATIBILITY *** - -2022-02-06: sethrj - #2194 Classes that are non-assignable due to const data or const - reference members are now automatically detected. - -2022-02-04: friedrichatgc - [Octave] #1672 Fix for isobject for Octave 4.4 - 6.0. - -2022-02-03: olly - [C#] #283 #998 Fix memory leak in directorin typemap for - std::string. - -2022-02-03: olly - [Python] #967 Make `self` parameter available to user typemaps. - -2022-02-03: teythoon - [Python] #801 Fix -Wunused-parameter warnings with builtin, - -2022-02-03: teythoon - #801 Fix -Wstrict-prototypes warnings in generated pointer - functions. - -2022-02-03: olly - #660 https://sourceforge.net/p/swig/bugs/1081/ - Default parameter values containing method calls are now parsed and - handled - e.g. `x->foo(3,4)` and `y.z()`. - -2022-02-02: olly - [Ruby] https://sourceforge.net/p/swig/bugs/1136/ Fix remove of prefix - from method name to only remove it at the start. - -2022-02-01: olly - #231 Handle returning an object by reference in a C++ trailing - return type. - -2022-02-01: davidcl - [Scilab] #745 use SWIG_<module>_Init() as a C module init function. - -2022-02-01: olly - [OCaml] #2083 Fix to work when CAML_SAFE_STRING is on, which it is - by default in recent Ocaml releases. - -2022-01-31: mreeez - https://sourceforge.net/p/swig/bugs/1147/ - Fix copyToR() generated for a struct in a namespace. - -2022-01-29: fschlimb - #655 Better handling of using declarations. - -2022-01-29: dontpanic92 - [Go] #676 Fix code generated for a C++ class with a non-capitalised - name. - -2022-01-26: trex58 - #1919 #1921 #1923 Various fixes for AIX portability. - -2022-01-26: olly - #1935 Don't crash on an unclosed HTML tag in a doxygen comment - when -doxygen is specified. - -2022-01-25: olly - Constant expressions now support member access with `.` such as - `foo.bar`. Previous this only worked in a case like `x->foo.bar`. - -2022-01-25: olly - #2091 Support most cases of `sizeof` applied to an expression - in constant expressions. Previously there was only support for - `sizeof(<type>)` and expressions which syntactically look like a - type (such as `sizeof(foo)`). - -2022-01-25: olly - #80 #635 https://sourceforge.net/p/swig/bugs/1139/ - Add support for parsing common cases of `<` and `>` comparisons - in constant expressions. Adding full support for these seems hard - to do without introducing conflicts into the parser grammar, but in - fact all reported cases have had parentheses around the comparison - and we can support that with a few restrictions on the left side of - `<`. - -2022-01-25: wsfulton - New warning 327 for extern templates, eg: - - extern template class std::vector<int>; - extern template void Func<int>(); - - results in warning - - example.i:3: Warning 327: Extern template ignored. - example.i:4: Warning 327: Extern template ignored. - - Extern template classes previously resulted in warning 320. - -2022-01-24: romintomasetti - #2131 #2157 C++11 extern function template parsing error fix. - -2022-01-21: wsfulton - #2120 #2138 Replace legacy PCRE dependency with PCRE2. - This requires changes for building SWIG from source. See updated - html documentation in Preface.html and Windows.html. Updated - instructions are also shown when running ./configure if PCRE2 is not - found. Note that debian based systems can install PCRE2 using: - - apt install libpcre2-dev - - Note that https://github.com/swig/swig/wiki/Getting-Started also has - updated information for building from source. - -2022-01-19: olly - [PHP] #2027 Automatically generate PHP type declarations for PHP 8. - The generate code still compiles for PHP 7.x, but without type - declarations since PHP 7.x has much more limited type declaration - support. - -2022-01-18: olly - [Perl] #1629 Perl 5.8.0 is now the oldest version we aim to support. - -2022-01-14: wsfulton - [Python] Fix %callback and specifying the callback function as a - static member function using Python staticmethod syntax, such as - Klass.memberfunction instead of Klass_memberfunction when using - -builtin and -fastproxy. - -2022-01-11: wsfulton - [Python] Accept keyword arguments accessing static member functions when - using -builtin and kwargs feature and Python class staticmethod syntax. - The missing keyword argument support was only when using the - class staticmethod syntax, such as Klass.memberfunction, and not when - using the flat static method syntax, such as Klass_memberfunction. - -2022-01-04: juierror - [Go] #2045 Add support for std::array in std_array.i. - -2021-12-18: olly - [PHP] Add PHP keyword 'readonly' (added in 8.1) to the list SWIG - knows to automatically rename. This keyword is special in that PHP - allows it to be used as a function (or method) name. - -2021-12-07: vstinner - [Python] #2116 Python 3.11 support: use Py_SET_TYPE() - -2021-12-05: rwf1 - [Octave] #2020 #1893 Add support for Octave 6 up to and including 6.4. - Also add support for compiling with -Bsymbolic which is used by default - by mkoctfile. - -2021-12-02: jsenn - [Python] #2102 Fixed crashes when using embedded Python interpreters. - -2021-11-12: wsfulton - [Javascript] v8 and node only. Fix mismatched new char[] and free() - when wrapping C code char arrays. Now calloc is now used instead of - new char[] in SWIG_AsCharPtrAndSize. - -2021-10-03: ajrh1 - [Perl] #2074: Avoid -Wmisleading-indentation in generated code - when using gcc11. - -2021-10-03: jschueller - [CMake] #2065: Add option to enable or disable PCRE support. - -2021-09-16: ianlancetaylor - [Go] Improved _cgo_panic implementation. - -2021-09-16: ianlancetaylor - [Go] Don't use crosscall2 for panicking. Instead rely on documented - and exported interfaces. - -2021-09-14: ianlancetaylor - [Go] Remove -no-cgo option (long unsupported in Go) - -2021-05-04: olly - [PHP] #2014 Throw PHP exceptions instead of using PHP errors - - PHP exceptions can be caught and handled if desired, but if they - aren't caught then PHP exits in much the same way as it does for a - PHP error. - - In particular this means parameter type errors and some other cases - in SWIG-generated wrappers now throw a PHP exception, which matches - how PHP's native parameter handling deals with similar situations. - - `SWIG_ErrorCode()`, `SWIG_ErrorMsg()`, `SWIG_FAIL()` and `goto thrown;` - are no longer supported (these are really all internal implementation - details and none are documented aside from brief mentions in CHANGES - for the first three). I wasn't able to find any uses in user interface - files at least in FOSS code via code search tools. - - If you are using these: - - Use `SWIG_PHP_Error(code,msg);` instead of `SWIG_ErrorCode(code); - SWIG_ErrorMsg(msg);` (which will throw a PHP exception in SWIG >= 4.1 - and do the same as the individual calls in older SWIG). - - `SWIG_FAIL();` and `goto thrown;` can typically be replaced with - `SWIG_fail;`. This will probably also work with older SWIG, but - please test with your wrappers if this is important to you. - - *** POTENTIAL INCOMPATIBILITY *** - -2021-05-17: adr26 - [Python] #1985 Fix memory leaks: - - 1. Python object references were being incorrectly retained by - SwigPyClientData, causing swig_varlink_dealloc() never to run / free - memory. SwigPyClientData_New() / SwigPyClientData_Del() were updated - to fix the object reference counting, causing swig_varlink_dealloc() - to run and the memory swig_varlink owns to be freed. - - 2. SwigPyClientData itself was not freed by SwigPyClientData_Del(), - causing another heap leak. The required free() was added to - SwigPyClientData_Del() - - 3. Fix reference counting/leak of python cached type query - - 4. Fix reference counting/leak of SwigPyObject dict (-builtin) - - 5. Python object reference counting fixes for out-of-memory - scenarios were added to: SWIG_Python_RaiseOrModifyTypeError(), - SWIG_Python_AppendOutput(), SwigPyClientData_New(), - SwigPyObject_get___dict__() and SwigPyObject_format() - - 6. Add error handling for PyModule_AddObject() to - SWIG_Python_SetModule() (failure could be caused by OOM or a name - clash caused by malicious code) - -2021-05-13: olly - [UFFI] #2009 Remove code for Common Lisp UFFI. We dropped support - for it in SWIG 4.0.0 and nobody has stepped forward to revive it in - over 2 years. - -2021-05-13: olly - [S-EXP] #2009 Remove code for Common Lisp S-Exp. We dropped - support for it in SWIG 4.0.0 and nobody has stepped forward to - revive it in over 2 years. - -2021-05-13: olly - [Pike] #2009 Remove code for Pike. We dropped support for it in - SWIG 4.0.0 and nobody has stepped forward to revive it in over 2 - years. - -2021-05-13: olly - [Modula3] #2009 Remove code for Modula3. We dropped support for it - in SWIG 4.0.0 and nobody has stepped forward to revive it in over 2 - years. - -2021-05-13: olly - [CLISP] #2009 Remove code for GNU Common Lisp. We dropped support - for it in SWIG 4.0.0 and nobody has stepped forward to revive it in - over 2 years. - -2021-05-13: olly - [Chicken] #2009 Remove code for Chicken. We dropped support for it - in SWIG 4.0.0 and nobody has stepped forward to revive it in over 2 - years. - -2021-05-13: olly - [Allegrocl] #2009 Remove code for Allegro Common Lisp. We dropped - support for it in SWIG 4.0.0 and nobody has stepped forward to - revive it in over 2 years. - -2021-05-04: olly - [PHP] #1982 #1457 https://sourceforge.net/p/swig/bugs/1339/ - SWIG now only use PHP's C API to implement its wrappers, and no - longer generates PHP code to define classes. The wrappers should - be almost entirely compatible with those generated before, but - faster and without some previously hard-to-fix bugs. - - The main notable difference is SWIG no longer generates a .php - wrapper at all by default (only if %pragma(php) code=... or - %pragma(php) include=... are specified in the interface file). - This also means you need to load the module via extension=... - in php.ini, rather than letting the dl() in the generated - .php wrapper load it (but dl() has only worked for command-line - PHP for some years now). - - *** POTENTIAL INCOMPATIBILITY *** - -2021-04-30: olly - #1984 Remove support for $source and $target. - These were officially deprecated in 2001, and attempts to use them have - resulted in a warning (including a pointer to what to update them to) - for most if not all of that time. - -2021-04-27: wsfulton - #1987 [Java] Fix %interface family of macros for returning by const - pointer reference. - -2021-04-19: olly - Fix use of uninitialised variable in the generated code for an - empty typecheck typemap, such as the dummy one we include for - std::initializer_list. - -2021-04-12: olly - #1777 [Python] Specifying -py3 now generates a check for Python - version >= 3.0. - -2021-03-26: olly - [PHP] Add PHP keywords 'fn' (added in 7.4) and 'match' (added in - 8.0) to the list SWIG knows to automatically rename. - -2021-03-23: wsfulton - #1942 [Python] Fix compilation error in wrappers when using -builtin - and wrapping varargs in constructors. - -2021-03-22: goto40 - #1977 Fix handling of template template parameters. - -2021-03-21: olly - #1929, #1978 [PHP] Add support for PHP 8. - -2021-03-19: wsfulton - #1610 Remove -ansi from default compilation flags. - -2021-03-19: dot-asm - #1934 [Java] Clean up typemaps for long long arrays. - -2021-03-19: olly - #1527 [PHP] Improve PHP object creation in directorin case. - Reportedly the code we were using in this case gave segfaults in - PHP 7.2 and later - we've been unable to reproduce these, but the - new approach is also simpler and should be bit faster too. - -2021-03-18: olly - #1655 [PHP] Fix char* typecheck typemap to accept PHP Null like the - corresponding in typemap does. - -2021-03-18: olly - #1900, #1905 [PHP] Fix wrapping of overloaded directed methods with - non-void return. - -2021-03-11: murillo128 - #1498 [Javascript] Support type conversion. - -2021-03-06: nshmyrev - #872 [Javascript] Various typemap issues in arrays_javascript.i fixed. - -2021-03-03: vaughamhong - #577 [Javascript] Implemented SetModule/GetModule for JSC to allow type sharing - across modules. - -2021-03-01: xantares, Oliver Buchtala, geographika - #1040 Add support for building SWIG with CMake. See documentation in Windows.html. - -2021-03-01: vadz - #1952 Fix incorrect warning "Unknown Doxygen command: ." - -2021-02-28: p2k - #969 [Javascript] v8/node - prevent crash calling a constructor without new keyword. - -2021-02-28: alecmev - #405 #1121 [Javascript] Fix OUTPUT typemaps on methods that don't return void. - The output value is appended to the return value. - -2021-02-26: murillo128, wsfulton - #1269 [Javascript] Fix handling of large positive unsigned long and - unsigned long long values. - -2021-02-24: tomleavy, yegorich, tungntpham - #1746 [Javascript] Add support for Node v12, v14 and v16. - SWIG support for Node is now for v6 and later only. - -2020-02-09: ZackerySpytz - #1872 Fix typos in attribute2ref macros. - -2020-10-10: wsfulton - [Javascript] Fix so that ccomplex.i interface to file can be used. - -2020-10-10: wsfulton - #252 complex can now be used as a C identifier and doesn't give a syntax error. - -2020-10-10: lpsinger - #1770 Correct C complex support. - _Complex is now parsed as a keyword rather than complex as per the C99 standard. - The complex macro is available in the ccomplex.i library file along with other - complex number handling provided by the complex.h header. - -2020-10-07: ZackerySpytz - [Python] #1812 Fix the error handling for the PyObject_GetBuffer() calls in - pybuffer.i. - -2020-10-07: treitmayr - #1824 Add missing space in director method declaration returning - const pointer. - -2020-10-07: adelva1984 - #1859 Remove all (two) exceptions from SWIG executable. - -2020-09-25: wsfulton - [C#, Java] #1874 Add ability to change the modifiers for the interface - generated when using the %interface macros. - - For C# use the 'csinterfacemodifiers' typemap. - For Java use the 'javainterfacemodifiers' typemap. - - For example: - - %typemap(csinterfacemodifiers) X "internal interface" - -2020-09-24: geefr - [C#] #1868 Fix wchar_t* csvarout typemap for member variable wrappers. - -2020-08-28: wsfulton - [Java] #1862 Fix crashes in swig_connect_director during director class construction - when using the director class from multiple threads - a race condition initialising - block scope static variables. The fix is guaranteed when using C++11, but most - compilers also fix it when using C++03/C++98. - -2020-08-16: wsfulton - [Python] Add missing initializer for member '_heaptypeobject::ht_module' when using - -builtin to complete Python 3.9 support. - -2020-08-16: wsfulton - [Python] Remove PyEval_InitThreads() call for Python 3.7 and later as Python calls - it automatically now. This removes a deprecation warning when using Python 3.9. - -2020-08-15: wsfulton - [Python] All Python examples and tests are written to be Python 2 and Python 3 - compatible, removing the need for 2to3 to run the examples or test-suite. - -2020-08-13: wsfulton - [C#] Add support for void *VOID_INT_PTR for member variables. - -2020-07-29: chrisburr - #1843 [Python] Compilation error fix in SwigPyBuiltin_SetMetaType when using PyPy. - -2020-06-14: ZackerySpytz - #1642 #1809 Fix virtual comparison operators in director classes by removing an - incorrect space in the function name (for example, operator= = is now operator==). - -Version 4.0.2 (8 Jun 2020) -========================== - -2020-06-07 vigsterkr - [Ruby] #1717 Nil fix mangling strings - -2020-06-07 vadz - #1748 Fix doxygen comments quoting issue - -2020-06-07 munoah - #1800 Escape spaces in file paths for dependencies (-M -MM etc) - -2020-06-06 andreas-schwab - [Ruby] #1801 Fix encoding on big endian systems when wrapping std::wstring. - -2020-05-31 kwwette - [Octave] #1789 error handling improvements and return error code on exit for SWIG wrapped modules. - -2020-05-30 msteinbeck - [D] #1593 Replace broken imports when using newer versions of D. - -2020-05-29: ZackerySpytz - [Python] #1716 Performance improvements when converting strings when using Python >= 3.3. - -2020-05-28: ZackerySpytz - #1776 Quite dramatically decrease run times when generating very large interface files by changing - some internal memory pool sizes. - -2020-05-28: mcfarljm - #1788 Fix handling of Doxygen \endlink command. - -2020-05-24: vapier - [Javascript] #1796 Fix pkg-config invocation in configure. - -2020-04-30: kwwette - [Octave] Fix exception raising for newer Octave versions - Since (at least) Octave 5.1.0, the Octave error() function now raises a C++ exception, - which if uncaught immediately exits a SWIG wrapper function, bypassing any cleanup code - that may appear after a "fail:" label. This patch adds a "try { ... } catch(...) { }" - block around the contents of SWIG wrapper functions to first execute the cleanup code - before rethrowing any exception raised. It is backward compatible with earlier versions - of Octave where error() does not raise an exception, which will still branch to the - "fail:" block to execute cleanup code if an error is encountered. - - Note that the new "try { ... } catch(...) { }" block will localise any local variables - used in typemaps that were NOT declared through SWIG's %typemap(...) syntax, so it's - possible this could break existing SWIG wrappers which were implicitly sharing local - variables between typemaps. This can be fixed, however, by declaring local variables - which need to be shared between typemaps through SWIG's %typemap(...) syntax. - -2020-02-18: ryannevell - [Lua] #1728 Add support for LUA lightuserdata to SWIG_Lua_ConvertPtr. - -2020-02-18: dmach - [Ruby] #1725 Fix gcc -Wcatch-value warnings. - -2020-02-14: treitmayr - #1724 Fix wrapping of abstract user-defined conversion operators. - -2020-02-13: ddurham2 - [Python] #1512 Fix memleak when using STL containers of shared_ptr objects. - -2020-02-06: wsfulton - [Python] #1673 #1674 Fix setting 'this' when extending a proxy class with __slots__. - -2020-01-31: vadz - [Ruby] #1651 Add std::auto_ptr<> typemaps. - -2020-01-31: ZackerySpytz - [Python] #1700 The Python C API functions PyBytes_AsStringAndSize() and - PyString_AsStringAndSize() are now checked for failure. - -2020-01-31: vadz - [Python] #1710 Fix crash parsing empty docstrings. - -2020-01-30: Alzathar - [R] #910 #914 Fix R memory leak on exception. - -2020-01-30: richardbeare - [R] #1511 Fix bug wrapping functions. These were previously incorrectly wrapped as if - they were variables. This happened when 'get' or 'set' was in the name of the function - or method, but sometimes also in some other circumstances. If you were using R - attribute syntax to access these methods, you'll need to switch to calling them as R - methods. - - *** POTENTIAL INCOMPATIBILITY *** - -2020-01-24: etse-dignitas, wsfulton - [C#, D, Java] #1533 Fix upcasting for shared_ptr's of templated types. - -2020-01-16: mcfarljm - #1643 #1654 When using -doxygen, fix segfault when nameless parameters or vararg parameters - are used. - -2020-01-16: mcfarljm - #1632 #1659 Fix newline handling for doxygen "///" comments. - -2020-01-14: mcfarljm - #1647 #1656 Fix crash handling empty doxygen comments. - -2020-01-14: mcfarljm - #1608 Improve doxygen support. - - Add support for \param[] commands such as: \param[in]. - - Optional arguments are marked as 'optional' in pydoc. - - Improve support for \code commands so that other languages are supported as code blocks. - Support added for java, c and py. For example Python: \code{.py} ... \endcode - - Fix doxygen handling of \em and \p tags for Python. - -2020-01-13: wsfulton - [Python] #1595 Python -builtin constructors silently ignored keyword arguments. - Instead of silently ignoring them, now a "TypeError: f() takes no keyword arguments" - exception is thrown if keyword arguments are used. Hence constructors and normal methods/ - functions behave in the same way. Note, -keyword should be used with -builtin to obtain - keyword argument support. - -2020-01-05: jschueller shadchin - [Python] #1670 #1696 Add missing field initializers introduced in python 3.8: - tp_vectorcall and tp_print. - -2020-01-05: friedrichatgc - [Octave] #1688 Change swig_this() to use size_t instead of long for compatibility - with Windows 64 bit. - -2020-01-05: treitmayr - [Ruby] #1692 #1689 Add support for Ruby 2.7 - -2019-12-30: treitmayr - [Ruby] #1653 #1668 Fix code generated when using -globalmodule option. - -2019-12-29: ZackerySpytz - [OCaml] #1686 Fix compilation errors with OCaml 4.09.0. - -2019-12-10: wsfulton - #1679 Fix parsing of C++11 identifiers with special meaning (final and override) when - they are used as part of the scope name of an identifier, such as a namespace name. - -2019-11-26: wsfulton - [C#] #1628 'out' or 'ref' used in a cstype typemap was not always stripped out in parts - of director code generation. - -2019-11-01: wsfulton - [Python] #1595 Fix bug in support for keyword arguments (kwargs feature or -keyword) - when using -builtin. The fix is in the argument error checking when wrapping zero - argument constructors only. - -Version 4.0.1 (21 Aug 2019) -=========================== - -2019-08-20: TekuConcept - [Javascript] #1535 Add %native support to Javascript. - -2019-08-20: bkotzz - [Java] #1616 Add SWIG_JavaIllegalStateException to support throwing - java.lang.IllegalStateException from JNI code. - -2019-08-19: sjml - [Lua] #1596 tostring output changes to show the underlying C/C++ pointer. - -2019-08-08: rokups - [C#, Java] #1601 Fix invalid code generated for "%constant enum EnumType. - -2019-08-07: wsfulton - [Python] Fix method overloading of methods that take STL containers of different - types. The following usage (using std::vector) would fail when using -builtin: - - %include <std_string.i> - %include <std_vector.i> - - %inline %{ - struct X {}; - %} - - %template(VectorX) std::vector<X>; - %template(VectorInt) std::vector<int>; - - %inline %{ - using namespace std; - string VectorOverload(vector<X> v); - string VectorOverload(vector<int> v); - %} - - The following would incorrectly fail: - - s = VectorOverload([1, 2, 3]) - - With: - - Traceback (most recent call last): - File "runme3.py", line 20, in <module> - ret = VectorOverload([1, 2, 3]) - TypeError: Wrong number or type of arguments for overloaded function 'VectorOverload'. - Possible C/C++ prototypes are: - VectorOverload(std::vector< Number,std::allocator< Number > >) - VectorOverload(std::vector< int,std::allocator< int > >) - - The problem was due to some error handling that was not cleared during typechecking. - In this case an error was not cleared when the elements in the list failed the - typecheck for converting to X. Only occurs in Python 3+. - - In some combinations of overloaded methods, the following type of error message would - occur: - - RuntimeError: in sequence element 0 - - The above exception was the direct cause of the following exception: - - Traceback (most recent call last): - File "runme3.py", line 23, in <module> - check(VectorOverload(v), "vector<X>") - SystemError: <built-in function VectorOverload> returned a result with an error set - -2019-08-01: wsfulton - #1602 Fix regression in 4.0.0 where a template function containing a parameter - with the same name as the function name led to the parameter name used in the - target language being incorrectly modified. - -2019-07-29: wsfulton - Remove all generated files on error. Previously generated files were not removed, - potentially breaking Makefiles using file dependencies, especially when -Werror - (warnings as errors) was used. - -2019-07-23: smithx - [C#] #1530 #1532 Fix marshalling of std::wstring to C#. - -2019-07-18: gicmo - [Python] #1587 Python 3.8 support - remove use of deprecated PyObject_GC_UnTrack. - -2019-07-18: cher-nov - [Python] #1573 Generated Python code uses consistent string quoting style - double - quotes. - -2019-07-16: geefr - [C#] #616 #1576 Fix C# bool INPUT[], bool OUTPUT[], bool INOUT[] typemaps to marshall - as 1-byte. - -2019-07-12: vadz - [C#, Java] #1568 #1583 Fix std::set<> typemaps for primitive types. - -2019-07-12: vadz - #1566 #1584 Regression in 4.0.0 - fix missing value for first item of enums with - trailing comma. - -2019-07-11: mcfarljm - #1548 #1578 Fix segfault in Doxygen parser parsing empty lines in some commands like - \code. - -2019-07-09: IsaacPascual - [C#, Java] #1570 Fix name of generated C#/Java classes for %interface macros - in swiginterface.i when wrapping nested C++ classes. - -2019-07-05: wsfulton - [Python] #1547 Whitespace fixes in Doxygen translated comments into pydoc comments - for Sphinx compatibility. - -2019-06-28: wsfulton - [MzScheme, OCaml] #1559 $arg and $input were incorrectly substituted in the - argout typemap when two or more arguments were present. - -2019-06-24: wsfulton - [Python, Ruby] #1538 Remove the UnknownExceptionHandler class in order to be - C++17 compliant as it uses std::unexpected_handler which was removed in C++17. - This class was intended for director exception handling but was never used by - SWIG and was never documented. - - *** POTENTIAL INCOMPATIBILITY *** - -2019-06-06: bkotzz - [Java] #1552 Improve performance in Java std::vector constructor wrapper that takes - a native Java array as input. - -2019-06-03: olly - [Python] Fix regression in implicit_conv handling of tuples, - introduced in SWIG 4.0.0. Fixes #1553, reported by Alexandre - Duret-Lutz. - -2019-05-24: wsfulton - [Octave] Fix detection of Octave on MacOS. - -2019-05-24: opoplawski - [Octave] #1522 Adapt OCTAVE_LDFLAGS for Octave 5.1. - -2019-05-22: ferdynator - [PHP] #1528 Don't add a closing '?>' PHP tag to generated files. - PSR-2 says it MUST be omitted for files containing only PHP. - -Version 4.0.0 (27 Apr 2019) -=========================== - -2019-04-24: vadz - #1517 Fix crash if "@return" Doxygen tag was used on a node without any return type. - -2019-04-24: vadz - #1515 Fix parsing of enums with trailing comma when using -doxygen. - -2019-04-19: ianlancetaylor - [Go] #1055 When generating Go code, make -cgo the default. Add new -no-cgo option - to disable the default. - -2019-04-19: pbecherer - [Tcl] #1508 Fix Visual Studio 2015 and later compilation errors due to snprintf macro - definition. - -2019-04-09: wsfulton - [C#] Fix FxCop warning CA2002 in SWIGPendingException - a lock on a reference of - type 'Type'. - -2019-03-30: wsfulton - [Java, D] Add the parameters typemap attribute to the javadestruct, - javadestruct_derived, ddispose, ddispose_derived typemaps to mirror enhanced - flexibility in the csdisposing and csdisposing_derived (C#) typemaps. If provided - the contents are generated as the delete/dispose method's parameters declaration. - -2019-03-30: wsfulton - [C#] #421 Fix FxCop warning CA1063 by implementing the recommended Dispose methods for - the IDisposable interface. Previously just the Dispose() method was generated. - Now the Dispose() and Dispose(bool disposing) methods are generated. - Changes are required if custom "csfinalize", "csdestruct" or "csdestruct_derived" - typemaps are being used. Details in #421 on Github. SWIG will error out if one of - the "csfinalize, "csdestruct" or "csdestruct_derived" typemaps are found. Example - error message: - - foo.h:60: Error: A deprecated csfinalize typemap was found for Foo, please remove - it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the - csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps. - - *** POTENTIAL INCOMPATIBILITY *** - -2019-03-25: Liryna - [C#] #1143 Add std_list.i for std::list support. - The C# std::list<T> wrappers are made to look and feel like a C# - System.Collections.Generic.LinkedList<> collection. - The IEnumerable<> interface is implemented in the proxy class. - The ICollection<> interface can also be implemented to provide enhanced functionality - whenever a C++ operator== is available. This is the case for when T is a - primitive type or a pointer. If T does define an operator==, then use the - SWIG_STD_LIST_ENHANCED macro to obtain this enhanced functionality, for example: - - SWIG_STD_LIST_ENHANCED(SomeNamespace::Klass) - %template(ListKlass) std::list<SomeNamespace::Klass>; - -2019-03-18: richardbeare - [R] #1328 Non-trivial enums are working now. The enum values are now obtained from - the C/C++ layer. const reference enums and C++11 enum classes are also now working. - -2019-03-14: mochizk - [Javascript] #1500 Fix compilation errors due to deprecating V8 API in Node.js. - New V8 API is used if node.js >= v10.12, or if V8 >= v7.0. - -2019-03-12: vadz - [C#] #1495 Add std_set.i for std::set support. - -2019-03-11: dirteat,opoplawski - [Octave] Fix compilation errors in Octave 5.1. - - error: format not a string literal and no format arguments [-Werror=format-security] - -2019-02-28: wsfulton - [Java] std::vector improvements for types that do not have a default constructor. - - The std::vector wrappers have been changed to work by default for elements that are - not default insertable, i.e. have no default constructor. This has been achieved by - not wrapping: - - vector(size_type n); - - Previously the above had to be ignored via %ignore. - - If the above constructor is still required it can be added back in again via %extend: - - %extend std::vector { - vector(size_type count) { return new std::vector< T >(count); } - } - - Alternatively, the following wrapped constructor could be used as it provides near-enough - equivalent functionality: - - vector(jint count, const value_type& value); - - *** POTENTIAL INCOMPATIBILITY *** - -2019-02-25: wsfulton - [Python] Fix compile errors wrapping overloaded functions/constructors where a vararg - function is declared after a non-vararg function. - -2019-02-23: zphensley42 - Use fully qualified name 'java.lang.Object' instead of 'Object' in generated code to - avoid clashes with wrapped C++ classes called 'Object'. - -2019-02-23: gtbX - [Java] #1035 Add (const char *STRING, size_t LENGTH) typemaps in addition to the non-const - typemaps (char *STRING, size_t LENGTH) which does not attempt to write back to the const - string. - -2019-02-22: tamuratak - [Ruby] #984 Add support for RTypedData introduced in Ruby 1.9.3. - -2019-02-22: ZackerySpytz - #1483 Fix compilation failures when a director class has final methods. - -2019-02-21: wsfulton - [Java] #1240 Suppress Java 9 deprecation warnings on finalize method. - -2019-02-21: ZackerySpytz - #1480 Fix some rejections of valid floating-point literals. - -2019-02-19: wsfulton - #1475 Fix regression parsing gcc preprocessor linemarkers in the form: - - # linenum filename flags - -2019-02-18: jakecobb - [Python] #945 #1234 Elements in std::vector memory access fix. - - Accessing an element in a std::vector obtains a reference to the element via an - iterator pointing to the element in the container. If the vector is garbage collected, - the SWIG wrapper containing the pointer to the element becomes invalid. The fix is - to obtain a back-reference to the container by the wrapper to the element in the Python - layer to prevent the garbage collector from destroying the underlying container. - -2019-02-17: wsfulton - Fix typemap matching to expand template parameters when the name contains - template parameters. In the %typemap below the type is T and the name is X<T>::make - and the name now expands correctly to X< int >::make - - template<typename T> struct X { - %typemap(out) T X<T>::make "..." - T make(); - }; - - %template(Xint) X<int>; - -2019-02-16: wsfulton - Fix parser error containing multiple #define statements inside an enum. - - The second #define fails to parse: - - enum FooEnum { - ENUM1 = 0, - ENUM2 = 1, - - #define MACRO_DEF1 "Hello" - #define MACRO_DEF2 "World!" - - ENUM3 = 2, - ENUM4 = 3, - }; - - Bug mentioned at https://sourceforge.net/p/swig/patches/333/ - -2019-02-14: wsfulton - Add some missing copy constructors into STL containers. - -2019-02-14: bkotzz - [Java] #1356 Add STL containers: - std::unordered_map - std::unordered_set - std::set - -2019-02-14: bkotzz - [Java] #1356 std::map wrappers have been modified. Now the Java proxy class - extends java.util.AbstractMap. The std::map container looks and feels much like - a java.util.HashMap from Java. - - A few members have changed their names. If the old method signatures are needed, - then copy std_map.i from swig-3.0.12 and use that instead. Alternatively, - add the old missing methods to the new methods by using the following %proxycode: - - %extend std::map { - %proxycode %{ - // Old API - public boolean empty() { - return isEmpty(); - } - public void set($typemap(jboxtype, K) key, $typemap(jboxtype, T) x) { - put(key, x); - } - public void del($typemap(jboxtype, K) key) { - remove(key); - } - public boolean has_key($typemap(jboxtype, K) key) { - return containsKey(key); - } - %} - } - - *** POTENTIAL INCOMPATIBILITY *** - -2019-02-13: ZackerySpytz - #1469 Add support for C++17 hexadecimal floating literals. - -2019-02-11: wsfulton - [OCaml] #1437 OCaml has been give the 'Experimental' language status. The examples work - and most of the test-suite is also working, so it is quite close to being a 'Supported' language. - -2019-02-10: ZackerySpytz - #1464 Add support for C++14 binary integer literals. - -2019-02-10: ZackerySpytz - #1450 Add support for C++11 UCS-2 and UCS-4 character literals. Also, add support for - C++17 UTF-8 character literals. - -2019-02-10: wsfulton - [MzScheme] #1437 MzScheme/Racket is now an 'Experimental' language. The examples work - and a large portion of the test-suite is also working. - -2019-02-10: wsfulton - [MzScheme] Destructor wrappers were not being generated. - -2019-02-10: wsfulton - [MzScheme] Static variable wrappers fixed - $argnum was not expanded. - -2019-02-10: sethrj - #1452 Fix %apply for anonymous template instantiations - -2019-02-09: olly - [PHP] Fix access to already released memory during PHP module - shutdown, which often didn't cause visible problems, but could - result in segmentation faults, bus errors, etc. Fixes #1170, - reported by Jitka Plesníková. - -2019-02-09: olly - [PHP] A renamed constructor is now wrapped as a static method in - PHP. - -2019-02-08: olly - [PHP] Don't generate code which references $r when $r hasn't been - defined. This could happen in overloaded methods which returned - void and took at least one const std::string& parameter. - -2019-02-08: olly - [PHP] The generated code is now compatible with PHP 7.3, and the - testsuite now runs cleanly with this version too. - -2019-02-05: wsfulton - #1437 SWIG now classifies the status of target languages into either 'Experimental' or - 'Supported'. This status is provided to indicate the level of maturity to expect when using - a particular target language as not all target languages are fully developed. Details are - in the Introduction.html chapter of the documentation. - -2019-02-04: wsfulton - [CFFI] #1447 Common Lisp CFFI has been disabled as a target language in SWIG as part of a - clean up to remove target languages that have been neglected/not functional. - -2019-02-04: wsfulton - [Allegrocl] #1447 Allegro Common Lisp has been disabled as a target language in SWIG as part of a - clean up to remove target languages that have been neglected/not functional. - -2019-02-04: wsfulton - [Chicken] #1447 CHICKEN has been disabled as a target language in SWIG as part of a - clean up to remove target languages that have been neglected/not functional. - -2019-02-04: wsfulton - [CLISP] #1447 GNU Common Lisp has been disabled as a target language in SWIG as part of a - clean up to remove target languages that have been neglected/not functional. - -2019-02-04: wsfulton - [S-EXP] #1447 Common Lisp S-Exp has been disabled as a target language in SWIG as part of a - clean up to remove target languages that have been neglected/not functional. - -2019-02-04: wsfulton - [UFFI] #1447 Common Lisp UFFI has been disabled as a target language in SWIG as part of a - clean up to remove target languages that have been neglected/not functional. - -2019-02-04: wsfulton - [Pike] #1447 Pike has been disabled as a target language in SWIG as part of a - clean up to remove target languages that have been neglected/not functional. - -2019-02-04: wsfulton - [Modula3] #1447 Modula3 has been disabled as a target language in SWIG as part of a - clean up to remove target languages that have been neglected/not functional. - -2019-02-02: ahnolds - [Python] Documentation enhancements for Python: - - #728 Fixed the handling of autodoc when using -fastproxy. - - #1367 Added documentation to wrapped member variables using the - property(... doc="...") construct. - - Only show a single documentation entry for functions with default arguments when - using autodoc. - - Fixed a bug where a cached doxygen docstring could be deleted while still in use, - causing swig to segfault. - -2019-01-31: olly - SWIG now requires a target language to be specified instead of - defaulting to wrapping for Tcl. Specifying swig --help without - a target language now just shows the generic help. The -nolang - option has been removed. - -2019-01-28: ZackerySpytz - [OCaml] #1429 Remove support for OCaml versions < 3.12.0. - - *** POTENTIAL INCOMPATIBILITY *** - -2019-01-22: vadz - [Ruby, Octave] #1424 Improve autodoc parameter naming. - -2019-01-22: vadz - [Python] #1271 #1423 Always include default parameter values in autodoc strings. - -2019-01-19: vadz - #1272, #1421 When a function's parameter is a keyword, the name of the paramater is - no longer simply changed to argN, where N is the argument number. Instead the - parameter name is changed to the renaming rules for keywords that normally apply to - symbols such as classes/functions etc. Note that unlike other symbol renaming, - parameter renaming does not issue a warning when the parameter is renamed. This - change only affects languages where the parameter names are actually used, for example, - Java function parameter lists in the proxy class or Python documentation comments. - -2019-01-18: wsfulton - #1420 Fix gdb debugger functions 'swigprint' and 'locswigprint' from swig.gdb to - work with newer versions of gdb-8. Fixes errors when debugging SWIG source with gdb: - - (gdb) swigprint n - Undefined command: "Printf". Try "help". - -2019-01-16: wsfulton - Python static method wrapper changes - - - Static method wrappers were using the 'fastproxy' approach by default. - This is inconsistent with instance method wrappers. The fastproxy approach - is now turned off by default to be consistent with instance methods. - Static method wrappers can now also be controlled using the -fastproxy and - -olddefs options. - - Example: - - struct Klass { - static int statmethod(int a = 2); - }; - - generates by default: - - class Klass(object): - ... - @staticmethod - def statmethod(a=2): - return _example.Klass_statmethod(a) - - instead of the following (which can be restored by using -fastproxy): - - class Klass(object): - ... - statmethod = staticmethod(_example.Klass_statmethod) - - - Modernise wrappers for static methods to use decorator syntax - @staticmethod. - - - Add missing runtime test for static class methods and using the actual class method. - -2019-01-12: ZackerySpytz - [OCaml] #1403 #1194 Fix compilation problems for OCaml >= 4.03.0 due to OCaml using - int64_t instead of int64. - -2019-01-11: ZackerySpytz - [OCaml] #1400 Fix the getters and setters of non-static member variables. - -2019-01-07: wsfulton - #358 Add VOID to windows.i - -2019-01-05: wsfulton - #948 #1019 #1273 Fix for C++11 raw strings where the delimiters were mistakenly left - in the string contents in situations where the string was copied into generated code. - For example, %constant, the "docstring" feature and for C#/Java/D constants turned on - with %javaconst/%csconst/%dmanifestconst. - -2019-01-05: wsfulton - [Ruby] #538. Fix Ruby support for %feature("docstring"). - -2019-01-03: wsfulton - #1202 Fix overloading of non-pointer class types in scripting languages when overloaded - with a pointer and a NULL scripting language equivalent is used, eg None in Python. - - The implementation changes the SWIGTYPE, SWIGTYPE& and SWIGTYPE&& typecheck typemaps to - prevent accepting a conversion to a NULL pointer. - -2019-01-03: ZackerySpytz - [OCaml] #1386 Fix the OCaml examples and test suite for out-of-source builds. - -2019-01-01: wsfulton - [Python] #639 remove duplicate proxy method definitions for global function wrappers. - - Global functions previously generated two definitions, eg: - - def foo(): - return _example.foo() - foo = _example.foo - - The first definition is replaced by the second definition and so the second definition - is the one used when the method is actually called. Now just the first definition is - generated by default and if the -fastproxy command line option is used, just the second - definition is generated. The second definition is faster as it avoids the proxy Python - method as it calls the low-level C wrapper directly. Using both -fastproxy and -olddefs - command line options will restore the previously generated code as it will generate both - method definitions. - - With this change, the wrappers for global C/C++ functions and C++ class methods now work - in the same way wrt to generating just a proxy method by default and control via - -fastproxy/-olddefs options. - -2018-12-20: hasinoff,wsfulton - [Java] #1334 Set Java thread name to native thread name when using directors. - - Default is to use name "Thread-XXX" and is still works like this by default. However, - adding the following will turn on the thread name setting (works for more recent - versions of Linux and MacOS): - - %begin %{ - #define SWIG_JAVA_USE_THREAD_NAME - %} - -2018-12-20: chlandsi - [Python] #1357. Fix overriding __new__ in Python 3.6. - - Fixes SystemError: Objects/tupleobject.c:81: bad argument to internal function" - -2018-12-16: wsfulton - [Python] #848 #1343 The module import logic has changed to stop obfuscating real ImportError - problems. Only one import of the low-level C/C++ module from the pure Python module is - attempted now. Previously a second import of the low-level C/C++ module was attempted - after an ImportError occurred and was done to support 'split modules'. A 'split module' is - a configuration where the pure Python module is a module within a Python package and the - low-level C/C++ module is a global Python module. Now a 'split module' configuration is - no longer supported by default. This configuration can be supported with a simple - customization, such as: - - %module(package="mypackage", moduleimport="import $module") foo - - or if using -builtin: - - %module(package="mypackage", moduleimport="from $module import *") foo - - instead of - - %module(package="mypackage") foo - - See the updated Python chapter titled "Location of modules" in the documentation. - -2018-12-11: tlby - [Perl] #1374 repair EXTEND() handling in typemaps - -2018-12-06: vadz - #1359 #1364 Add missing nested class destructor wrapper when the nested class is - inside a template. Removes associated bogus 'Illegal destructor name' warning. Only - occurred when the nested class' destructor is explicitly specified. - -2018-12-04: adr26 - [Python] #1368 #1369 Access Violation in tp_print caused by mismatched Python/extension - CRT usage - - Remove all use of tp_print, as this API uses a FILE*, which can be - mismatched when modules are built with different C libraries from - the main python executable. - - This change also brings consistent output between Python 2 and 3 for the 'cvar' SWIG - object (that contains the global variables) and SWIG packed objects (such as callback - constants). - -2018-12-04: wsfulton - [Python] #1282 Fix running 'python -m' when using 'swig -builtin' - - Similar to the earlier PEP 366 conforming fix for non-builtin. - -2018-11-29: adr26 - [Python] #1360 Leak of SWIG var link object - - Fix reference counting on _SWIG_globals to allow var link to be freed on module unload. - -2018-11-28: wsfulton - [Python] When using -builtin, the two step C-extension module import is now - one step and the wrapped API is only available once and not in an underlying - module attribute like it is without -builtin. To understand this, consider a - module named 'example' (using: %module example). The C-extension is compiled into - a Python module called '_example' and a pure Python module provides the actual - API from the module called 'example'. It was previously possible to additionally - access the API from the module attribute 'example._example'. The latter was an - implementation detail and is no longer available. It shouldn't have been used, but - if necessary it can be resurrected using the moduleimport attribute described in the - Python chapter of the documentation. If both modules are provided in a Python - package, try: - - %module(moduleimport="from . import _example\nfrom ._example import *") example - or more generically: - %module(moduleimport="from . import $module\nfrom .$module import *") example - - and if both are provided as global modules, try: - - %module(moduleimport="import _example\nfrom _example import *") example - or more generically: - %module(moduleimport="import $module\nfrom $module import *") example - - The module import code shown will appear in the example.py file. - -2018-11-24: vadz - #1358 Fix handling of abstract base classes nested inside templates - - Correct detecting of whether a derived class method overrides a pure virtual - base class method when both classes are nested inside a template class: this - notably didn't work correctly for methods taking parameters of the base class - type. - -2018-11-22: rupertnash - [Python] #1282 Make generated module runnable via python -m (PEP 366 conforming) - - Previously any SWIG generated modules in a package would fail with an ImportError - when using 'python -m' for example 'python -m mypkg.mymodule'. - - This fix also allows the SWIG generated module to be placed into a directory and - then renamed __init__.py to convert the module into a package again. This ability - stopped working in swig-3.0.9. However, only Python 2.7 or 3.3 and later work. If - Python 3.2 support is needed, use moduleimport in %module to customise the import - code. - -2018-11-13: wsfulton - #1340 Remove -cppcast and -nocppcast command line options (this was an option - available to the scripting language targets). - - The -cppcast option is still turned on by default. The -nocppcast option - to turn off the use of c++ casts (const_cast, static_cast etc) has been - removed. However, defining SWIG_NO_CPLUSPLUS_CAST will still generate C casts - instead of C++ casts for C++ wrappers. - - *** POTENTIAL INCOMPATIBILITY *** - -2018-11-13: wsfulton - [Python] #1340 Remove -outputtuple and -nooutputtuple command line options. - - Both the command line and %module options of the same name have been - removed. These were undocumented. The -outputtuple option returned a - Python tuple instead of a list, mostly typically in the OUTPUT - typemap implementations. - - It unclear why a tuple instead of a list return type is needed and - hence this option has been removed as part of the simplification of - the SWIG Python command line options for SWIG 4. - -2018-11-13: wsfulton - [Python] #1340 Remove -noproxyimport command line option. - - This option turned off the insertion of Python import statements - derived from a %import directive. For example given: - - %module module_b - %import "module_a.i" - - then module_b.py will contain: - - import module_a - - *** POTENTIAL INCOMPATIBILITY *** - -2018-10-29: AlexanderGabriel - [PHP] The following PHP7 reserved keywords are now only renamed by - SWIG when used as function names in the API being wrapper: - __halt_compiler array die echo empty eval exit include include_once - isset list print require require_once return unset - -2018-10-22: olly,wsfulton - [Python] #1261 #1340 Turn on many optimisation options by default and rationalise the - number of command line options. - - There were an unnecessary number of command line options and many of these have now - been removed in a drive for simplification. Some were needed to support older versions - of Python (2.6 and earlier). - - Many of the options could be turned on individually and when using -O. Previously -O - resulted in turning on a set of options: - - -modern -fastdispatch -nosafecstrings -fvirtual -noproxydel - -fastproxy -fastinit -fastunpack -fastquery -modernargs -nobuildnone - - Now -O results in turning on this reduced set: - - -fastdispatch -fastproxy -fvirtual - - The following options are now on by default, a deprecated warning is displayed if they - are used: - -fastinit Class initialisation code done in C/C++ rather than in Python code. - -fastquery Python dictionary used for lookup of types. - -fastunpack Faster unpacking of function arguments in C/C++ wrappers. - -modern Use Python 2.3 features such as object and property. - -modernargs Use Python 2.3 C APIs for unpacking arguments in tuples. - -noproxydel Stop generating a proxy __del__ method for backwards compatiblity. - -safecstrings No discernable difference - - The following options have been removed altogether: - -aliasobj0 - -buildnone - -classptr - -new_repr - -newrepr - -noaliasobj0 - -nobuildnone - -nocastmode - -nodirvtable - -noextranative - -nofastinit - -nofastproxy - -nofastquery - -nomodern - -nomodernargs - -nooutputtuple - -nosafecstrings - -old_repr - -oldrepr - -proxydel - - -new_vwm is no longer supported. Use the -newvwm alias instead. - - *** POTENTIAL INCOMPATIBILITY *** - -2018-10-22: olly - [Python] #1261 Remove command line option no longer needed as Python 2.3 and earlier - are no longer supported: - - -classic - -2018-10-09: wsfulton - [D, Go, Guile, Lua, Mzscheme, Ocaml, Perl5, Php, Scilab, Tcl] - Allow wrapping of std::map using non-default comparison function. - -2018-10-09: vadz - [Java] #1274 Allow wrapping of std::map using non-default comparison function. - -2018-10-04: wsfulton - [Python] #1126 Fix C default arguments with -builtin and -fastunpack and -modernargs. - Problem occurred when there is just one (defaulted) parameter in the parameter list. - -2018-09-24: wsfulton - [Python] #1319 C++11 hash tables implementation is finished now (including for -builtin): - std::unordered_map - std::unordered_set - std::unordered_multimap - std::unordered_multiset - -2018-09-21: wsfulton - [Python] Fix when using -builtin and wrapping std::map, std::set, std::unordered_map or - std::unordered_set to ensure __contains__ is called. This is a wrapper for the STL - container's find method. Without it, Python will do its own slower sequence search. - -2018-09-19: wsfulton - [Python] Fix functors (wrapped as __call__) when using -builtin -modern -fastunpack. - -2018-09-02: andreas.gaeer,tkrasnukha - [Python] #1321 Fix assert in PyTuple_GET_SIZE in debug interpreter builds of python-3.7 - when calling tp_new. - -2018-09-01: ChristopherHogan - [Guile] #1288 Fix garbage collection for guile >= 2.0.12. - -2018-08-31: wsfulton - [Python] #1319 C++11 hash tables support: - std::unordered_map - std::unordered_set - std::unordered_multimap - std::unordered_multiset - is now compiling and working (sorting using -builtin not fully functional yet though). - -2018-08-20: wkalinin - #1305 Fix nested structure symbol tables in C mode to fix member name conflicts - in different structs with the same nested struct member name. - -2018-08-18: wsfulton - [Python] #688 Fix makefile recursion when running python test-suite. - -2018-08-18: wsfulton - [Python] #1310 Re-implement Python -fastproxy option. - - The previous implementation failed with Python 3 and abstract base clases. - The new implementation replaces the Python 2 implementation using - new.instancemethod with the C API PyMethod_New to match the equivalent Python 3 - implementation which uses PyInstanceMethod_New. - - The new approach runs slightly faster. See #1310. - -2018-08-12: gmazzamuto - [Python] #1283 Update pybuffer.i library to use new-style Python buffer C API. - -2018-08-12: brianhatwood,wsfulton - [Java] #1303 #1304 Fix crash in directors when using OUTPUT and INOUT typemaps in typemaps.i and - passing NULL pointers in C++ to director method overloaded and implemented in Java. - -2018-08-10: wsfulton - [Python] #1293 Improve TypeError message inconsistencies between default and fastdispatch - mode when handling overloaded C++ functions. Previously the error message did not always - display the possible C/C++ prototypes in fastdispatch mode. - -2018-08-02: furylynx,jacobwgillespie,p2k - [Javascript] #1290, #968. Add support for NodeJS versions 2-10. - -2018-07-31: wsfulton - [Python] #1293 Overloaded C++ function wrappers now raise a TypeError instead - of NotImplementedError when the types passed are incorrect. This change means - there is now consistency with non-overloaded function wrappers which have always - raised TypeError when the incorrect types are passed. The error message remains - the same and is for example now: - - TypeError: Wrong number or type of arguments for overloaded function 'f'. - Possible C/C++ prototypes are: - f(int) - f(char const *) - - instead of: - - NotImplementedError: Wrong number or type of arguments for overloaded function 'f'. - Possible C/C++ prototypes are: - f(int) - f(char const *) - - *** POTENTIAL INCOMPATIBILITY *** - -2018-06-23: wsfulton - [Python] #718 Fix pythonnondynamic feature for modern classes - - Fixes nondynamic mode when an instance variable is set with the same - name as a class variable in a class derived from a SWIG proxy class. - This corner case set an instance variable instead of raising an AttributeError. - - Also fix %pythonnondynamic in Python 3 with -modern. The metaclass - containing the implementation was previously not being applied in Python 3. - -2018-07-17: petrmitrichev,wsfulton - [Python] #1275 #1279 Initialize function-local statics (singletons) that call Python - code during Python module initialization in order to avoid deadlocks with subsequent - multi-threaded usage. - -2018-06-15: wsfulton - [Python] Fix seg fault using Python 2 when passing a Python string, containing - invalid utf-8 content, to a wstring or wchar * parameter. A TypeError is thrown instead, eg: - - %include <std_wstring.i> - void instring(const std::wstring& s); - - instring(b"h\xe9llooo") # Python - -2018-06-15: wsfulton - [Python] Python 3.7 support: Replace use of deprecated PyUnicode_GetSize with - PyUnicode_GetLength to remove deprecated warnings compiling the C/C++ wrappers. - -2018-06-12: wsfulton - [Python] Python 3.7 support: The %pythonabc feature in pyabc.i now uses base classes - collections.abc.MutableSequence - collections.abc.MutableMapping - collections.abc.MutableSet - instead of - collections.MutableSequence - collections.MutableMapping - collections.MutableSet - as the latter are deprecated in Python 3.7 and are due to be removed in Python 3.8. - The classes in collections.abc.* are available from Python 3.3 onwards. If you - require support for Python 3.2, then copy the pyabc.i file and modify by removing - the few instances of the .abc sub-module. - - *** POTENTIAL INCOMPATIBILITY *** - -2018-06-12: olly,wsfulton - [Python] #701 Remove support for Python versions < 2.7 and 3.0 and 3.1. - - *** POTENTIAL INCOMPATIBILITY *** - -2018-06-11: olly - [Python] Fix new GCC8 warnings in generated code by avoiding casts - between incompatible function types where possible, and by - suppressing the warning when it's due to the design of Python's C - API. Fixes #1259. - -2018-06-08: philippkraft - [Python] Stop exposing <CLASS>_swigregister to Python. It's not - useful for user Python code to call this, and it just clutters the - API unnecessarily. Fixes #1225. - -2018-06-07: cmfoil, kabbi, Jamie Kirkpatrick, markok314, vadz, wsfulton, Yann Diorcet - #170 Doxygen documentation support added. This allows translation of Doxygen comments - into JavaDoc and PyDoc documentation. It is enabled via the -doxygen command line - option. See the Doxygen.html chapter in the documentation for further information. - -2018-06-07: olly - [PHP] We've finally removed support for %pragma(php4) which was - deprecated back in 2008. Use %pragma(php) instead, which has been - supported since at least 2005. - - *** POTENTIAL INCOMPATIBILITY *** - -2018-06-07: olly - [PHP5] Support for PHP5 has been removed. PHP5 is no longer - actively supported by the PHP developers and security support for - it ends completely at the end of 2018, so it doesn't make sense - to include support for it in the upcoming SWIG 4.0.0 release. - - *** POTENTIAL INCOMPATIBILITY *** - -2018-06-06: olly - [Lua] Improve configure probes for Lua headers and libs used in testsuite. - -2018-05-15: kwwette - [Octave] add support for version 4.4 - - Should not introduce any user-visible incompatibilities - -2018-05-15: wsfulton - [C#, D, Java] Fix lookup of csconstruct, dconstruct and javaconstruct typemaps. - The C++ namespace was previously ignored when looking up the typemap. - -2018-05-15: wsfulton - [Javascript] Fix generated C++ code when using %nspace on namespaces that are more - than two levels deep. - -2018-05-14: wsfulton - Issue #1251 Add support for C++17 nested namespace definitions, - for example: - namespace A::B { ... } - -2018-05-11: wsfulton - [C#, D, Java] Add support so that the %csmethodmodifiers, %dmethodmodifiers, - %javamethodmodifiers can modify the method modifiers for the destructor wrappers - in the proxy class: dispose, Dispose, delete. With this feature, it is now possible - to make a C# proxy class sealed, eg when wrapping a class X, the virtual method modifiers - can be removed using: - - %typemap(csclassmodifiers) X "public sealed class" - %csmethodmodifiers X::~X "public /*virtual*/"; - -2018-04-18: olly - [Python] Suppress new pycodestyle warning: - E252 missing whitespace around parameter equals - -2018-04-07: goatshriek - [Ruby] #1213 Fix ruby %alias directive for global C/C++ functions. - -2018-04-03: olly - [Ruby] Fix to pass Qnil instead of NULL to rb_funcall(), which silences GCC - -Wconversion-null warning (on by default with recent GCC). - -2018-03-09: wsfulton - [Java] #1184 Fix swigReleaseOwnership() and swigTakeOwnership() regression - for non-director classes. Restores a dynamic_cast which was previously removed. - -2018-03-07: llongi - Github PR #1166 - Fix preprocessor handling of macros with commas - in a // comment. - -2018-02-18: JPEWdev - Patch #1164 - Add support for a command-line options file, also sometimes - called a response file. This is useful if the command-line options exceed - the system command-line length limit. To use, put the command-line options - into a file, then provide the file name prefixed with @, for example using - a file called args.txt: - - swig @args.txt - -2018-02-11: wsfulton - [Javascript] #1187 Fix compilation error wrapping std::complex via - std_complex.i. - -2018-01-30: smarchetto - [Scilab] add type name argument in SWIG_ptr() function to cast from pointer address to typed pointers - -2018-01-16: wsfulton - Expressions following a preprocessor directive must now be separated by whitespace - or non-numeric characters. This syntax change makes the SWIG preprocessor work like - the C preprocessor in this area. - - For example, the following code used be accepted as valid syntax: - #if1 - #define ABC 123 - #endif - - Now you get an error: - example.h:1: Error: Unknown SWIG preprocessor directive: if1 (if this is a block of - target language code, delimit it with %{ and %}) - example.h:3: Error: Extraneous #endif. - - The following is the correct syntax: - #if 1 - #define ABC 123 - #endif - - The following of course also works: - #if(1) - #define ABC 123 - #endif - - *** POTENTIAL INCOMPATIBILITY *** - -2018-01-15: wsfulton - Fix issue #1183. Floating point exception evaluating preprocessor expressions - resulting in division by zero. - -2018-01-14: wsfulton - Fix issue #1172. Seg fault parsing invalid exponents in the preprocessor. - -2018-01-12: Liryna - [C#] Patch #1128. Add ToArray function to std::vector wrappers. - -2018-01-12: wsfulton - [Java] Fix issue #1156. Add missing throws clause for interfaces when using the - %interface family of macros. - -2018-01-05: wsfulton - Fix default arguments using expressions containing -> syntax error. Problem reported on - swig-user mailing list. - -2017-12-30: wsfulton - [Python] Replace pep8 with pycodestyle for checking the Python code style when - running Python tests. - -2017-12-30: davedissian - Fixed a symbol lookup issue when encountering a typedef of a symbol from the tag - namespace to the global namespace when the names are identical, such as 'typedef - struct Foo Foo;'. - -2017-12-13: wsfulton - [Perl] add missing support for directorfree typemaps. - -2017-12-13: wsfulton - Issue #1167 Fix directorout typemaps which were causing undefined behaviour when - returning pointers by reference. - -2017-12-08: olly - [PHP] Use ZEND_MODULE_GLOBALS_ACCESSOR to access globals so the - generated code builds when PHP was built with ZTS enabled. - -2017-12-04: wsfulton - [Python] Add missing checks for failures in calls to PyUnicode_AsUTF8String. Previously a - seg fault could occur when passing invalid UTF8 strings (low surrogates), eg passing - u"\udcff" to the C layer (Python 3). - -2017-11-24: joequant - [R] Fix #1124 and return R_NilValue for null pointers - -2017-11-29: wsfulton - [Java] director exception handling improvements. - - When a director method throws an exception and it is caught by DirectorException - and passed back to Java using Swig::DirectorException::throwException, the Java - stack trace now contains the original source line that threw the exception. - - Deprecate Swig::DirectorException::raiseJavaException, please replace usage with - Swig::DirectorException::throwException. - - *** POTENTIAL INCOMPATIBILITY *** - -2017-10-26: wsfulton - Add support for C++11 ref-qualifiers when using directors. - -2017-10-26: wsfulton - Fix generated code when using directors and methods returning const ref pointers. - -2017-10-26: wsfulton - [C#, D, Java, Octave, R, Scilab] Port director typemaps to these additional languages. - Issue #700. - -2017-10-26: radarsat1 - [Ruby Python] Patch #1029 - Correct handling of null using directors and shared_ptr. - -2017-10-10: joequant - [R] pass enum expressions to R. This will generate - incorrect files when there is an arithmetic expression - in the enum, but this is better than silently generating - incorrect code - -2017-10-09: olly - [PHP] Fix incorrect wrapper code generated when there's a - combination of overloading, parameters with a default value - and %newobject. Fixes https://sourceforge.net/p/swig/bugs/1350/ - -2017-10-09: olly - Remove GCJ support. It isn't in a good state and doesn't seem to - be used, and GCC7 dropped GCJ. Closes - https://sourceforge.net/p/swig/bugs/823/ - -2017-10-07: olly - Fix preprocessor handling of empty macro arguments to match that of - C/C++ compilers. Fixes issue #1111 and - https://sourceforge.net/p/swig/bugs/826/ - -2017-10-06: wsfulton - [Python] Issue #1108. Fix platform inconsistency in Python default argument handling. - 32 bit and 64 bit compiled versions of SWIG generated different Python files - when default arguments were outside the range of 32 bit signed integers. - The default arguments specified in Python are now only those that are in the - range of a 32 bit signed integer, otherwise the default is obtained from C/C++ code. - -2017-10-02: wsfulton - [C#] Fix std::complex types passed by value. - -2017-10-02: wsfulton - [Javascript, Python, Ruby] Issue #732 - Missing type information for std::complex - in std_complex.i meant that previously std::complex always had to be fully qualified - in order to be wrapped with the appropriate typemaps. - -2017-10-01: joequant - allow R package names with docs - allowing multiple get accessors in R - fix smart-pointer and NAMESPACE support - constructors now returning smart pointers (if class - declared as such) - smart-pointer classes deriving from parent smart-pointers - -2017-09-29: wsfulton - Issue #1100 - Allow an instantiated template to have the same name in the target - language as the C++ template name, for example, this is now possible: - - template<typename T> struct X { ... }; - %template(X) X<int>; - -2017-09-23: wsfulton - Issue #1098. Fix overloading of shared_ptr with underlying pointer types, eg: - - void m(std::shared_ptr<T> p); - void m(T &p); - void m(T *p); - - Only the first method is wrapped and the others are ignored/shadowed. - The implementation is done via a new attribute in the 'typecheck' typemap called - 'equivalent'. If specified, it must contain the equivalent pointer type for overloading - and can only be used for the special SWIG_TYPECHECK_POINTER precedence level. - The shared_ptr 'typecheck' typemaps have been modified accordingly. - Here is a simplified version: - - %typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="T *") - T, - T CONST &, - T CONST *, - T *CONST&, - std::shared_ptr< T >, - std::shared_ptr< T > &, - std::shared_ptr< T > *, - std::shared_ptr< T > *& - { ... } - - Overloading with any of these types will result in SWIG ignoring all but the first - overloaded method by default. Without the 'equivalent' attribute, wrapping the overloaded - methods resulted in types being shadowed (scripting languages) or code that did not - compile (statically typed languages). - -2017-09-19: futatuki - [Python] #1003 Add --with-2to3=/path/to/2to3 option to configure. - -2017-09-18: wsfulton - Fix type promotion wrapping constant expressions of the form: - # define EXPR_MIXED1 (0x80 + 11.1) - 1 - This was previously an integral type instead of a floating point type. - -2017-09-17: wsfulton - Fix generated code for constant expressions containing wchar_t L literals such as: - # define __WCHAR_MAX (0x7fffffff + L'\0') - # define __WCHAR_MIN (-__WCHAR_MAX - 1) - -2017-09-10: mlamarre - [Python] Patch #1083. Define_DEBUG to 1 to do exactly like Visual Studio - /LDd, /MDd or /MTd compiler options. - -2017-08-25: wsfulton - Issue #1059. Add support for C++11 ref-qualifiers on non-static member functions. - Members with lvalue ref-qualifiers such as: - - struct RQ { - void m1(int x) &; - void m2(int x) const &; - }; - - are wrapped like any other member function. Member functions with rvalue ref-qualifiers - are ignored by default, such as: - - struct RQ { - void m3(int x) &&; - void m4(int x) const &&; - }; - - example.i:7: Warning 405: Method with rvalue ref-qualifier m3(int) && ignored. - example.i:8: Warning 405: Method with rvalue ref-qualifier m4(int) const && ignored. - - These can be unignored and exposed to the target language, see further documentation in - CPlusPlus11.html. - -2017-08-16: wsfulton - Fix #1063. Add using declarations to templates into typedef table. - - Using declarations to templates were missing in SWIG's internal typedef tables. - This led to a few problems, such as, templates that did not instantiate and generated - C++ code that did not compile as SWIG did not know what scope the template was - in. This happened mostly when a using declaration was used on a template type in a - completely unrelated namespace. - -2017-08-16: wsfulton - Fix type lookup in the presence of using directives and using declarations. - - Fix some cases of type lookup failure via a combination of both using directives and - using declarations resulting in C++ code that did not compile as the generated type was - not fully qualified for use in the global namespace. Example below: - - namespace Space5 { - namespace SubSpace5 { - namespace SubSubSpace5 { - struct F {}; - } - } - using namespace SubSpace5; - using SubSubSpace5::F; - void func(SubSubSpace5::F f); - } - -2017-08-16: wsfulton - Issue #1051. %template scope enforcement and class definition fixes. - - The scoping rules around %template have been specified and enforced. - The %template directive for a class template is the equivalent to an - explicit instantiation of a C++ class template. The scope for a valid - %template instantiation is now the same as the scope required for a - valid explicit instantiation of a C++ template. A definition of the - template for the explicit instantiation must be in scope where the - instantiation is declared and must not be enclosed within a different - namespace. - - For example, a few %template and C++ explicit instantiations of std::vector - are shown below: - - // valid - namespace std { - %template(vin) vector<int>; - template class vector<int>; - } - - // valid - using namespace std; - %template(vin) vector<int>; - template class vector<int>; - - // valid - using std::vector; - %template(vin) vector<int>; - template class vector<int>; - - // ill-formed - namespace unrelated { - using std::vector; - %template(vin) vector<int>; - template class vector<int>; - } - - // ill-formed - namespace unrelated { - using namespace std; - %template(vin) vector<int>; - template class vector<int>; - } - - // ill-formed - namespace unrelated { - namespace std { - %template(vin) vector<int>; - template class vector<int>; - } - } - - // ill-formed - namespace unrelated { - %template(vin) std::vector<int>; - template class std::vector<int>; - } - - When the scope is incorrect, an error now occurs such as: - - cpp_template_scope.i:34: Error: 'vector' resolves to 'std::vector' and - was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'. - - Previously SWIG accepted the ill-formed examples above but this led to - numerous subtle template scope problems especially in the presence of - using declarations and using directives as well as with %feature and %typemap. - - Actually, a valid instantiation is one which conforms to the C++03 - standard as C++11 made a change to disallow using declarations and - using directives to find a template. - - // valid C++03, ill-formed C++11 - using std::vector; - template class vector<int>; - - Similar fixes for defining classes using forward class references have - also been put in place. For example: - - namespace Space1 { - struct A; - } - namespace Space2 { - struct Space1::A { - void x(); - } - } - - will now error out with: - - cpp_class_definition.i:5: Error: 'Space1::A' resolves to 'Space1::A' and - was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'. - - Previously some symbols would have been instantiated in the wrong scope and led - to lots of scope problems involving SWIG typemaps, features, renames etc. - You will need to correct the scope used in other SWIG directives which do not - support 'using declarations' and 'using directives'. For example, if you previously had: - - %rename(Zap) vector<int>::clear; - using namespace std; - %template(VectorInt) vector<int>; - - Prior versions of SWIG incorrectly instantiated vector<int> in the global namespace - and so the %rename matched. Now the template is instantiated in the correct namespace, - so is fully qualified as std::vector<int>. The other SWIG directives need correcting as - they do not follow 'using declarations' and 'using directives'. Change it to: - - %rename(Zap) std::vector<int>::clear; - using namespace std; - %template(vin) vector<int>; - - - *** POTENTIAL INCOMPATIBILITY *** - -2017-08-16: wsfulton - Fix scope lookup for template parameters containing unary scope operators. - - Fixes cases like: - - namespace Alloc { - template<typename T> struct Rebind { - typedef int Integer; - }; - } - %template(RebindBucket) Alloc::Rebind< Bucket >; - OR - %template(RebindBucket) Alloc::Rebind< ::Bucket >; - - Alloc::Rebind< Bucket >::Integer Bucket1(); - Alloc::Rebind< ::Bucket >::Integer Bucket2(); - Alloc::Rebind<::template TemplateBucket<double>>::Integer Bucket3(); - -2017-08-16: wsfulton - For templates only, the template parameters are fully resolved when - handling typemaps. Without this, it is too hard to have decent rules - to apply typemaps when parameter types are typedef'd and template - parameters have default values. - - Fixes %clear for typedefs in templates, eg: - - %typemap("in") XXX<int>::Long "..." - template typename<T> struct XXX { - typedef long Long; - }; - %clear XXX<int>::Long; - - as the typemap was previously incorrectly stored as a typemap for long - instead of XXX<int>::Long. - -2017-08-05: olly - [C++11] Allow static_assert at the top level (and disallow it right - after template<T>). Fixes issue 1031 reported by Artem V L. - -2017-08-02: wsfulton - Fix incorrectly shown warning when an empty template instantiation was used on a - class used as a base class and that base class was explicitly ignored with %ignore. - Example of the warning which will no longer appear: - - Warning 401: Base class 'Functor< int,int >' has no name as it is an empty - template instantiated with '%template()'. Ignored. - -2017-07-17: fflexo - [Java] #674 Add std_list.i to add support for std::list containers. The Java proxy - extends java.util.AbstractSequentialList and makes the C++ std::list container look - and feel much like a java.util.LinkedList from Java. - -2017-07-07: wsfulton - [Python] Fix display of documented template types when using the autodoc - feature. For example when wrapping: - - %feature("autodoc"); - template<typename X> struct T {}; - %template(TInteger) T<int>; - - the generated documentation contains: - """Proxy of C++ T< int > class.""" - instead of: - """Proxy of C++ T<(int)> class.""" - and - """__init__(TInteger self) -> TInteger""" - instead of - """__init__(T<(int)> self) -> TInteger""" - -2017-06-27: nihaln - [PHP] Update the OUTPUT Typemap to add return statement to the - PHP Wrapper. - -2017-06-27: nihaln - [PHP] Update the enum and value examples to use the OO wrappers - rather than the flat functions produced with -noproxy. There's - not been a good reason to use -noproxy for since PHP5 OO wrapping - was fixed back in 2005. - -2017-06-23: m7thon - [Python] fix and improve default argument handling: - - 1. Fix negative octals. Currently not handled correctly by `-py3` - (unusual case, but incorrect). - 2. Fix arguments of type "octal + something" (e.g. `0640 | 04`). - Currently drops everything after the first octal. Nasty! - 3. Fix bool arguments "0 + something" (e.g. `0 | 1`) are always - "False" (unusual case, but incorrect). - 4. Remove special handling of "TRUE" and "FALSE" from - `convertValue` since there's no reason these have to match - "true" and "false". - 5. Remove the Python 2 vs. Python 3 distinction based on the - `-py3` flag. Now the same python code is produced for default - arguments for Python 2 and Python 3. For this, octal default - arguments, e.g. 0644, are now wrapped as `int('644', 8)`. This - is required, as Python 2 and Python 3 have incompatible syntax - for octal literals. - - Fixes #707 - -2017-06-21: futatuki - #1004 - Fix ccache-swig executable name to respect configure's --program-prefix and - --program-suffix values if used. - -2017-06-21: tamuratak - [Ruby] #911 - Add std::wstring support. - -2017-06-19: wsfulton - [Python] Fix handling of rich comparisons when wrapping overloaded operators: - - operator< operator<= operator> operator>= operator== operator!= - - Previously a TypeError was always thrown if the type was not correct. NotImplemented - is now returned from these wrapped functions if the type being compared with is - not correct. The subsequent behaviour varies between different versions of Python - and the comparison function being used, but is now consistent with normal Python - behaviour. For example, for the first 4 operator overloads above, a TypeError - 'unorderable types' is thrown in Python 3, but Python 2 will return True or False. - NotImplemented should be returned when the comparison cannot be done, see PEP 207 and - https://docs.python.org/3/library/constants.html#NotImplemented - - Note that the bug was only present when overloaded operators did not also have a - function overload. - - Fixes SF bug #1208 (3441262) and SF patch #303. - - *** POTENTIAL INCOMPATIBILITY *** - -2017-06-17: fabrice102 - [Go] Fix Go callback example. Fixes github #600, #955, #1000. - -2017-06-16: wsfulton - Make sure warning and error messages are not split up by other processes writing to - stdout at the same time. - -2017-06-16: wsfulton - [R] Fix wrapping function pointers containing rvalue and lvalue reference parameters. - -2017-06-13: olly - [Perl] Fix testsuite to work without . in @INC - it was removed in - Perl 5.26 for security reasons, and has also been removed from - older versions in some distros. Fixes #997 reported by lfam. - -2017-06-03: wsfulton - Fix %import on a file containing a file scope %fragment forced inclusion to not - generate the fragment contents as %import should not result in code being generated. - The behaviour is now the same as importing code insertion blocks. - Wrapping FileC.i in the following example will result in no generated code, whereas - previously "#include <limits.h>" was generated: - - // FileA.i - %fragment("<limits.h>", "header") %{ - #include <limits.h> - %} - - %{ - #include <stdio.h> - %} - %fragment("<limits.h>"); - - // FileC.i - %import "FileA.i" - - *** POTENTIAL INCOMPATIBILITY *** - -2017-05-26: Volker Diels-Grabsch, vadz - [Java] #842 Extend from java.util.AbstractList<> and implement java.util.RandomAccess for - std::vector wrappers. This notably allows to iterate over wrapped vectors in a natural way. - Note that boxed types are now used in the Java layer when wrapping vector of C primitive - types, for example. This may introduce some subtle incompatibilities due to some - differences in how Java converts boxed types and unboxed types. For example, - - int i=0; - double d1 = i; // ok - Double d2 = i; // error: incompatible types: int cannot be converted to Double - - This can be a problem when calling the add and set functions. A suggested backwards - compatible workaround is to use something like (shown for std::vector<double>: - - #if defined(SWIGJAVA) - // Add in old api that uses non-boxed types - %extend std::vector<double> { - %proxycode %{ - public void add(double x) { - add(Double.valueOf(x)); - } - public void set(int i, double val) { - set(i, Double.valueOf(val)); - } - %} - } - #endif - - %include "std_vector.i" - %template(VectorDouble) std::vector<double>; - - *** POTENTIAL INCOMPATIBILITY *** - -2017-05-30: davidcl - [Scilab] #994 Undefined symbol error when loading in Scilab 6 - -2017-05-25: asibross - [Java] #370 #417 Missing smart pointer handling in Java director extra methods - swigReleaseOwnership() and swigTakeOwnership(). - -2017-05-23: wsfulton - [Java] #230 #759 Fix Java shared_ptr and directors for derived classes java compilation - error. - - For shared_ptr proxy proxy classes, add a protected method swigSetCMemOwn for modifying - the swigCMemOwn and swigCMemOwnDerived member variables which are used by various other - methods for controlling memory ownership. - -2017-05-21: Sghirate - [Java, C#, D] #449 Remove unnecessary use of dynamic_cast in directors to enable - non-RTTI compilation. - -2017-05-21: wsfulton - [Python] #993 Fix handling of default -ve unsigned values, such as: - void f(unsigned = -1U); - -2017-05-20: jschueller - [Python] #991 Fix E731 PEP8 warning: do not assign a lambda expression - -2017-05-16: nihal95 - [PHP] Add %pragma version directive to allow the version of the - extension to be set. Patch #970, fixes #360. - -2017-05-13: yag00 - Patch #975 - Add support for noexcept on director methods. - -2017-04-27: redbrain - Issue #974, Patch #976 - Fix preprocessor handling of macros with commas in a comment. - -2017-04-25: jleveque - [Lua] #959 - Fix Visual Studio C4244 conversion warnings in Lua wrappers. - -2017-04-21: tamuratak - [Ruby] #964 - Add shared_ptr director typemaps. - -2017-04-20: wsfulton - [Ruby] #586, #935 Add assert for invalid NULL type parameter when calling SWIG_Ruby_NewPointerObj. - -2017-04-20: tamuratak - [Ruby] #930, #937 - Fix containers of std::shared_ptr. - Upcasting, const types (eg vector<shared_ptr<const T>>) and NULL/nullptr support added. - -2017-04-12: smarchetto - [Scilab] New parameter targetversion to specify the Scilab target version (5, 6, ..) for code generation - With Scilab 6 target specified, identifier names truncation is disabled (no longer necessary) - -2017-03-24: tamuratak - [Ruby] Fix #939 - Wrapping std::vector<bool> fix due to incorrect null checks - on VALUE obj. - -2017-03-17: vadz - [C#] #947 Add support for std::complex<T> - -2017-03-17: wsfulton - [Go] Fix handling of typedef'd function pointers and typedef'd member function pointers - such as: - - typedef int (*FnPtr_td)(int, int); - int do_op(int x, int y, FnPtr_td op); - -2017-03-16: wsfulton - Add support for member const function pointers such as: - - int fn(short (Funcs::* parm)(bool)) const; - - Also fix parsing of references/pointers and qualifiers to member - pointers such as: - - int fn(short (Funcs::* const parm)(bool)); - int fn(short (Funcs::* & parm)(bool)); - -2017-03-10: wsfulton - Extend C++11 alternate function syntax parsing to support const and noexcept, such as: - - auto sum1(int x, int y) const -> int { return x + y; } - auto sum2(int x, int y) noexcept -> int { return x + y; } - -2017-02-29: tamuratak - [Ruby] #917 - Add Enumerable module to all container class wrappers. It was missing - for std::list, std::multiset, std::unordered_multiset and std::unordered_map. - -2017-02-27: assambar - [C++11] Extend parser to support throw specifier in combination - with override and/or final. - -2017-02-10: tamuratak - [Ruby] #883 - Add support for C++11 hash tables: - std::unordered_map - std::unordered_set - std::unordered_multimap - std::unordered_multiset - -2017-02-08: jcsharp - [C#] #887 Improve std::vector<T> wrapper constructors - - Replace constructor taking ICollection with IEnumerable and also add IEnumerable<T> - constructor to avoid the boxing and unboxing overhead of the original constructor, - when the type parameter is a value type. - -Version 3.0.12 (27 Jan 2017) -============================ - -2017-01-27: wsfulton - [C#] #882 Fix missing filename in error messages when there is a problem - writing out C# files. - -2017-01-27: briancaine - [Guile] #744 Fix compilation errors in Guile wrappers - regression - introduced in swig-3.0.11. - -2017-01-24: andrey-starodubtsev - [Java] Apply #704 - director typemap improvements. - Memory leak fixes, add support for "directorargout" typemap and - add director support to typemaps.i. - -2017-01-24: wsfulton - Enhance %extend to extend a class with template constructors, eg: - - struct Foo { - %extend { - template<typename T> - Foo(int a, T b) { - ... - } - } - }; - %template(Foo) Foo::Foo<double>; - -2017-01-22: wsfulton - Issue #876 Enhance %extend to extend a class with template methods, eg: - - struct Foo { - %extend { - template<typename T> - void do_stuff(int a, T b) { - ... - } - } - }; - %template(do_stuff_inst) Foo::do_stuff<double>; - - Similarly for static template methods. - -2017-01-22: kwwette - [Octave] add support for version 4.2 - - The Octave API now uses some C++11 features. It is recommended to use - the mkoctfile program supplied by Octave to compile the SWIG-generated - wrapper code, as mkoctfile will ensure the correct C++ compiler/options - are used. Otherwise, the value of `mkoctfile -p CXX` should be parsed - for any -std=* flags which might be present. - - Octave has dropped support for << and >> operators, so SWIG now - ignores them. - - The Octave error() function now raises C++ exceptions to propagate - Octave errors, so %exception directives may need to be modified. - For convenience the SWIG_RETHROW_OCTAVE_EXCEPTIONS macro can be used - to rethrow any Octave exceptions for Octave itself to handle, e.g.: - - try { - $action // may call error() - } - SWIG_RETHROW_OCTAVE_EXCEPTIONS // error() exceptions are rethrown - catch(...) { - ... // all other exceptions - } - - *** POTENTIAL INCOMPATIBILITY *** - -2017-01-16: wkalinin - [C#] Fix #733 regression introduced in swig-3.0.9. - Missing virtual function override in C# layer when using %import. - -2017-01-16: fschlimb - Fix #813 template symbol name lookup bug when typedef names are the same but in different - namespaces. - -2017-01-15: wsfulton - [C# D Java] - The SWIG library no longer uses the javatype, dtype or cstype typemaps, thereby - completely freeing them up for users to use without having to replicate the library - code that they previously added. The code previously generated by these typemaps - has been replaced by the new %proxycode directive. Their use in the library code - was fairly minimal: - - C# cstype: std_array.i std_map.i std_vector.i - D dtype: std_vector.i - Java javatype: arrays_java.i - -2017-01-14: wsfulton - The %extend directive can now optionally support one of the 'class', 'struct' or 'union' - keywords before the identifier name, for example: - - struct X { ... }; - %extend struct X { ... } - - Previously this had to specified as: - - struct X { ... }; - %extend X { ... } - -2017-01-13: wsfulton - [C# D Java] Add new %proxycode directive which is a macro for %insert("proxycode"). - This is a way of adding pure C#/D/Java code into the appropriate proxy class, eg: - - %extend Proxy2 { - %proxycode %{ - public int proxycode2(int i) { - return i+2; - } - %} - } - - %inline %{ - struct Proxy2 {}; - %} - - There will then be a pure Java/C#/D method called proxycode2 in the Proxy2 class. - -2016-12-31: ajrheading1 - Issue #860 - Remove use of std::unary_function and std::binary_function - which is deprecated in C++11. - -2016-12-30: olly - [PHP7] Register internal 'swig_runtime_data_type_pointer' constant - as "CONST_PERSISTENT" to avoid segmentation fault on module unload. - Fixes #859 reported by Timotheus Pokorra. Thanks also to Javier Torres - for a minimal reproducer. - -Version 3.0.11 (29 Dec 2016) -============================ - -2016-12-24: wsfulton - [C#] Add %feature("csdirectordelegatemodifiers") to enable customization - of the delegate access modifiers generated in director classes. - Fixes issue #748. - -2016-12-23: wsfulton - [Python] Fix builtin "python:slot" feature failing for tp_hash when using - hashfunc closure with a "Wrong type for hash function" for Python 2. - Issue #843. - -2016-12-21: joequamt - Changed generation of functions so that only functions - that end in _set generate accessor functions rather than - looking for "set". - Change generation of operators to not have underscores - to start in R. Users need to provide custom names for these operator overloads. - -2016-12-21: olly - Fix isfinite() checks to work with all C++11 compilers. - Fixes issues #615, #788 and #849. - -2016-12-20: wsfulton - %namewarn unnecessarily caused keyword warnings for non-instantiated template classes - and duplicate warnings for instantiated template classes when keywords were used. - Issue #845. - -2016-12-18: ezralanglois - [Python, Ruby, Octave] Memory leak fix on error in std::pair wrappers. - Issue #851. - -2016-12-18: wsfulton - Zero initialize arrays when using %array_class and %array_functions. - -2016-12-18: t-ikegami - [Python] Fix #446 - Python %array_class of carrays.i failed with -builtin option. - -2016-12-16: briancaine - [Guile] Patch #744 Added support for Guile's native pointer functionality - -2016-12-01: wsfulton - [Python] Issue #769. - Add optional moduleimport attribute to %module so that the - default module import code can be overridden. See the "Searching for the wrapper module" - documentation in Python.html. Example: - - %module(moduleimport="import _foo") foo - - $module also expands to the low-level C/C++ module name, so the following is the - same as above - - %module(moduleimport="import $module") foo - -2016-11-30: olly - [PHP] Add support for PHP7. PHP5's C extension API has changed - substantially so you need to use -php7 to specify you want PHP7 - compatible wrappers. The default extension for generated wrappers - is now .cxx (to match SWIG's default for every other language - to - generate foo_wrap.cpp you can run SWIG with -cppext cpp). Fixes - issue #571. - - As part of this change, the language subdirectory for PHP5 has - changed from "php" to "php5" - if you are making use of the search - path feature where the language subdirectory of each directory - is also searched, you'll need to update your bindings. A simple - fix which works for older and newer SWIG is to add a symlink: - ln -s php php5 - - *** POTENTIAL INCOMPATIBILITY *** - -2016-11-30: olly - [PHP] Only emit one copy of each distinct arginfo. Previously we - emitted a separate one for every wrapped function, but typically - many functions have the same number of parameters and combinations - of parameters passed by reference or not. - - This change significantly reduces both the size of the generated - wrapper, and of the compiled PHP extension module (e.g. by ~6% for - the stripped extension module for Xapian's PHP7 bindings). - -2016-11-28: wsfulton - Fix %rename override of wildcard %rename for templates. For example: - - %rename(GlobalIntOperator) *::operator bool; // wildcard %rename - - %rename(XIntOperator) X::operator bool; // fix now overrides first %rename above - OR - %rename(XIntOperator) X<int>::operator bool; // fix now overrides first %rename above - - template<typename T> struct X { - operator bool(); - ... - }; - %template(Xint) X<int>; - - This also fixes %rename override of global %rename for templates. For example: - - // Global rename to make all functions start with a lower case letter - %rename("%(firstlowercase)s", %$isfunction ) ""; - %rename(woohoo) W::Woo; // fix now overrides above %rename - - template<typename T> struct W { - W Woo(); - ... - }; - %template(Wint) W<int>; - - The above also introduces a possibly unexpected change. Many of the STL containers - provided by SWIG use %rename to rename some methods, eg in std::vector, push_back - is renamed to add in Java. Previously this intended rename did not happen when using - using global %rename rules and the method would remain as push_back, but is now - renamed to add. Some more info in issue #856. - - *** POTENTIAL INCOMPATIBILITY *** - -2016-11-26: m7thon - [Python] Issue #709 - improved wrapping of division operators - 'from __future__ import division' now works in Python 2 whether or not the - -py3 flag is used. - -2016-11-12: joequant - [R] Issue #697 - fix comma issue with overload methods - -2016-11-12: joequant - [R] Issue #555 - R runtime needs stdio.h - -2016-11-02: wsfulton - [Python] Issue #816 - fix compilation error when using -extranative and -builtin. - -2016-11-02: liorgold - Patch #741 - Add support for C++11 alias templates, see updated CPlusPlus11.html - documentation. - -2016-10-30: myd7349 - [C#] Patch #740 Add std_array.i for C# for wrapping std::array. - - Patch also enhances std::vector<std::wstring> C# wrappers with additional functions - (Contains, IndexOf, LastIndexOf and Remove). - -2016-10-30: tobilau - [Java] Fix wrappers for wstring parameters in director methods to cleanup local - ref after director callback has finished. - -2016-10-23: wsfulton - [C#] Add missing csdirectorin VOID_INT_PTR and csdirectorout VOID_INT_PTR typemaps. - -2016-10-23: jiulongw - Patch #781 - Fix wrapping of C compound expressions containing char constants - in quotes such as: - - #define H_SUPPRESS_SCALING_MAGIC (('s'<<24) | ('u'<<16) | ('p'<<8) | 'p') - - enum DifferentTypes { - typecharcompound='A'+1, - typecharcompound2='B' << 2 - }; - -2016-10-13: wsfulton - [Python] Issue #808 - fix Python pickling and metaclass for builtin wrappers. - - The metaclass (SwigPyObjectType) for SWIG objects was not defined in - a way that let importlib successfully import the Python wrappers. - The pickle module previously failed to pickle objects because it couldn't - determine what module the SWIG wrapped objects were in. - -2016-09-29: wsfulton - [Allegrocl, CFFI, GO, Javascript, Ocaml, R, Scilab] - Add missing support for the "ret" typemap in a few target languages. - The documentation also now has info on the "ret" typemap. - -2016-09-27: ahmed-usman - [xml] Handle template parameters correctly. - -2016-09-27: dontpanic92 - [Go] Fix argument names in inherited functions taking more than 8 - parameters. Fixes #795. - -2016-09-26: smarchetto - [Scilab] mlists that map pointers can be given a custom type name. - -2016-09-25: wsfulton - Patch #793 from q-p to expand exception handling to include std::bad_cast - in std_except.i. - -2016-09-24: olly - [PHP] Fix code generated for feature("director:except") - - previously the return value of call_user_function() was ignored and - we checked an uninitialised value instead. Fixes #627. Based on - patch from Sergey Seroshtan. - -2016-09-22: wsfulton - [Python] More flexible python builtin slots for overloaded C++ function. - - The closure names used for builtin slots are mangled with their functype so - that overloaded C++ method names can be used for multiple slots. - For example: - - %feature("python:slot", "mp_subscript", functype="binaryfunc") SimpleArray::__getitem__; - %feature("python:slot", "sq_item", functype="ssizeargfunc") SimpleArray::__getitem__(Py_ssize_t n); - - will generate closures: - - SWIGPY_SSIZEARGFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___ssizeargfunc_closure */ - SWIGPY_BINARYFUNC_CLOSURE(_wrap_SimpleArray___getitem__) /* defines _wrap_SimpleArray___getitem___binaryfunc_closure */ - - Previously only one name was defined: _wrap_SimpleArray___getitem___closure. - Hence the overloaded __getitem__ method can be used to support both mp_subscript and sq_item slots. - -2016-09-17: wsfulton - [Python] Fix iterators for containers of NULL pointers (or Python None) when using - -builtin. Previously iteration would stop at the first element that was NULL. - -2016-09-16: olly - [Javascript] Fix SWIG_exception() macro to return from the current - function. Fixes #789, reported by Julien Dutriaux. - -2016-09-16: olly - [PHP] Fix SWIG_exception() macro to return from the current function. - Fixes #240, reported by Sergey Seroshtan. - -2016-09-12: xypron - [C#] Patch #786 Keyword rename to be CLS compliant by adding an underscore - suffix instead of an underscore prefix to the C symbol name. Please use an explicit - %rename to rename the symbol with a _ prefix if you want the old symbol name. - - *** POTENTIAL INCOMPATIBILITY *** - -2016-09-09: olly - [Python] Fix import handling for Python 2.6 to work in a frozen - application. Fixes #145, reported by Thomas Kluyver. - -2016-09-02: smarchetto - [Scilab] Pointers are mapped to mlist instead of tlist - (mlist better for scilab overloading) - -2016-09-02: olly - [PHP] Fix "out" typemap for member function pointers and "in" - typemap for char INPUT[ANY]. - -2016-09-01: wsfulton - [Python] More efficient Python slicing. - Call reserve for container types that support it to avoid repeated - memory reallocations for new slices or slices that grow in size. - -2016-09-01: wsfulton - [Python] #771 - Make builtin types hashable by default. - Default hash is the underlying C/C++ pointer. This matches up with testing for - equivalence (Py_EQ in SwigPyObject_richcompare) which compares the pointers. - -2016-08-22: wsfulton - [Python] The following builtin slots can be customized like other slots via the - "python:<x>" and "python:slot" features where <x> is the appropriate slot name: - tp_allocs - tp_bases - tp_basicsize - tp_cache - tp_del - tp_dealloc - tp_flags - tp_frees - tp_getset - tp_is_gc - tp_maxalloc - tp_methods - tp_mro - tp_new - tp_next - tp_prev - tp_richcompare - tp_subclasses - tp_weaklist - was_sq_ass_slice - was_sq_slice - - A few documentation improvements for slot customization. - -2016-08-09: joequant - [R] Patch #765 Fix extern "C" header includes for C++ code. - -2016-08-05: olly - [xml] Fix how the output filename is built to avoid problems when - it contains the embedded strings ".c", ".cpp" or ".cxx". - Fixes #540 reported by djack42. - -2016-07-01: wsfulton - Fix corner case of wrapping std::vector of T pointers where a pointer to a pointer of T - also exists in the wrapped code. SF Bug 2359417 (967). - -2016-06-26: wkalinin - [Java, C#] Patch #681 Fix seg fault when ignoring nested classes. - -2016-06-25: mromberg - [Python] #711 Fix -castmode and conversion of signed and unsigned integer types. - See 2015-12-23 CHANGES entry for details of these improvements when they were - implemented for the default options (ie not using -castmode). - -2016-06-25: ahnolds - Patch #730 - Fix %implicitconv for overloaded functions when using - -castmode or -fastdispatch options. - - The result is that in all overload cases where there are multiple possibilities - with the same number of arguments, the dispatch function will first check for - exact (aka non implicit) matches, and then subsequently check for implicit - casting matches. This was already happening in the normal dispatch situation, - and in the -fastdispatch case two passes through the candidates were happening, - just with SWIG_POINTER_IMPLICIT_CONV always set. After this patch, it is not set - on the first pass, and then set on the second pass. - -2016-06-25: liorgold - Patch #727 - Add support for C++11 type aliasing. - -Version 3.0.10 (12 Jun 2016) -============================ - -2016-06-06: mromberg - [Python] Patch #698. Add support for -relativeimport for python 2.7, so -py3 is no - longer also required for relative import support. - -2016-06-05: mromberg - [Python] Patch #694 - Fix package import regressions introduced in swig-3.0.9. - - 1) The code in 3.0.9 did not fall back to 'import _foo' if 'import bar._foo' failed - (assuming bar.foo was the main module). Every place _foo is imported now first tries - it from the package where foo was found and if that fails tries _foo as a global module. - - 2) The separate block of Python code that injected code to pull in the attributes - from _foo when -builtin is used made use of the -py3 switch to either do - 'from ._foo import *' or "from _foo import *". This block of code no longer does this - and instead checks the Python version at runtime to switch between the two syntaxes. - - In summary, swig-3.0.10 has been modified to ease the creation of wrapper modules - that can be fully made part of a Python package. SWIG no longer - assumes the dynamically linked C module is a global module. - The dynamic module can now be placed into either the same package as the pure Python - module or as a global module. Both locations are used by the Python wrapper to - locate the C module. - - However, this could cause a backwards incompatibility with some code - that was relying on the ability of "from package import _module" to - pull attributes out of the package directly. If your code populates a - module (which is also a package) with attributes that are SWIG - generated modules which were not loaded in a conventional way, - swig-3.0.8 and earlier may have worked due to 'from package import - _module' bypassing a real import and pulling your module in as an - attribute. This will no longer work. Since this is not a common (or - even recommended) practice, most folk should not be affected. - - *** POTENTIAL INCOMPATIBILITY *** - -2016-05-31: wsfulton - Fix #690 - Smart pointer to %ignored class doesn't expose inherited methods. - Regression introduced in swig-3.0.9. - -Version 3.0.9 (29 May 2016) -=========================== - -2016-05-24: mromberg - [Python] Patch #612 - Add support for Python's implicit namespace packages. - -2016-05-23: wsfulton - [Ruby] Fix #602 - Error handling regression of opaque pointers introduced - in swig-3.0.8 when C functions explicitly reset a pointer using 'DATA_PTR(self) = 0'. - An ObjectPreviouslyDeleted error was incorrectly thrown when the pointer was used - as a parameter. - -2016-05-17: tamuratak - [Ruby] Patch #651 - Correct overloaded function error message when function is - using %newobject. - -2016-05-17: aurelj - [Ruby] Patch #582 - add support for docstring option in %module() - -2016-05-14: wsfulton - Fix #434 - Passing classes by value as parameters in director methods did not create - a copy of the argument leading to invalid memory accesses if the object was used - after the upcall into the target language. Passing arguments by value shouldn't give - rise to these sorts of memory problems and so the objects are now copied and ownership - of their lifetime is controlled by the target language. - -2016-05-07: wsfulton - Fix #611. Fix assertion handling defaultargs when using %extend for a template - class and the extended methods contain default arguments. - -2016-05-05: ejulian - [Python] Patch #617. Fix operator/ wrappers. - -2016-05-02: wsfulton - Fix #669. Don't issue warning about ignoring base classes when the derived class is - itself ignored. - -2016-04-18: ianlancetaylor - [Go] Fix use of goout typemap when calling base method by - forcing the "type" attribute to the value we need. - -2016-04-17: ianlancetaylor - [Go] Fixes for Go 1.6: avoid returning Go pointers from - directors that return string values; add a trailing 0 byte - when treating Go string as C char*. - -2016-04-06: smarchetto - [Scilab] #552 Make Scilab runtime keep track of pointer types - Instead of a Scilab pointer which has no type, SWIG Scilab maps a - pointer to a structure tlist containing the pointer adress and its type. - -2016-04-02: ahnolds - [Python] Apply #598. Fix misleading error message when attempting to read a non-existent - attribute. The previous cryptic error message: - AttributeError: type object 'object' has no attribute '__getattr__' - is now replaced with one mentioning the attribute name, eg: - AttributeError: 'Foo' object has no attribute 'bar' - -2016-04-02: derkuci - [Python] Patch #610 to fix #607. - Fix single arguments when using python -builtin -O with %feature("compactdefaultargs") - -2016-03-31: wsfulton - Fixes #594. Fix assertion for some languages when wrapping a C++11 enum class that - is private in a class. - - Also don't wrap private enums for a few languages that attempted to do so. - -2016-03-31: wsfulton - [Java] unsigned long long marshalling improvements when a negative number - is passed from Java to C. A cast to signed long long in the C layer will now - result in the expected value. No change for positive numbers passed to C. - Fixes #623. - -2016-03-22: alexwarg - [Lua] #398 Fix lua __getitem + inheritance - The new handling of classes in Lua (not merging methods into the derived classes) - breaks for classes that provide a __getitem function. The __getitem function - prevents method calls to any method defined in a base class. This fix calls - __getitem only if the member is not found using recursive lookup. - -2016-03-18: ptomulik - [Python] #563 Stop generating unnecessary _swigconstant helpers. - -2016-03-16: richardbeare - [R] #636 Add extra std::vector numeric types - -2016-03-14: wsfulton - [Java] Add std_array.i for C++11 std::array support. - -2016-03-12: wsfulton - [Java, C#, D] Fix static const char member variables wrappers with %javaconst(1) - %csconst(1) or %dmanifestconst. - This fixes the case when an integer is used as the initializer, such as: - - struct W { static const char w = 100; }; - - Fix generated code parsing enum values using char escape sequences - when these values appear in the Java code (usually when using %javaconst(1)) - such as: - - enum X { x1 = '\n', x2 = '\1' }; - - Similarly for static const member char variables such as: - - struct Y { static const char y = '\n'; } - - Likewise for D and %dmanifestconstant. For C# and %csconst(1), char - values in C# are now hex escaped as C# doesn't support C octal escaping. - -2016-03-11: wsfulton - [Java C#] Add support for treating C++ base classes as Java interfaces - instead of Java proxy classes. This enable some sort of support for - multiple inheritance. The implementation is in swiginterface.i and - provides additional macros (see Java.html for full documentation): - - %interface(CTYPE) - %interface_impl(CTYPE) - %interface_custom("PROXY", "INTERFACE", CTYPE) - -2016-03-01: wsfulton - Add rstrip encoder for use in %rename. This is like the strip encoder but - strips the symbol's suffix instead of the prefix. The example below - will rename SomeThingCls to SomeThing and AnotherThingCls to AnotherThing: - - %rename("%(rstrip:[Cls])s") ""; - - class SomeThingCls {}; - struct AnotherThingCls {}; - -2016-03-01: olly - Fix isfinite() check to work with GCC6. Fixes - issue #615 reported by jplesnik. - -2016-02-17: olly - [Python] Add missing keywords 'as' and 'with' to pythonkw.swg. - -2016-02-07: kwwette - [Octave] recognise various unary functions - * Use __float__() for numeric conversions, e.g. when calling double() - * Map various unary functions, e.g. abs() to __abs__(), see full list - in section 32.3.10 of manual; only available in Octave 3.8.0 or later - -2016-02-07: kwwette - [Octave] export function swig_octave_prereq() for testing Octave version - -2016-02-06: pjohangustavsson - [C#] Fix duplicate symbol problems when linking the source generated - from multiple SWIG modules into one shared library for the -namespace - option. The namespace is now mangled into the global PInvoke function - names. - - *** POTENTIAL INCOMPATIBILITY *** - -2016-01-27: ahnolds - [Python] Added support for differentiating between Python Bytes - and Unicode objects using by defining SWIG_PYTHON_STRICT_BYTE_CHAR - and SWIG_PYTHON_STRICT_UNICODE_WCHAR. - -2016-01-27: steeve - [Go] Ensure structs are properly packed between gc and GCC/clang. - -2016-01-25: ahnolds - [Python] Support the full Python test suite in -classic mode - * Convert long/unsigned long/long long/unsigned long long to PyInt - rather than PyLong when possible. Certain python functions like - len() require a PyInt when operating on old-style classes. - * Add support for static methods in classic mode, including support - for pythonappend, pythonprepend, and docstrings. - * Removing the use of __swig_getmethods__ for static member methods - since they will always be found by the standard argument lookup - * Fix a bug where the wrong type of exception was caught when - checking for new-style class support - -2016-01-23: ahnolds - [Go] Enable support for the Go test-suite on OSX: - * The linker on OSX requires that all symbols (even weak symbols) - are defined at link time. Because the function _cgo_topofstack is - only defined starting in Go version 1.4, we explicitly mark it as - undefined for older versions of Go on OSX. - * Avoid writing empty swigargs structs, since empty structs are not - allowed in extern "C" blocks. - -2016-01-12: olly - [Javascript] Look for "nodejs" as well as "node", as it's packaged - as the former on Debian. - -2016-01-12: olly - [Javascript] For v8 >= 4.3.0, use V8_MAJOR_VERSION. - Fixes issue 561. - -2016-01-10: ahnolds - Improved size_t and ptrdiff_t typemaps to support large values - on platforms where sizeof(size_t) > sizeof(unsigned long) and - sizeof(ptrdiff_t) > sizeof(long). - -Version 3.0.8 (31 Dec 2015) -=========================== - -2015-12-30: wsfulton - The pdf documentation is now generated by wkhtmltopdf and has colour - for the code snippets just like the html documentation! - -2015-12-23: ahnolds - [Python] Fixes for conversion of signed and unsigned integer types: - - No longer check for PyInt objects in Python3. Because PyInt_Check - and friends are #defined to the corresponding PyLong methods, this - had caused errors in Python3 where values greater than what could be - stored in a long were incorrectly interpreted as the value -1 with - the Python error indicator set to OverflowError. This applies to - both the conversions PyLong->long and PyLong->double. - - Conversion from PyLong to long, unsigned long, long long, and - unsigned long long now raise OverflowError instead of TypeError in - both Python2 and Python3 for PyLong values outside the range - expressible by the corresponding C type. This matches the existing - behavior for other integral types (signed and unsigned ints, shorts, - and chars), as well as the conversion for PyInt to all numeric - types. This also indirectly applies to the size_t and ptrdiff_t - types, which depend on the conversions for unsigned long and long. - -2015-12-19: wsfulton - [Python] Python 2 Unicode UTF-8 strings can be used as inputs to char * or - std::string types if the generated C/C++ code has SWIG_PYTHON_2_UNICODE defined. - -2015-12-17: wsfulton - Issues #286, #128 - Remove ccache-swig.1 man page - please use the CCache.html docs instead. - The yodl2man and yodl2html tools are no longer used and so SWIG no - longer has a dependency on these packages which were required when - building from git. - -2015-12-16: zturner/coleb - [Python] Fix Python3.5 interpreter assertions when objects are being - deleted due to an existing exception. Most notably in generators - which terminate using a StopIteration exception. Fixes #559 #560 #573. - If a further exception is raised during an object destruction, - PyErr_WriteUnraisable is used on this second exception and the - original exception bubbles through. - -2015-12-14: ahnolds/wsfulton - [Python] Add in missing initializers for tp_finalize, - nb_matrix_multiply, nb_inplace_matrix_multiply, ht_qualname - ht_cached_keys and tp_prev. - -2015-12-12: wsfulton - Fix STL wrappers to not generate <: digraphs. - For example std::vector<::X::Y> was sometimes generated, now - corrected to std::vector< ::X::Y >. - -2015-11-25: wsfulton - [Ruby] STL ranges and slices fixes. - - Ruby STL container setting slices fixes: - - Setting an STL container wrapper slice better matches the way Ruby - arrays work. The behaviour is now the same as Ruby arrays. The only - exception is the default value used when expanding a container - cannot be nil as this is not a valid type/value for C++ container - elements. - - Obtaining a Ruby STL container ranges and slices fixes: - - Access via ranges and slices now behave identically to Ruby arrays. - The fixes are mostly for out of range indices and lengths. - - Zero length slice requests return an empty container instead of nil. - - Slices which request a length greater than the size of the container - no longer chop off the last element. - - Ranges which used to return nil now return an empty array when the - the start element is a valid index. - - Ruby STL container negative indexing support improved. - - Using negative indexes to set values works the same as Ruby arrays, eg - - %template(IntVector) std::vector<int>; - - iv = IntVector.new([1,2,3,4]) - iv[-4] = 9 # => [1,2,3,9] - iv[-5] = 9 # => IndexError - -2015-11-21: wsfulton - [Ruby, Python] Add std::array container wrappers. - - These work much like any of the other STL containers except Python/Ruby slicing - is somewhat limited because the array is a fixed size. Only slices of - the full size are supported. - -2015-10-10: wsfulton - [Python] #539 - Support Python 3.5 and -builtin. PyAsyncMethods is a new - member in PyHeapTypeObject. - -2015-10-06: ianlancetaylor - [Go] Don't emit a constructor function for a director - class with an abstract method, since the function will - always panic. - -2015-10-01: wsfulton - Fix %shared_ptr support for private and protected inheritance. - - Remove unnecessary Warning 520: Derived class 'Derived' of 'Base' - is not similarly marked as a smart pointer - - Do not generate code that attempts to cast up the inheritance chain in the - type system runtime in such cases as it doesn't compile and can't be used. - Remove unnecessary warning 520 for %shared_ptr when the base class is ignored. - -2015-10-01: vkalinin - Fix #508: Fix segfault parsing anonymous typedef nested classes. - -2015-09-26: wsfulton - [Ruby] Add shared_ptr support - -2015-09-13: kkaempf - [Ruby] Resolve tracking bug - issue #225. - The bug is that the tracking code uses a ruby hash and thus may - allocate objects (Bignum) while running the GC. This was tolerated in - 1.8 but is invalid (raises an exception) in 1.9. - The patch uses a C hash (also used by ruby) instead. - -2015-09-09: lyze - [CFFI] Extend the "export" feature in the CFFI module to support - exporting to a specified package. - -2015-09-04: olly - [Python] Fix docstrings for %callback functions. - -2015-09-03: demi-rluddy - [Go] Removed golang stringing for signed/unsigned char - - Changed default handling of signed char* and unsigned char* to be - opaque pointers rather than strings, similarly to how other - languages work. - - Any existing code relying on treating signed char* or unsigned - char* as a string can restore the old behavior with typemaps.i by - using %apply to copy the [unchanged] char* behavior. - - *** POTENTIAL INCOMPATIBILITY *** - -2015-08-07: talby - [Perl] tidy -Wtautological-constant-out-of-range-compare warnings when building generated code under clang - -2015-08-07: xantares - [Python] pep257 & numpydoc conforming docstrings: - - Mono-line module docsstring - - Rewrite autodoc parameters section in numpydoc style: - https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt - - One line summary should end with "." - - Adds a blank line after class docstring - -2015-08-05: vadz - [Java] Make (char* STRING, size_t LENGTH) typemaps usable for - strings of other types, e.g. "unsigned char*". - -Version 3.0.7 (3 Aug 2015) -========================== - -2015-08-02: wsfulton - [Java] Fix potential security exploit in generated Java classes. - The swigCPtr and swigCMemOwn member variables in the generated Java - classes are now declared 'transient' by default. Further details of the exploit - in Android is being published in an academic paper as part of USENIX WOOT '15: - https://www.usenix.org/conference/woot15/workshop-program/presentation/peles. - - In the unlikely event that you are relying on these members being serializable, - then you will need to override the default javabody and javabody_derived typemaps - to generate the old generated code. The relevant typemaps are in the Lib directory - in the java.swg, boost_shared_ptr.i and boost_intrusive_ptr.i files. Copy the - relevant default typemaps into your interface file and remove the 'transient' keyword. - - *** POTENTIAL INCOMPATIBILITY *** - -2015-08-01: vadz - Make configure --without-alllang option more useful: it can now be overridden by the following - --with-xxx options, allowing to easily enable just one or two languages. - -2015-07-30: wsfulton - Fix #440 - Initialise all newly created arrays when using %array_functions and %array_class - in the carrays.i library - bug is only relevant when using C++. - -2015-07-29: wsfulton - [Python] Improve indentation warning and error messages for code in the following directives: - - %pythonprepend - %pythonappend - %pythoncode - %pythonbegin - %feature("shadow") - - Old error example: - Error: Line indented less than expected (line 3 of pythoncode) - - New error example: - Error: Line indented less than expected (line 3 of %pythoncode or %insert("python") block) - as no line should be indented less than the indentation in line 1 - - Old warning example: - Warning 740: Whitespace prefix doesn't match (line 2 of %pythoncode or %insert("python") block) - - New warning example: - Warning 740: Whitespace indentation is inconsistent compared to earlier lines (line 3 of - %pythoncode or %insert("python") block) - - -2015-07-28: wsfulton - [Python] Fix #475. Improve docstring indentation handling. - - SWIG-3.0.5 and earlier sometimes truncated text provided in the docstring feature. - This occurred when the indentation (whitespace) in the docstring was less in the - second or later lines when compared to the first line. - SWIG-3.0.6 gave a 'Line indented less than expected' error instead of truncating - the docstring text. - Now the indentation for the 'docstring' feature is smarter and is appropriately - adjusted so that no truncation occurs. - -2015-07-22: wsfulton - Support for special variable expansion in typemap attributes. Example usage expansion - in the 'out' attribute (C# specific): - - %typemap(ctype, out="$*1_ltype") unsigned int& "$*1_ltype" - - is equivalent to the following as $*1_ltype expands to 'unsigned int': - - %typemap(ctype, out="unsigned int") unsigned int& "unsigned int" - - Special variables can be used within special variable macros too. Example usage expansion: - - %typemap(cstype) unsigned int "uint" - %typemap(cstype, out="$typemap(cstype, $*1_ltype)") unsigned int& "$typemap(cstype, $*1_ltype)" - - Special variables are expanded first and hence the above is equivalent to: - - %typemap(cstype, out="$typemap(cstype, unsigned int)") unsigned int& "$typemap(cstype, unsigned int)" - - which then expands to: - - %typemap(cstype, out="uint") unsigned int& "uint" - -2015-07-22: lindleyf - Apply patch #439 - support for $typemap() (aka embedded typemaps or special variable - macros) in typemap attributes. A simple example where $typemap() is expanded in the - 'out' attribute (C# specific): - - %typemap(cstype) unsigned int "uint" - %typemap(cstype, out="$typemap(cstype, unsigned int)") unsigned int& "$typemap(cstype, unsigned int)" - - is equivalent to: - - %typemap(cstype, out="uint") unsigned int& "uint" - -2015-07-18: m7thon - [Python] Docstrings provided via %feature("docstring") are now quoted and added to - the tp_doc slot when using python builtin classes (-builtin). When no docstring is - provided, the tp_doc slot is set to the fully qualified C/C++ class name. - Github issues #445 and #461. - -2015-07-17: kwwette - [octave] Support Octave version 4.0.0 (thanks to patches from Orion Poplawski). - -2015-07-07: wsfulton - SWIG no longer generates a wrapper for a class' constructor if that class has - any base class with a private destructor. This is because your compiler should - not allow a class to be instantiated if a base has a private destructor. Some - compilers do, so if you need the old behaviour, use the "notabstract" feature, eg: - - %feature("notabstract") Derived; - class Base { - ~Base() {} - }; - struct Derived : Base {}; - -Version 3.0.6 (5 Jul 2015) -========================== - -2015-07-02: wsfulton - Fix syntax error when the template keyword is used in types, eg: - - std::template vector<int> v; - -2015-07-02: ngladitz - [Lua] Push characters as unformatted 1-character strings to avoid - unprintable characters such as (char)127 being converted to - "<\127>" with Lua 5.3 and later. (github PR #452) - -2015-06-29: olly - [Python] Improve handling of whitespace in %pythoncode. - - Previously SWIG looked at the indentation of the first line and - removed that many characters from each subsequent line, regardless - of what those characters were. This was made worse because SWIG's - preprocessor removes any whitespace before a '#'. Fixes github - issue #379, reported by Joe Orton. - -2015-06-12: wsfulton - [R] Fix #430 - call to SWIG_createNewRef in copyToC was incorrectly named. - -2015-06-11: sghirate - [C#] Patch #427 adds in new command line option -outfile to combine all the - generated C# code into a single file. - -2015-06-09: wsfulton - Fix seg fault processing C++11 type aliasing. Issue #424. - -2015-05-28: wsfulton - [Python] Add new feature "python:cdefaultargs" to control default argument - code generation. By default, SWIG attempts to convert C/C++ default argument values - into Python values and generates code into the Python layer with these values. - Recent versions of SWIG are able to convert more of these values, however, the - new behaviour can be circumvented if desired via this new feature, such that - the default argument values are obtained from the C layer and not the Python layer. - For example: - - struct CDA { - int fff(int a = 1, bool b = false); - }; - - The default code generation in the Python layer is: - - class CDA(_object): - ... - def fff(self, a=1, b=False): - return _default_args.CDA_fff(self, a, b) - - Adding the feature: - - %feature("python:cdefaultargs") CDA::fff; - - Results in: - - class CDA(_object): - ... - def fff(self, *args): - return _default_args.CDA_fff(self, *args) - - Some code generation modes, eg -builtin and -fastproxy, are unaffected by this as - the default values are always obtained from the C layer. - -2015-05-27: wsfulton - [Python] Deal with an integer as the default value of a typedef to bool - parameter in the C++ prototype. See #327. Regression from 3.0.0 onwards. - -2015-05-19: olly - [Python] Fix warning when compiling generated code with MSVC. - (Fixes https://sourceforge.net/p/swig/patches/351/ reported by - Mateusz Szyma¿ski). - -2015-05-14: wsfulton - Fix seg fault wrapping shared_ptr of classes with private constructors and destructors. - This also fixes the "unref" feature when used on classes with private destructors. - -2015-05-10: wsfulton - [Java] Fix multi-argument typemaps (char *STRING, size_t LENGTH) - so that they can be applied to a wider range of types. Fixes #385. - -2015-05-07: olly - [Python] Deal with an integer as the default value of a bool - parameter in the C++ prototype. Fixes github #327, reported by - Greg Allen. - -2015-05-07: LindleyF - [Java] Allow feature("director") and feature("ref") to be used - together. Github PR#403. - -2015-05-05: olly - Suppress warning 325 "Nested class not currently supported (Foo - ignored)" when Foo has already been explicitly ignored with "%ignore". - -2015-05-04: wsfulton - Add support for friend templates, including operator overloading - fixes #196. Considering - the example below, previously the operator gave a syntax error and friendfunc incorrectly - warned with: - - "Warning 503: Can't wrap 'friendfunc<(Type)>' unless renamed to a valid identifier." - - template <class Type> class MyClass { - friend int friendfunc <Type>(double is, MyClass <Type> & x); - friend int operator<< <Type>(double un, const MyClass <Type> &x); - }; - - The following also previously incorrectly warned with: - - "Warning 302: Identifier 'template_friend' redefined (ignored)," - - template<typename T> T template_friend(T); - struct MyTemplate { - template<typename T> friend T template_friend(T); - }; - -2015-05-01: wsfulton - Fix handling of conversion operators where the operator is split over multiple - lines or has comments within the operator type. Fixes #401. - - Also fix similar problem with normal operators which gave a syntax error if split over - multiple lines or had a comment within the operator declaration. - -2015-04-30: olly - Ignore unknown preprocessor directives which are inside an inactive - conditional (github issue #394, reported by Dan Wilcox). - Regression introduced in 3.0.3. - -2015-04-27: vadz - [Python] Fix "default" typemap used after an argument with "numinputs=0" (#377). - -2015-04-24: wsfulton - [Python] Fix #256. Code generated with '-builtin -modernargs' segfaults for any - method taking zero arguments. - - Also fixes: "SystemError: error return without exception set" during error checking - when using just -builtin and the incorrect number of arguments is passed to a class - method expecting zero arguments. - -2015-04-23: wsfulton - [Java] Bug #386 - Memory leak fix in (char *STRING, size_t LENGTH) typemaps. - -2015-04-23: vadz - [Python] Make "default" typemap work again (#330, #377). - -2015-04-23: vadz - [Python] Fix the use of default values for the pointer types (#365, #376). - -2015-04-23: wsfulton - Fix 'make check-ccache' which is part of 'make check' when one of the CCACHE_ - environment variables, for example CCACHE_DISABLE, is set. - -2015-04-14: wsfulton - Clearer warning message for badly constructed typecheck typemaps. For example, was: - - example.i:3: Warning 467: Overloaded foo(int) not supported (no type checking - rule for 'int'). - - Now: - - example.i:3: Warning 467: Overloaded foo(int) not supported (incomplete type checking - rule - no precedence level in typecheck typemap for 'int'). - -2015-04-11: wsfulton - [Java] Fix #353 - Linker multiple definition of 'ExceptionMatches' when - using directors and multiple modules. - -2015-04-11: wsfulton - Merge #320 - Make __dict__ accessible for Python builtin classes. - -2015-04-07: wsfulton - Fix #375 - parsing of extern "C" and typedef for example: - extern "C" typedef void (*Hook2_t)(int, const char *); - extern "C" typedef int Integer; - -2015-03-12: olly - -DSWIG_DIRECTOR_STATIC is now supported for all languages with - director support, not only Python and PHP. - -2015-03-02: ianlancetaylor - [Go] Add -cgo option, required for Go versions 1.5 and - later. - -2015-02-26: olly - Fix segmentation fault when top==NULL, introduced by nested class - handling (reported in issue#346 by Pawe¿ Tomulik). - -2015-02-09: wsfulton - [Guile] Fix generated code for static const char member variables when - defined and declared inline. - -2015-02-09: mishas - [Go] Fix %import of files in sub directories. - -2015-02-05: ianlancetaylor - [Go] Ignore Go specific type maps (goin, goout, etc.) if they are empty. - -2015-02-05: ianlancetaylor - [Go] Generated Go code no longer calls _swig_goallocate or - _swig_makegostring, as they will no longer work as of Go 1.5. - -Version 3.0.5 (31 Jan 2015) -=========================== - -2015-01-30: wsfulton - [Python] Fix Python -classic and property setting. Setting properties on classic classes - was broken in swig-3.0.3 by attempting to use __setattr__. This regression is fixed now - by using __dict__ again when using -classic. - Fixes patch #232. - -2015-01-27: smarchetto - [Scilab] Support for the Scilab language has been added - -2015-01-23: olly - [PHP] When wrapping a returned resource as an object, check if all - cases wrap it in the same class, and if so eliminate the pointless - switch statement wrapper we previously generated. - -2015-01-22: wsfulton - [Octave] Merge patch #297 for SF bug #1277 - Octave shared_ptr support - -2015-01-15: wsfulton - [Python] Merge patch #250 - Fixes for using %constant and objects (non-primitive types) - -2015-01-15: wsfulton - [C# Go] Merge patch #308 and fix #307 - C++11 strongly typed enum support - in directors - -2015-01-15: wsfulton - [Python] Second fix for #294 #296 - Regression introduced in SWIG-3.0.3 when - wrapping functions with default arguments, this time when using kwargs. - -Version 3.0.4 (14 Jan 2015) -=========================== - -2015-01-12: olly - [PHP] Fix segfault in director upcall check when using PHP built with - ZTS enabled. Fixes #155, reported by Pierre Labastie. - -2015-01-12: vadz - [Python] Fix #294 #296 - Regression introduced in SWIG-3.0.3 when - wrapping functions with default arguments. Invalid or missing default - arguments were sometimes being generated into the python layer. - -2015-01-08: olly - Allow C++11 "explicit constexpr". Fixes github issue #284 reported - by Pawel Tomulik. Also handle "constexpr explicit" and "constexpr - static". - -2015-01-08: olly - When reporting an error for a construct which hasn't been - terminated when the end of the file is reached, report it at the - start line rather than "EOF" as then tools like editors and IDEs - will take you to a generally more useful place for fixing the - problem. - -2015-01-08: olly - Improve error messages for a few cases which previously gave the - one of the cryptic catch-all errors "Syntax error in input". - -2015-01-08: olly - Provide -cppext as a general command line option for setting the - extension used for generated C++ files (previously it was specific - to the PHP backend). Deprecate the equivalent -suffix option - provided by the Ocaml backend, but continue to support that for - now. - -Version 3.0.3 (30 Dec 2014) -=========================== - -2014-12-27: wsfulton - Fix #280 - abort using all default template parameters within other template - parameters. - -2014-12-27: talby - [Perl] Issue #282 perl5 archlib vs archlibexp - [Perl] tidy "warning: duplicate 'extern' declaration specifier" when building generated code - under clang - -2014-12-18: wsfulton - Add support for %constant and structs/classes - issue #272 - -2014-12-09: wsfulton - Fix #245 - regression (since swig-3.0.0) in templated constructors. - Templated constructors could not be instantiated - they were incorrectly ignored with a warning 504: - "Function: xyz must have a return type. Ignored." - -2014-12-07: wsfulton - Add support for C++11 strongly typed enumerations. - -2014-11-21: wsfulton - [Java C#] Fix multiply defined error when using %rename of enum items when using the "simple enum" - wrappers. - -2014-10-28: vadz - [Python] Patch #201 The generated .py file no longer uses *args for all Python parameters. - Instead, the parameters are named using the C++ parameter names. - - "compactdefaultargs" feature can be enabled to restore the old behaviour. - - *** POTENTIAL INCOMPATIBILITY *** - -2014-10-24: timotheecour - [D] Patch #204 Use core.atomic.atomicOp to mutate shared variables - -2014-10-21: wsfulton - Fix issue #242 - Use of the "kwargs" feature no longer automatically turns on the - "compactdefaultargs" feature if the target language does not support kwargs. - This change affects all languages except Python and Ruby. - - *** POTENTIAL INCOMPATIBILITY *** - -2014-10-10: diorcety - [Python] Patch #232 Fix property access using directors - -2014-10-06: wsfulton - [Python] Fixes when using -builtin and std::vector/std::list wrappers to allow deletion - of single elements, such as 'del vec[0]'. - -2014-09-30: oliverb - [Javascript] Merge patch #216 by Richie765 - Added support for many versions of v8 javascript. - -2014-09-30: oliverb - [Javascript] Merge patch #195 by zittix - Fixed JSClassRef declaration not using the static one. - -2014-09-30: ianlancetaylor - [Go] In configure script, require Go 1.1 or later. - -2014-09-30: wsfulton - [Python] Patch #207 - Fix No module error with -relativeimport when using single - header file import. - -2014-09-27: wsfulton - Patch #208 - Initialise newly created array when using array_functions in the - carrays.i library (C++ usage). - -2014-09-27: wsfulton - [Ruby] Patch #187 - Fix crash on shutdown of the Ruby interpreter if more than one - module was loaded at a time when data is being shared between modules. - -2014-09-27: wsfulton - [Java] Patch #168 - Fix leak in Java director string handling after the Java - upcall when called from a native thread. - -2014-09-25: ianlancetaylor - [Go] Adjust generated code to work with upcoming Go 1.4 - release. - -2014-09-23: wsfulton - [Python] Add patch from Thomas Maslach to fix crash in wrappers when using -threads in - the STL iterators (SwigPyIterator destructor). - -2014-09-17: wsfulton - [C#] Merge patch #229 from contre - Add bool array types to arrays_csharp.i - -2014-09-12: olly - [PHP] Add support for specifying any PHP interfaces a wrapped class - implements, e.g.: %typemap("phpinterfaces") MyIterator "Iterator" - -2014-09-11: olly - [PHP] Fix throwing a PHP exception through C++ from a subclassed - director method - PHP NULL gets returned by the subclassed method - in this case, so the directorout typemap needs to allow that (at - least if an exception is active). - -2014-09-09: ianlancetaylor - [Go] Add goargout typemap. - -2014-09-09: olly - [PHP] Fix segmentation faults with directors in PHP >= 5.4, and - reenable runme tests for director_basic testcase. Fix from - pavel-charvat in issue#164. - -2014-09-05: ianlancetaylor - [Go] Add imtype, goin, goout, godirectorin, and - godirectorout typemaps, to support writing Go code to - convert between types. - -2014-09-02: olly - [Python] Fix regression in indentation of python code produced with - -modern, introduced by changes in #188. Reported by fabiencastan - in #218. - -2014-09-01: olly - Issue an error for unknown SWIG preprocessor directives, rather - than quietly ignoring them. Reported by jrhelsey in issue#217. - - *** POTENTIAL INCOMPATIBILITY *** - -2014-08-15: talby - [Perl] Include guard fix for nested modules from Anthony Heading (SF Patch #350). - -2014-08-04: wsfulton - [C#] Merge patch #200 from gpetrou - Changed CSharp license header to include auto-generated - tag so that StyleCop ignores the files. - -2014-08-04: wsfulton - [Java] Merge patch #198 from Yuval Kashtan - Support for java.nio.ByteBuffer mapping to - unsigned char * in various.i in NIOBUFFER typemaps. - -2014-07-14: ianlancetaylor - [Go] Change struct definition to use void *, not uint8, so - that the type is recorded as possibly containing - pointers. This ensures that the 1.3 garbage collector - does not collect pointers passed to C++ code. - -2014-07-01: wsfulton - Fix SF Bug #1375 - Expansion of the $parentclassname special variable incorrectly contains - brackets in the expanded name. - -Version 3.0.2 (4 Jun 2014) -========================== - -2014-06-02: v-for-vandal - [Lua] Pull request #176: - If class has no __eq implemented, then default __eq is generated. - Default __eq compares actual pointers stored inside Lua userdata. - -2014-06-02: vkalinin - Fix #183 - %extend and unnamed nested structs - -2014-05-28: kwwette - Fix install failure when using an 'out of source' build using the shipped - tarball - regression introduced in swig-3.0.1. - -2014-05-24: kwwette - [Octave] Remove deprecated -global/-noglobal command-line arguments - - *** POTENTIAL INCOMPATIBILITY *** - -Version 3.0.1 (27 May 2014) -=========================== - -2014-05-25: hfalcic - [Python] Python 3 byte string output: use errors="surrogateescape" - if available on the version of Python that's in use. This allows - obtaining the original byte string (and potentially trying a fallback - encoding) if the bytes can't be decoded as UTF-8. - - Previously, a UnicodeDecodeError would be raised with no way to treat - the data as bytes or try another codec. - -2014-05-18: vkalinin - Bug #175 - Restore %extend to work for unnamed nested structures by using a C - symbol comprising the outer structure name and unnamed variable instance name. - -2014-05-15: kwwette - Add #166 - 'make check' now works out of source. This required the examples to build - out of source. The main languages have been tested - C#, Go, Guile, Java, Javascript, - Lua, Octave, Perl, PHP, Python, Ruby and Tcl. - -2014-05-01: Oliver Buchtala - Javascript support added, see Javascript chapter in the documentation. - -2014-05-01: olly - [PHP] The generated __isset() method now returns true for read-only properties. - -2014-04-24: kwwette - [Go] Fix go ./configure parsing of gccgo --version, and - goruntime.swg typo in __GNUC_PATCHLEVEL__ (SF Bug #1298) - -2014-04-24: kwwette - Fix {python|perl5|ruby|tcl}/java examples - - In Lib/gcj/cni.i, for compatibility with newer gcj versions: - - - remove JvAllocObject() which gcj no longer defines, from gcj Changelog: - 2004-04-16 Bryce McKinlay <mckinlay@redhat.com> - * gcj/cni.h (JvAllocObject): Remove these obsolete, - undocumented CNI calls. - - - change JvCreateJavaVM() argument from void* to JvVMInitArgs*, from gcj Changelog: - 2005-02-23 Thomas Fitzsimmons <fitzsim@redhat.com> - PR libgcj/16923 - ... - (JvCreateJavaVM): Declare vm_args as JvVMInitArgs* rather than void*. - - *** POTENTIAL INCOMPATIBILITY *** - -2014-04-08: wsfulton - SF Bug #1366 - Remove duplicate declarations of strtoimax and strtoumax in inttypes.i - -2014-04-08: wsfulton - [Java C#] Enums which have been ignored via %ignore and are subsequently - used are handled slightly differently. Type wrapper classes are now generated - which are effectively a wrapper of an empty enum. Previously in Java uncompilable - code was generated and in C# an int was used. - -2014-04-04: wsfulton - Fix regression in 3.0.0 where legal code following an operator<< definition might - give a syntax error. SF Bug #1365. - -2014-04-03: olly - [PHP] Fix wrapping director constructors with default parameters - with a ZTS-enabled build of PHP. - -2014-04-02: olly - [PHP] Pass the ZTS context we already have to avoid needing to - call TSRMLS_FETCH, which is relatively expensive. - -2014-04-02: olly - [PHP] Pass ZTS context through to t_output_helper() so it works - with a ZTS-enabled build of PHP. Reported by Pierre Labastie in - github PR#155. - -2014-03-28: wsfulton - [Java C# D Go] Fixes for C enums used in an API and the definition of the enum - has not been parsed. For D, this fixes a segfault in SWIG. The other languages - now produce code that compiles, although the definition of the enum is needed - in order to use the enum properly from the target language. - -2014-03-23: v-for-vandal - [Lua] Fix for usage of snprintf in Lua runtime which Visual Studio does not have. - -Version 3.0.0 (16 Mar 2014) -=========================== - -2014-03-16: wsfulton - C++11 support initially developed as C++0x support by Matevz Jekovec as a Google Summer of Code - project has been further extended. The C++11 support is comprehensive, but by no means complete - or without limitations. Full details for each new feature in C++11 is covered in the - CPlusPlus11.html chapter in the documentation which is included in SWIG and also available - online at https://www.swig.org/Doc3.0/CPlusPlus11.html. - -2014-03-14: v-for-vandal - [Lua] Numerous Lua improvements: - 1. %nspace support has been added. Namespaces are mapped to tables in the module, with the same - name as the C++ namespace. - 2. Inheritance is now handled differently. Each class metatable keeps a list of class bases instead - of merging all members of all bases into the derived class. - 3. The new metatables result in differences in accessing class members. For example: - - %module example - struct Test { - enum { TEST1 = 10, TEST2 = 20 }; - static const int ICONST = 12; - }; - - Now this can be used as follows: - print(example.Test.TEST1) - print(example.Test.ICONST) - The old way was: - print(example.Test_TEST1) - print(example.Test_ICONST) - - 4. The special class metatable member ".constructor" was removed. Now SWIG generates the proxy - function by itself and assigns it directly to the class table "__call" method. - 5. eLua should also now support inheritance. - 6. 'const' subtable in eLua is considered deprecated. - - Changes in behaviour: - a. You can no longer assign to non-existing class members in classes without a __setitem__ method. - It will cause a Lua error. - b. You can no longer iterate over a module table and copy everything into the global namespace. - Actually, this was never the case, but it is now explicitly prohibited. - c. Now changing a base class will immediately affect all derived classes. - d. There might be some issues with inheritance. Although the bases iteration scheme is the same - as was used for merging base classes into derived one, some unknown issues may arise. - - The old metatable behaviour can be restored by using the -no-old-metatable-bindings option. - - *** POTENTIAL INCOMPATIBILITY *** - -2014-03-06: wsfulton - [Python] Change in default behaviour wrapping C++ bool. Only a Python True or False - will now work for C++ bool parameters. This fixes overloading bool with other types. - Python 2.3 minimum is now required for wrapping bool. - - When wrapping: - - const char* overloaded(bool value) { return "bool"; } - const char* overloaded(int value) { return "int"; } - - Previous behaviour: - >>> overloaded(False) - 'int' - >>> overloaded(True) - 'int' - >>> overloaded(0) - 'int' - - Now we get the expected behaviour: - >>> overloaded(False) - 'bool' - >>> overloaded(0) - 'int' - - The consequence is when wrapping bool in non-overloaded functions: - - const char* boolfunction(bool value) { return value ? "true" : "false"; } - - The previous behaviour was very Pythonic: - >>> boolfunction("") - 'false' - >>> boolfunction("hi") - 'true' - >>> boolfunction(12.34) - 'true' - >>> boolfunction(0) - 'false' - >>> boolfunction(1) - 'true' - - Now the new behaviour more along the lines of C++ due to stricter type checking. The - above calls result in an exception and need to be explicitly converted into a bool as - follows: - >>> boolfunction(0) - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - TypeError: in method 'boolfunction', argument 1 of type 'bool' - >>> boolfunction(bool(0)) - 'false' - - The old behaviour can be resurrected by passing the -DSWIG_PYTHON_LEGACY_BOOL command line - parameter when executing SWIG. Typemaps can of course be written to customise the behaviour - for specific parameters. - - *** POTENTIAL INCOMPATIBILITY *** - -2014-03-06: wsfulton - Fix SF Bug #1363 - Problem with method overloading when some methods are added by %extend - and others are real methods and using template default parameters with smart pointers. - This is noticeable as a regression since 2.0.12 when using the default smart pointer - handling for some languages when the smart pointer wraps std::map and other STL containers. - -2014-03-02: wsfulton - [Python] SF Patch #346 from Jens Krueger. Correct exception thrown attempting to - access a non-existent C/C++ global variable on the 'cvar' object. The exception thrown - used to be a NameError. However, as this access is via a primary, an AttributeError - is more correct and so the exception thrown now is an AttributeError. Reference: - http://docs.python.org/2/reference/expressions.html#attribute-references - - *** POTENTIAL INCOMPATIBILITY *** - -2014-03-01: wsfulton - [Python] Patch #143 Fix type shown when using type() to include the module and package - name when using -builtin. - -2014-03-01: wsfulton - [Python] SF patch #347 Fix missing argument count checking with -modern. - Fixes regression introduced when builtin changes were introduced in SWIG-2.0.3. - -2014-02-21: wsfulton - [PHP] Fix warning suppression using %warnfilter for PHP reserved class names. - -2014-02-19: olly - [Lua] Add keyword warnings for Lua keywords and Basic Functions. - -2014-02-19: olly - -Wallkw now includes keywords for all languages with keyword - warnings (previously Go and R were missing). - -2014-02-19: olly - [PHP] Update the lists of PHP keywords with new ones from PHP 5.4 - and newer (and some missing ones from 5.3). Reserved PHP constants - names are now checked against enum values and constants, instead - of against function and method names. Built-in PHP function names - no longer match methods added by %extend. Functions and methods - named '__sleep', '__wakeup', 'not', 'parent', or 'virtual' are no - longer needlessly renamed. - -2014-02-15: wsfulton - Fix the %$ismember %rename predicates to also apply to members added via %extend. - - Add %$isextendmember for %rename of members added via %extend. This can be used to - distinguish between normal class/struct members and %extend members. For example - '%$ismember, %$not %$isextendmember' will now identify just class/struct members. - - *** POTENTIAL INCOMPATIBILITY *** - -2014-02-16: hfalcic - [Python] Patch #137 - fix crashes/exceptions in exception handling in Python 3.3 - -2014-02-15: wsfulton - [Java] Add support for the cdata library. - -2014-02-08: vkalinin - Nested class support added. This primarily allows SWIG to properly parse nested - classes and keep the nested class information in the parse tree. Java and C# - have utilised this information wrapping the C++ nested classes as Java/C# - nested classes. The remaining target languages ignore nested classes as in - previous versions. Help is needed by users of these remaining languages to - design how C++ nested classes can be best wrapped. Please talk to us on the - swig-devel mailing list if you think you can help. - - Previously, there was limited nested class support. Nested classes were treated - as opaque pointers. However, the "nestedworkaround" feature provided a way to - wrap a nested class as if it was a global class. This feature no longer exists - and is replaced by the new "flatnested" feature. This effectively does the same - thing with less manual code to be written. Please see the 'Nested classes' - section in the documentation in SWIGPlus.html if you were previously using this - feature. - - SWIG now parses the contents of nested classes where previously it did not. You - may find that you will need to make adjustments to your interface file as - effectively extra code is being wrapped. - - *** POTENTIAL INCOMPATIBILITY *** - -2014-02-06: gjanssens - [Guile] Patch #133. Make scm to string conversion work with non-ascii strings. - Guile 2 has a completely rewritten string implementation. SWIG made some assumptions - that are no longer valid as to the internals of guile's string representation. - -2014-01-30: wsfulton - [C#] Add new swigtype_inout.i library containing SWIGTYPE *& OUTPUT typemaps. - - Example usage wrapping: - - void f(XXX *& x) { x = new XXX(111); } - - would be: - - XXX x = null; - f(out x); - // use x - x.Dispose(); // manually clear memory or otherwise leave out and leave it to the garbage collector - -2014-01-21: ianlancetaylor - [Go] Add %go_import directive. - -2014-01-21: ianlancetaylor - [Go] Add support for Go 1.3, not yet released. - -2014-01-20: wsfulton - Director exceptions (Swig::DirectorException) now derive from std::exception - and hence provide the what() method. In Python and Ruby, this replaces the now - deprecated DirectorException::getMessage() method. - -2014-01-14: diorcety - Patch #112 - Fix symbol resolution involving scopes that have multiple levels - of typedefs - fixes some template resolutions as well as some typemap searches. - -2014-01-11: wsfulton - Fix and document the naturalvar feature override behaviour - the naturalvar - feature attached to a variable name has precedence over the naturalvar - feature attached to the variable's type. The overriding was not working - when turning the feature off on the variable's name. - - Fix so that any use of the naturalvar feature will override the global - setting. Previously when set globally by -naturalvar or %module(naturalvar=1), - use of the naturalvar feature was not always honoured. - -2014-01-06: ianlancetaylor - [Go] Fix bug that broke using directors from a thread not - created by Go. - -2013-12-24: ptomulik - [Python] SF Bug #1297 - - Resolve several issues related to python imports. - For example, it's now possible to import modules having the same module - names, but belonging in different packages. - - From the user's viewpoint, this patch gives a little bit more control on - import statements generated by SWIG. The user may choose to use relative - or absolute imports. - - Some details: - - we (still) generate import statements in the form 'import a.b.c' which - corresponds to absolute imports in python3 and (the only available) - ambiguous one in python2. - - added -relativeimport option to use explicit relative import syntax - (python3), - - The "Python Packages" section in the documentation discusses how to work - with importing packages including the new -relativeimport command line option. - -2013-12-23: vadz - [Octave, Perl, Python, R, Ruby, Tcl] Change the length of strings created from fixed-size char - buffers in C code. - - This is a potential backwards compatibility break: a "char buf[5]" containing "ho\0la" was - returned as a string of length 5 before, but is returned as a string of length 2 now. Also, - it was possible to assign a (non-NUL-terminated) string "hello" to such a buffer before but - now this fails and only "helo" can fit. - - Apply "char FIXSIZE[ANY]" typemaps to explicitly choose the old behaviour. - - *** POTENTIAL INCOMPATIBILITY *** - -2013-12-23: talby - [Perl] Add support for directors. - -2013-12-18: ianlancetaylor - [Go] Don't require that Go environment variables be set - when running examples or testsuite when using Go 1 or - later. - -2013-12-17: ianlancetaylor - [Go] Remove -longsize option (for backward compatibility, - ignore it if seen). - -2013-12-17: ianlancetaylor - [Go] Add -go-pkgpath option. - -2013-12-16: ianlancetaylor - [Go] Update for Go 1.2 release. Add support for linking - SWIG code directly into executable, rather than using a - shared library. - -2013-12-13: ianlancetaylor - [Go] Add SWIG source file name as comments in generated - files. This can be used by Go documentation tools. - -2013-12-12: jleveque - [Lua] Fix typo (wchar instead of wchar_t) which made wchar.i - for Lua useless. - -2013-12-12: vmiklos - [PHP] PHP's peculiar call-time pass-by-reference feature was - deprecated in PHP 5.3 and removed in PHP 5.4, so update the REF - typemaps in phppointers.i to specify pass-by-reference in the - function definition. Examples/php/pointer has been updated - accordingly. - -2013-12-12: olly - [PHP] The usage of $input in PHP directorout typemaps has been - changed to be consistent with other languages. The typemaps - provided by SWIG have been updated accordingly, but if you - have written your own directorout typemaps, you'll need to - update $input to &$input (or make equivalent changes). - - *** POTENTIAL INCOMPATIBILITY *** - -2013-11-27: vadz - [C#, Java, Python] Add std_auto_ptr.i defining typemaps for returning std::auto_ptr<>. - -2013-11-09: wsfulton - [C#] Apply patch #79 from Brant Kyser - - Remove using directives from the generated C# code and fully qualify the use of all .NET - framework types in order to minimize potential name collisions from input files defining - types, namespace, etc with the same name as .NET framework members. - - Globally qualify the use of .NET framework types in the System namespace - - Remove .NET 1.1 support, .NET 2 is the minimum for the C# module - - This is a potential backwards compatibility break if code has been added relying on these using - statements that used to be generated: - - using System; - using System.Runtime.InteropServices; - - The quick fix to add these back in is to add the -DSWIG2_CSHARP command line option when - executing SWIG. See CSharp.html documentation for more info. - - *** POTENTIAL INCOMPATIBILITY *** - -2013-11-05: wsfulton - [Java] Fix some corner cases for the $packagepath/$javaclassname special variable substitution. - -2013-11-05: wsfulton - [Java] Apply patch #91 from Marvin Greenberg - Add director:except feature for improved - exception handling in director methods for Java. - -2013-10-15: vadz - Allow using \l, \L, \u, \U and \E in the substitution part of %(regex:/pattern/subst/) - inside %rename to change the case of the text being replaced. - -2013-10-12: wsfulton - [CFFI] Apply #96 - superclass not lispify - -2013-10-12: wsfulton - Merge in C++11 support from the gsoc2009-matevz branch where Matevz Jekovec first - started the C++0x additions. Documentation of the C++11 features supported is in a - new Chapter of the documentation, "SWIG and C++11" in Doc/Manual/CPlusPlus11.html. - -2013-10-04: wsfulton - Fix %naturalvar not having any affect on templated classes instantiated with an - enum as the template parameter type. Problem reported by Vadim Zeitlin. - -2013-09-20: wsfulton - [Java] Fix a memory leak for the java char **STRING_ARRAY typemaps. - -Version 2.0.12 (9 Feb 2014) -=========================== - -2014-01-16: wsfulton - [PHP] Fix compilation error in ZTS mode (64 bit windows) due to incorrect placement - of TSRMLS_FETCH() in SWIG_Php_GetModule() as reported by Mark Dawson-Butterworth. - -2014-01-13: kwwette - [Octave] update support to Octave version 3.8.0 - - - Octave 3.8.0 no longer defines OCTAVE_API_VERSION_NUMBER, but 3.8.1 - will define OCTAVE_{MAJOR,MINOR,PATCH}_VERSION instead: see - http://hg.savannah.gnu.org/hgweb/octave/rev/b6b6e0dc700e - So we now use a new macro SWIG_OCTAVE_PREREQ(major,minor,patch) to - enable features requiring Octave version major.minor.patch or later. - - For Octave versions prior to 3.8.1, we reconstruct values for - OCTAVE_{MAJOR,MINOR,PATCH}_VERSION based on OCTAVE_API_VERSION_NUMBER, - extracted from Octave's ChangeLogs. An additional hack is needed to - distinguish between Octave <= 3.2.x and 3.8.0, neither of which define - OCTAVE_API_VERSION_NUMBER. - - - Octave 3.8.0 deprecates symbol_table::varref(), so remove its use - for this and future versions of Octave. - - - Octave 3.8.0 removes octave_value::is_real_nd_array(), used in - octave_swig_type::dims(). Its use is not required here, so remove it. - - - Retested against Octave versions 3.0.5, 3.2.4, 3.4.3, 3.6.4, and 3.8.0. - - - Updated Octave documentation with tested Octave versions, and added a - warning against using versions <= 3.x.x, which are no longer tested. - -2013-12-22: wsfulton - C++11 support for new versions of erase and insert in the STL containers. - - The erase and insert methods in the containers use const_iterator instead - of iterator in C++11. There are times when the methods wrapped must match - the parameters exactly. Specifically when full type information for - template types is missing or SWIG fails to look up the type correctly, - for example: - - %include <std_vector.i> - typedef float Real; - %template(RealVector) std::vector<Real>; - - SWIG does not find std::vector<Real>::iterator because %template using - typedefs does not always work and so SWIG doesn't know if the type is - copyable and so uses SwigValueWrapper<iterator> which does - not support conversion to another type (const_iterator). This resulted - in compilation errors when using the C++11 version of the containers. - - Closes #73 - -2013-10-17: wsfulton - [R] Fix SF #1340 - Visual Studio compile error in C++ wrappers due to #include <exception> - within extern "C" block. - -2013-10-17: wsfulton - [Python] Fix SF #1345 - Missing #include <stddef.h> for offsetof when using -builtin. - -2013-10-12: wsfulton - [Lua] Apply #92 - missing return statements for SWIG_Lua_add_namespace_details() - and SWIG_Lua_namespace_register(). - -Version 2.0.11 (15 Sep 2013) -============================ - -2013-09-15: wsfulton - [R] Fix attempt to free a non-heap object in OUTPUT typemaps for: - unsigned short *OUTPUT - unsigned long *OUTPUT - signed long long *OUTPUT - char *OUTPUT - signed char*OUTPUT - unsigned char*OUTPUT - -2013-09-12: wsfulton - [Lua] Pull Git patch #62. - 1) Static members and static functions inside class can be accessed as - ModuleName.ClassName.FunctionName (MemberName respectively). Old way such as - ModuleName.ClassName_FunctionName still works. - 2) Same goes for enums inside classes: ModuleName.ClassName.EnumValue1 etc. - -2013-09-12: wsfulton - [UTL] Infinity is now by default an acceptable value for type 'float'. This fix makes - the handling of type 'float' and 'double' the same. The implementation requires the - C99 isfinite() macro, or otherwise some platform dependent equivalents, to be available. - - Users requiring the old behaviour of not accepting infinity, can define a 'check' typemap - wherever a float is used, such as: - - %typemap(check,fragment="<float.h>") float, const float & %{ - if ($1 < -FLT_MAX || $1 > FLT_MAX) { - SWIG_exception_fail(SWIG_TypeError, "Overflow in type float"); - } - %} - - *** POTENTIAL INCOMPATIBILITY *** - -2013-08-30: wsfulton - [Lua] Pull Git patch #81: Include Lua error locus in SWIG error messages. - This is standard information in Lua error messages, and makes it much - easier to find bugs. - -2013-08-29: wsfulton - Pull Git patch #75: Handle UTF-8 files with BOM at beginning of file. Was giving an - 'Illegal token' syntax error. - -2013-08-29: wsfulton - [C#] Pull Git patch #77: Allow exporting std::map using non-default comparison function. - -2013-08-28: wsfulton - [Python] %implicitconv is improved for overloaded functions. Like in C++, the methods - with the actual types are considered before trying implicit conversions. Example: - - %implicitconv A; - struct A { - A(int i); - }; - class CCC { - public: - int xx(int i) { return 11; } - int xx(const A& i) { return 22; } - }; - - The following python code: - - CCC().xx(-1) - - will now return 11 instead of 22 - the implicit conversion is not done. - -2013-08-23: olly - [Python] Fix clang++ warning in generated wrapper code. - -2013-08-16: wsfulton - [Python] %implicitconv will now accept None where the implicit conversion takes a C/C++ pointer. - Problem highlighted by Bo Peng. Closes SF patch #230. - -2013-08-07: wsfulton - [Python] SF Patch #326 from Kris Thielemans - Remove SwigPyObject_print and SwigPyObject_str and - make the generated wrapper use the default python implementations, which will fall back to repr - (for -builtin option). - - Advantages: - - it avoids the swig user having to jump through hoops to get print to work as expected when - redefining repr/str slots. - - typing the name of a variable on the python prompt now prints the result of a (possibly redefined) - repr, without the swig user having to do any extra work. - - when redefining repr, the swig user doesn't necessarily have to redefine str as it will call the - redefined repr - - the behaviour is exactly the same as without the -builtin option while requiring no extra work - by the user (aside from adding the %feature("python:slot...) statements of course) - - Disadvantage: - - default str() will give different (but clearer?) output on swigged classes - -2013-07-30: wsfulton - [Python, Ruby] Fix #64 #65: Missing code in std::multimap wrappers. Previously an instantiation - of a std::map was erroneously required in addition to an instantiation of std::multimap with the - same template parameters to prevent compilation errors for the wrappers of a std::multimap. - -2013-07-14: joequant - [R] Change types file to allow for SEXP return values - -2013-07-05: wsfulton - [Python] Add %pythonbegin directive which works like %pythoncode, except the specified code is - added at the beginning of the generated .py file. This is primarily needed for importing from - __future__ statements required to be at the very beginning of the file. Example: - - %pythonbegin %{ - from __future__ import print_function - print("Loading", "Whizz", "Bang", sep=' ... ') - %} - -2013-07-01: wsfulton - [Python] Apply SF patch #340 - Uninitialized variable fix in SWIG_Python_NonDynamicSetAttr - when using -builtin. - -2013-07-01: wsfulton - [Python, Ruby, Ocaml] Apply SF patch #341 - fix a const_cast in generated code that was generating - a <:: digraph when using the unary scope operator (::) (global scope) in a template type. - -2013-07-01: wsfulton - [Python] Add SF patch #342 from Christian Delbaere to fix some director classes crashing on - object deletion when using -builtin. Fixes SF bug #1301. - -2013-06-11: wsfulton - [Python] Add SWIG_PYTHON_INTERPRETER_NO_DEBUG macro which can be defined to use the Release version - of the Python interpreter in Debug builds of the wrappers. The Visual Studio .dsp example - files have been modified to use this so that Debug builds will now work without having - to install or build a Debug build of the interpreter. - -2013-06-07: wsfulton - [Ruby] Git issue #52. Fix regression with missing rb_complex_new function for Ruby - versions prior to 1.9 using std::complex wrappers if just using std::complex as an output type. - Also fix the Complex helper functions external visibility (to static by default). - -2013-06-04: olly - [PHP] Fix SWIG_ZTS_ConvertResourcePtr() not to dereference NULL - if the type lookup fails. - -Version 2.0.10 (27 May 2013) -============================ - -2013-05-25: wsfulton - [Python] Fix Python 3 inconsistency when negative numbers are passed - where a parameter expects an unsigned C type. An OverFlow error is - now consistently thrown instead of a TypeError. - -2013-05-25: Artem Serebriyskiy - SVN Patch ticket #338 - fixes to %attribute macros for template usage - with %arg. - -2013-05-19: wsfulton - Fix ccache-swig internal error bug due to premature file cleanup. - - Fixes SF bug 1319 which shows up as a failure in the ccache tests on - Debian 64 bit Wheezy, possibly because ENABLE_ZLIB is defined. - - This is a corner case which will be hit when the maximum number of files - in the cache is set to be quite low (-F option), resulting in a cache miss. - -2013-05-09: kwwette - [Octave] Fix bugs in Octave module loading: - - fix a memory leak in setting of global variables - - install functions only once, to speed up module loads - -2013-04-28: gjanssens - [Guile] Updates in guile module: - - Add support for guile 2.0 - - Drop support for guile 1.6 - - Drop support for generating wrappers using guile's gh interface. - All generated wrappers will use the scm interface from now on. - - Deprecate -gh and -scm options. They are no longer needed. - A warning will be issued when these options are still used. - - Fix all tests and examples to have a successful travis test - -2013-04-18: wsfulton - Apply Patch #36 from Jesus Lopez to add support for $descriptor() special variable macro expansion - in fragments. For example: - - %fragment("nameDescriptor", "header") - %{ - static const char *nameDescriptor = "$descriptor(Name)"; - %} - - which will generate into the wrapper if the fragment is used: - - static const char *nameDescriptor = "SWIGTYPE_Name"; - -2013-04-18: wsfulton - Fix SF Bug #428 - Syntax error when preprocessor macros are defined inside of enum lists, such as: - - typedef enum { - eZero = 0 - #define ONE 1 - } EFoo; - - The macros are silently ignored. - -2013-04-17: wsfulton - [C#] Pull patch #34 from BrantKyser to fix smart pointers in conjunction with directors. - -2013-04-15: kwwette - [Octave] Fix bugs in output of cleanup code. - - Cleanup code is now written also after the "fail:" label, so it will be called if - a SWIG_exception is raised by the wrapping function, consistent with other modules. - - Octave module now also recognises the "$cleanup" special variable, if needed. - -2013-04-08: kwwette - Add -MP option to SWIG for generating phony targets for all dependencies. - - Prevents make from complaining if header files have been deleted before - the dependency file has been updated. - - Modelled on similar option in GCC. - -2013-04-09: olly - [PHP] Add missing directorin typemap for char* and char[] which - fixes director_string testcase failure. - -2013-04-05: wsfulton - [Ruby] SF Bug #1292 - Runtime fixes for Proc changes in ruby-1.9 when using STL - wrappers that override the default predicate, such as: - - %template(Map) std::map<swig::LANGUAGE_OBJ, swig::LANGUAGE_OBJ, swig::BinaryPredicate<> >; - -2013-04-05: wsfulton - [Ruby] SF Bug #1159 - Correctly check rb_respond_to call return values to fix some - further 1.9 problems with functors and use of Complex wrappers. - -2013-04-02: wsfulton - [Ruby] Runtime fixes for std::complex wrappers for ruby-1.9 - new native Ruby complex numbers are used. - -2013-03-30: wsfulton - [Ruby] Fix seg fault when using STL containers of generic Ruby types, GC_VALUE or LANGUAGE_OBJECT, - on exit of the Ruby interpreter. More frequently observed in ruby-1.9. - -2013-03-29: wsfulton - [Ruby] Fix delete_if (reject!) for the STL container wrappers which previously would - sometimes seg fault or not work. - -2013-03-25: wsfulton - [Python] Fix some undefined behaviour deleting slices in the STL containers. - -2013-03-19: wsfulton - [C#, Java, D] Fix seg fault in SWIG using directors when class and virtual method names are - the same except being in different namespaces when the %nspace feature is not being used. - -2013-02-19: kwwette - Fix bug in SWIG's handling of qualified (e.g. const) variables of array type. Given the typedef - a(7).q(volatile).double myarray // typedef volatile double[7] myarray; - the type - q(const).myarray // const myarray - becomes - a(7).q(const volatile).double // const volatile double[7] - Previously, SwigType_typedef_resolve() produces the type - q(const).a(7).q(volatile).double // non-sensical type - which would never match %typemap declarations, whose types were parsed correctly. - Add typemap_array_qualifiers.i to the test suite which checks for the correct behaviour. - -2013-02-18: wsfulton - Deprecate typedef names used as constructor and destructor names in %extend. The real - class/struct name should be used. - - typedef struct tagEStruct { - int ivar; - } EStruct; - - %extend tagEStruct { - EStruct() // illegal name, should be tagEStruct() - { - EStruct *s = new EStruct(); - s->ivar = ivar0; - return s; - } - ~EStruct() // illegal name, should be ~tagEStruct() - { - delete $self; - } - } - - For now these trigger a warning: - - extend_constructor_destructor.i:107: Warning 522: Use of an illegal constructor name 'EStruct' in - %extend is deprecated, the constructor name should be 'tagEStruct'. - extend_constructor_destructor.i:111: Warning 523: Use of an illegal destructor name 'EStruct' in - %extend is deprecated, the destructor name should be 'tagEStruct'. - - These %extend destructor and constructor names were valid up to swig-2.0.4, however swig-2.0.5 ignored - them altogether for C code as reported in SF bug #1306. The old behaviour of using them has been - restored for now, but is officially deprecated. This does not apply to anonymously defined typedef - classes/structs such as: - - typedef struct {...} X; - -2013-02-17: kwwette - When generating functions provided by %extend, use "(void)" for no-argument functions - instead of "()". This prevents warnings when compiling with "gcc -Wstrict-prototypes". - -2013-02-17: kwwette - [Octave] Minor fix to autodoc generation: get the right type for functions returning structs. - -2013-02-15: wsfulton - Deprecate typedef names used in %extend that are not the real class/struct name. For example: - - typedef struct StructBName { - int myint; - } StructB; - - %extend StructB { - void method() {} - } - - will now trigger a warning: - - swig_extend.i:19: Warning 326: Deprecated %extend name used - the struct name StructBName - should be used instead of the typedef name StructB. - - This is only partially working anyway (the %extend only worked if placed after the class - definition). - -2013-02-09: wsfulton - [CFFI] Apply patch #22 - Fix missing package before &body - -2013-01-29: wsfulton - [Java] Ensure 'javapackage' typemap is used as it stopped working from version 2.0.5. - -2013-01-28: wsfulton - [Python] Apply patch SF #334 - Fix default value conversions "TRUE"->True, "FALSE"->False. - -2013-01-28: wsfulton - [Java] Apply patch SF #335 - Truly ignore constructors in directors with %ignore. - -2013-01-18: Brant Kyser - [Java] Patch #15 - Allow the use of the nspace feature without the -package commandline option. - This works as long and the new jniclasspackage pragma is used to place the JNI intermediate class - into a package and the nspace feature is used to place all exposed types into a package. - -2013-01-15: wsfulton - Fix Visual Studio examples to work when SWIG is unzipped into a directory containing spaces. - -2013-01-15: wsfulton - [C#] Fix cstype typemap lookup for member variables so that a fully qualified variable name - matches. For example: - %typemap(cstype) bool MVar::mvar "MyBool" - struct MVar { - bool mvar; - }; - -2013-01-11: Brant Kyser - [Java, C#, D] SF Bug #1299 - Fix generated names for when %nspace is used on - classes with the same name in two different namespaces. - -2013-01-11: Vladimir Kalinin - [C#] Add support for csdirectorin 'pre', 'post' and 'terminator' attributes. - -2013-01-08: olly - [PHP] Fix to work with a ZTS build of PHP (broken in 2.0.7). - -2013-01-07: olly - Fix bashism in configure, introduced in 2.0.9. - -2013-01-06: wsfulton - Pull patch #4 from ptomulik to fix SF Bug #1296 - Fix incorrect warning for virtual destructors - in templates, such as: - Warning 521: Illegal destructor name B< A >::~B(). Ignored. - -2013-01-05: wsfulton - [Python] Pull patch #3 from ptomulik to fix SF Bug #1295 - standard exceptions as - classes using the SWIG_STD_EXCEPTIONS_AS_CLASSES macro. - -2013-01-04: wsfulton - [Java] Pull patch #2 from BrantKyser to fix SF Bug #1283 - fix smart pointers in conjuction - with directors. - -2013-01-03: wsfulton - [Java] Pull patch #1 from BrantKyser to fix SF Bug #1278 - fix directors and nspace feature when - multilevel namespaces are used. - -Version 2.0.9 (16 December 2012) -================================ - -2012-12-16: wsfulton - Fix garbage line number / empty file name reporting for some missing - '}' or ')' error messages. - -2012-12-15: kkaempf - [Ruby] Apply patch 3530444, Class#methods and Class#constants returns array of - symbols in Ruby 1.9+ - -2012-12-14: kkaempf - [Ruby] Apply patch 3530439 and finally replace all occurrences of the STR2CSTR() macro - with StringValuePtr(). STR2CSTR was deprecated since years and got removed in Ruby 1.9 - -2012-12-14: kkaempf - [Ruby] Applied patches #3530442 and 3530443 to adapt compile and runtime include - paths to match Ruby 1.9+ - -2012-12-14: wsfulton - [CFFI] Fix #3161614 - Some string constants are incorrect - -2012-12-13: wsfulton - [CFFI] Fix #3529690 - Fix incorrect constant names. - -2012-12-12: drjoe - [R] add fix to finalizer that was missed earlier - -2012-12-11: wsfulton - [Python] Apply patch #3590522 - fully qualified package paths for Python 3 even if a module is in the - same package. - -2012-12-08: wsfulton - [Python] Bug #3563647 - PyInt_FromSize_t unavailable prior to Python 2.5 for unsigned int types. - -2012-12-08: wsfulton - [Perl] Fix bug #3571361 - C++ comment in C wrappers. - -2012-12-07: wsfulton - [C#] Apply patch #3571029 which adds missing director support for const unsigned long long &. - -2012-11-28: kwwette - [Octave] Simplified module loading: now just the syntax - $ example; - is accepted, which loads functions globally but constants and variables relative to the current scope. - This make module loading behaviour reliably consistent, and reduces problems when loading modules which - depend on other modules which may not have been previously loaded. - -2012-11-27: wsfulton - [cffi] Fix junk output when wrapping single character literal constants. - -2012-11-17: wsfulton - [Tcl, Modula3] Add missing support for -outdir. - -2012-11-17: wsfulton - Fix segfaults when using filename paths greater than 1024 characters in length. - -2012-11-14: wsfulton - [ccache-swig] Apply patch #3586392 from Frederik Deweerdt to fix some error cases - incorrectly using - memory after it has been deleted. - -2012-11-09: vzeitlin - [Python] Fix overflow when passing values greater than LONG_MAX from Python 3 for parameters with unsigned long C type. - -2012-11-09: wsfulton - Fix some feature matching issues for implicit destructors and implicit constructors and implicit - copy constructors added with %copyctor. Previously a feature for these had to be fully qualified - in order to match. Now the following will also match: - - %feature("xyz") ~XXX(); - struct XXX {}; - -2012-11-09: wsfulton - Further consistency in named output typemap lookups for implicit constructors and destructors and - implicit copy constructors added with %copyctor. Previously only the fully qualified name was being - used, now the unqualified name will also be used. For example, previously: - - example.i:38: Searching for a suitable 'out' typemap for: void Space::More::~More - Looking for: void Space::More::~More - Looking for: void - - Now the unqualified name is also used: - - example.i:38: Searching for a suitable 'out' typemap for: void Space::More::~More - Looking for: void Space::More::~More - Looking for: void ~More - Looking for: void - -2012-11-02: wsfulton - Fix some subtle named output typemap lookup misses, the fully qualified name was not always being - used for variables, for example: - - struct Glob { - int MyVar; - }; - - Previously the search rules (as shown by -debug-tmsearch) for the getter wrapper were: - - example.i:44: Searching for a suitable 'out' typemap for: int MyVar - Looking for: int MyVar - Looking for: int - - Now the scope is named correctly: - - example.i:44: Searching for a suitable 'out' typemap for: int Glob::MyVar - Looking for: int Glob::MyVar - Looking for: int MyVar - Looking for: int - -2012-10-26: wsfulton - Fix director typemap searching so that a typemap specified with a name will be correctly matched. Previously - the name was ignored during the typemap search. Applies to the following list of typemaps: - directorout, csdirectorout, cstype, imtype, ctype, ddirectorout, dtype, gotype, jtype, jni, javadirectorout. - -2012-10-11: wsfulton - Most of the special variables available for use in %exception are now also available for expansion in - %extend blocks. These are: $name $symname $overname $decl $fulldecl $parentclassname $parentclasssymname, see docs - on "Class extension" in SWIGPlus.html. Patch based on submission from Kris Thielemans. - -2012-10-10: wsfulton - Additional new special variables in %exception are expanded as follows: - $parentclassname - The parent class name (if any) for a method. - $parentclasssymname - The target language parent class name (if any) for a method. - -2012-10-08: iant - [Go] Generating Go code now requires using the -intgosize option to - indicate the size of the 'int' type in Go. This is because the - size of the type is changing from Go 1.0 to Go 1.1 for x86_64. - -2012-09-14: wsfulton - Add new warning if the empty template instantiation is used as a base class, for example: - - template <typename T> class Base {}; - %template() Base<int>; - class Derived : public Base<int> {}; - - gives the following warning instead of silently ignoring the base: - - cpp_inherit.i:52: Warning 401: Base class 'Base< int >' has no name as it is an empty template instantiated with '%template()'. Ignored. - cpp_inherit.i:51: Warning 401: The %template directive must be written before 'Base< int >' is used as a base class and be declared with a name. - - -2012-09-11: wsfulton - [Java] Fix #3535304 - Direct use of a weak global reference in directors - sometimes causing seg faults especially on Android. - -2012-09-06: wsfulton - [Java] Fix (char *STRING, size_t LENGTH) typemaps to accept NULL string. - -2012-08-26: drjoe - [R] make ExternalReference slot ref to contain reference - -2012-08-26: drjoe - [R] fix Examples/Makefile to use C in $(CC) rather than $(CXX) - -Version 2.0.8 (20 August 2012) -============================== - -2012-08-15: wsfulton - [Perl] Add size_type, value_type, const_reference to the STL containers. - -2012-08-15: wsfulton - [Python] Add discard and add methods to std::set wrappers so that pyabc.i can be used ensuring - MutableSet is a valid abstract base class for std::set. As reported by Alexey Sokolov. - Similarly for std::multiset. - -2012-08-15: wsfulton - [Python] Fix #3541744 - Missing PyInt_FromSize_t calls for Python 3. - -2012-08-13: wsfulton - [Java] Patch from David Baum to add the assumeoverride feature for Java directors to - improve performance when all overridden methods can be assumed to be overridden. - -2012-08-05: wsfulton - [Python] #3530021 Fix unused variable warning. - -2012-08-05: wsfulton - [C#] Fix #3536360 - Invalid code sometimes being generated for director methods - with many arguments. - -2012-08-05: wsfulton - [Perl] #3545877 - Don't undefine bool if defined by C99 stdbool.h - problem using - Perl 5.16 and later. - -2012-08-04: wsfulton - Remove incorrect warning (314) about target language keywords which were triggered - by using declarations and using directives. For example 'string' is a keyword in C#: - namespace std { class string; } - using std::string; - -2012-07-21: wsfulton - Fix display of pointers in various places on 64 bit systems - only 32 bits were being shown. - -2012-07-21: wsfulton - Fix gdb debugger functions 'swigprint' and 'locswigprint' to display to the gdb output window - rather than stdout. This fixes display problems in gdbtui and the ensures the output - appears where expected in other gdb based debuggers such as Eclipse CDT. - -2012-07-20: kwwette - [Octave] segfault-on-exit prevention hack now preserves exit status, and uses C99 _Exit(). - -2012-07-02: wsfulton - Fix Debian bug http://bugs.debian.org/672035, typemap copy failure - regression introduced - in swig-2.0.5: - %include<stl.i> - using std::pair; - %template(StrPair) pair<std::string, std::string>; - -2012-07-02: wsfulton - Fix using declarations combined with using directives with forward class declarations so that - types are correctly found in scope for templates. Example: - - namespace Outer2 { - namespace Space2 { - template<typename T> class Thing2; - } - } - using namespace Outer2; - using Space2::Thing2; - template<typename T> class Thing2 {}; - // STILL BROKEN void useit2(Thing2<int> t) {} - void useit2a(Outer2::Space2::Thing2<int> t) {} - void useit2b(::Outer2::Space2::Thing2<int> t) {} - void useit2c(Space2::Thing2<int> t) {} - namespace Outer2 { - void useit2d(Space2::Thing2<int> t) {} - } - - %template(Thing2Int) Thing2<int>; - - -2012-06-30: wsfulton - Fix template namespace problems for symbols declared with a forward class declarations, such as: - - namespace Space1 { - namespace Space2 { - template<typename T> struct YYY; - } - template<typename T> struct Space2::YYY { - T yyy(T h) { - return h; - } - }; - void testYYY1(Space1::Space2::YYY<int> yy) {} - void testYYY2(Space2::YYY<int> yy) {} - void testYYY3(::Space1::Space2::YYY<int> yy) {} - } - - %template(YYYInt) Space1::Space2::YYY<int>; - -2012-06-30: wsfulton - Fix namespace problems for symbols declared with a forward class declarations, such as: - - namespace Space1 { - namespace Space2 { - struct XXX; - struct YYY; - } - - struct Space2::YYY {}; - struct Space1::Space2::XXX {}; - - void testXXX2(Space2::XXX xx) {} - void testYYY2(Space2::YYY yy) {} - } - - where xx and yy were not recognised as the proxy classes XXX and YYY. - -2012-06-30: wsfulton - Fix using declarations combined with using directives with forward class declarations so that - types are correctly found in scope. - - namespace Outer2 { - namespace Space2 { - class Thing2; - } - } - using namespace Outer2; - using Space2::Thing2; - class Thing2 {}; - // None of the methods below correctly used the Thing2 proxy class - void useit2(Thing2 t) {} - void useit2a(Outer2::Space2::Thing2 t) {} - void useit2b(::Outer2::Space2::Thing2 t) {} - void useit2c(Space2::Thing2 t) {} - namespace Outer2 { - void useit2d(Space2::Thing2 t) {} - } - -2012-06-25: wsfulton - Fix using declarations combined with using directives so that types are correctly found in scope. - Example: - - namespace Outer2 { - namespace Space2 { - class Thing2 {}; - } - } - using namespace Outer2; // using directive - using Space2::Thing2; // using declaration - void useit2(Thing2 t) {} - - Similarly for templated classes. - -2012-05-29: wsfulton - Fix #3529601 - seg fault when a protected method has the "director" - feature but the parent class does not. Also fix similar problems with - the allprotected feature. - -2012-05-28: wsfulton - Fix seg fault when attempting to warn about an illegal destructor - #3530055, 3530078 and #3530118. - -Version 2.0.7 (26 May 2012) -=========================== -2012-05-26: wsfulton - std::string typemap modifications so they can be used with %apply for other string - classes. - -2012-05-25: wsfulton - [Lua] Fixes for -external-runtime to work again. - -2012-05-22: szager - [python] Disambiguate SWIG_From_unsigned_SS_int and SWIG_From_unsigned_SS_long. - -2012-05-18: olly - [PHP] Fix getters for template members. (SF#3428833, SF#3528035) - -2012-05-14: wsfulton - Fix some language's std::map wrappers to recognise difference_type, size_type, key_type - and mapped_type. - -2012-05-14: kwwette (signed off by xavier98) - [Octave] Prevent Octave from seg-faulting at exit when SWIG - modules are loaded, due to bugs in Octave's cleanup code: - * Wrapping functions now declared with Octave DEFUN_DLD macro, - and loaded through Octave's dynamic module loader - * Global variables of swigref type are now assigned a new() - copy of the swigref class, to prevent double-free errors - * SWIG module at-exit cleanup function now created in Octave - through eval(), so not dependent on loaded .oct library - * For Octave versions 3.1.* to 3.3.*, register C-level at-exit - function which terminates Octave immediately (with correct - status code) without performing memory cleanup. This function - can be controlled with macros in Lib/octave/octruntime.swg - - [Octave] New syntax for determing whether SWIG module should be - loaded globally or non-globally. To load module "example" globally, - type the module name - $ example; - as before; to load module non-globally, assign it to a variable: - $ example = example; - or - $ ex = example; - for a shorter (local) module name. -global/-noglobal command-line - options and module command line are deprecated. Added usage info - to module, so typing - $ help example - or incorrect usage should display proper usage, with examples. - - *** POTENTIAL INCOMPATIBILITY *** - -2012-05-12: olly - [PHP] Fix memory leak in code generated for a callback. Patch from - SF bug #3510806. - -2012-05-12: olly - [PHP] Avoid using zend_error_noreturn() as it doesn't work with all - builds of PHP (SF bug #3166423). Instead we now wrap it in a - SWIG_FAIL() function which we annotate as "noreturn" for GCC to - avoids warnings. This also reduces the size of the compiled - wrapper (e.g. the stripped size is reduced by 6% for Xapian's PHP - bindings). - -2012-05-11: wsfulton - [Java] SF patch #3522855 Fix unintended uninitialised memory access in OUTPUT typemaps. - -2012-05-11: wsfulton - [Java] SF patch #3522674 Fix possible uninitialised memory access in char **STRING_OUT - typemap. - -2012-05-11: wsfulton - [Java] SF patch #3522611 Fix uninitialised size regression in char **STRING_ARRAY - introduced in swig-2.0.6. - -2012-05-11: wsfulton - SF bug #3525050 - Fix regression introduced in swig-2.0.5 whereby defining one typemap - method such as an 'out' typemap may hide another typemap method such as an 'in' typemap - - only occurs when the type is a template type where the template parameters are the same - via a typedef. - -2012-05-10: olly - [PHP] Fix the constant typemaps for SWIGTYPE, etc - previously - these used the wrong name for renamed constants. Add - autodoc_runme.php to the testsuite as a regression test for this. - -2012-05-02: ianlancetaylor - [Go] Remove compatibility support for gccgo 4.6. Using - SWIG with gccgo will now require gccgo 4.7. Using SWIG - with the more commonly used gc compiler is unaffected. - -2012-05-01: wsfulton - Fix generated code for C forward enum declarations in some languages. - -Version 2.0.6 (30 April 2012) -============================= - -2012-04-25: wsfulton - [Lua] Fix uninitialised variable in SWIGTYPE **OUTPUT typemaps as reported by Jim Anderson. - -2012-04-28: wsfulton - [Python] Fix compilation errors when wrapping STL containers on Mac OS X and possibly other systems. - -2012-04-28: wsfulton - [Java] Patch 3521811 from Leo Davis - char **STRING_ARRAY typemaps fixed to handle - null pointers. - -Version 2.0.5 (19 April 2012) -============================= - -2012-04-14: wsfulton - [Lua] Apply patch #3517435 from Miles Bader - prefer to use Lua_pushglobaltable - -2012-04-14: wsfulton - [Ruby] Apply patch #3517769 from Robin Stocker to fix compile error on MacRuby using RSTRING_PTR. - -2012-04-13: wsfulton - Apply patch #3511009 from Leif Middelschulte for slightly optimised char * variable wrappers. - -2012-04-13: wsfulton - [Lua] Apply #3219676 from Shane Liesegang which adds: - - support for %factory - - a __tostring method - - a __disown method - -2012-04-13: wsfulton - [Xml] Apply #3513569 which adds a catchlist to the xml output. - -2012-04-05: olly - [Lua] Add support for Lua 5.2 (patch SF#3514593 from Miles Bader) - -2012-03-26: xavier98 - [octave] Apply patch #3425993 from jgillis: add extra logic to the octave_swig_type::dims(void) method: it checks if the user has defined a __dims__ method and uses this in stead of returning (1,1) - [octave] Apply patch #3424833 from jgillis: make is_object return true for swig types - -2012-03-24: wsfulton - [D] Apply #3502431 to fix duplicate symbols in multiple modules. - -2012-03-21: wsfulton - Fix #3494791 - %$isglobal for %rename matching. - -2012-03-20: wsfulton - Fix #3487706 and #3391906 - missing stddef.h include for ptrdiff_t when using %import - for STL containers and compiling with g++-4.6. An include of stddef.h is now only - generated when SWIG generates STL helper templates which require ptrdiff_t. If you - were previously relying on "#include <stddef.h>" always being generated when using a - %include of an STL header, you may now need to add this in manually. - -2012-03-16: wsfulton - Apply patch #3392264 from Sebastien Bine to parse (unsigned) long long types in enum value assignment. - -2012-03-16: wsfulton - Apply patch #3505530 from Karl Wette to allow custom allocators in STL string classes for the UTL languages. - -2012-03-13: wsfulton - Apply patch #3468362 from Karl Wette to fix %include inside %define. - -2012-03-13: wsfulton - [Python, Ruby, Octave, R] Fix #3475492 - iterating through std::vector wrappers of enumerations. - -2012-02-27: xavier98 (patches from Karl Wette) - [Octave] Use -globals . to load global variables in module namespace - [Octave] Comment declaration of unimplemented function swig_register_director - [Octave] Fix OCTAVE_PATH in octave Makefiles - [Octave] Add support for std::list - fix li_std_containers_int test - [Octave] Fix imports test - -2012-02-16: wsfulton - [Java] Make generated support functions in arrays_java.i static so that generated code - from multiple instances of SWIG can be compiled and linked together - problem reported by - Evan Krause. - -2012-01-24: wsfulton - Fix crash with bad regex - bug #3474250. - -2012-01-24: wsfulton - [Python] Add Python stepped slicing support to the STL wrappers (std::vector, std::list). - Assigning to a slice, reading a slice and deleting a slice with steps now work. - For example: - - %template(vector_i) std::vector<int> - - vi = vector_i(range(10)) - print list(vi) - vi[1:4:2] = [111, 333] - print list(vi) - del vi[3:10:3] - print list(vi) - print list(vi[::-1]) - - gives (same behaviour as native Python sequences such as list): - - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - [0, 111, 2, 333, 4, 5, 6, 7, 8, 9] - [0, 111, 2, 4, 5, 7, 8] - [8, 7, 5, 4, 2, 111, 0] - -2012-01-23: klickverbot - [D] Correctly annotate function pointers with C linkage. - [D] Exception and Error have become blessed names; removed d_exception_name test case. - -2012-01-20: wsfulton - [Python] Fix some indexing bugs in Python STL wrappers when the index is negative, eg: - - %template(vector_i) std::vector<int> - - iv=vector_i([0,1,2,3,4,5]) - iv[-7:] - - now returns [0, 1, 2, 3, 4, 5] instead of [5]. - - vv[7:9] = [22,33] - - now returns [0, 1, 2, 3, 4, 5, 22, 33] instead of "index out range" error. - - Also fix some segfaults when replacing ranges, eg when il is a std::list wrapper: - - il[0:2] = [11] - -2012-01-17: wsfulton - [Go] Fix forward class declaration within a class when used as a base. - -2012-01-07: wsfulton - [C#] Add support for %nspace when using directors. - -2012-01-06: wsfulton - [Java] Patch #3452560 from Brant Kyser - add support for %nspace when using directors. - -2011-12-21: wsfulton - The 'directorin' typemap now accepts $1, $2 etc expansions instead of having to use workarounds - - $1_name, $2_name etc. - -2011-12-20: wsfulton - [Java] Add (char *STRING, size_t LENGTH) director typemaps. - -2011-12-20: wsfulton - [C#, Go, Java, D] Add support for the 'directorargout' typemap. - -2011-12-20: wsfulton - [Ocaml, Octave, PHP, Python, Ruby] Correct special variables in 'directorargout' typemap. - This change will break any 'directorargout' typemaps you may have written. Please change: - $result to $1 - $input to $result - - Also fix the named 'directorargout' DIRECTOROUT typemaps for these languages which didn't - previously compile and add in $1, $2 etc expansion. - - *** POTENTIAL INCOMPATIBILITY *** - -2011-12-10: talby - [perl5] SWIG_error() now gets decorated with perl source file/line number. - [perl5] error handling now conforms to public XS api (fixes perl v5.14 issue). - -2011-12-10: wsfulton - [Android/Java] Fix directors to compile on Android. - - Added documentation and examples for Android. - -2011-12-08: vadz - Bug fix: Handle methods renamed or ignored in the base class correctly in the derived classes - (they could be sometimes mysteriously not renamed or ignored there before). - -2011-12-03: klickverbot - [D] Fix exception glue code for newer DMD 2 versions. - [D] Do not default to 32 bit glue code for DMD anymore. - [D] Use stdc.config.c_long/c_ulong to represent C long types. - -2011-12-01: szager - [python] Fixed bug 3447426: memory leak in vector.__getitem__. - -2011-11-30: wsfulton - [R] Remove C++ comments from generated C code. - -2011-11-27: olly - [Python] Fix some warnings when compiling generated wrappers with - certain GCC warning options (Debian bug #650246). - -2011-11-28: wsfulton - Fix #3433541 %typemap(in, numinputs=0) with 10+ arguments. - -2011-11-28: olly - [Perl] Fix warnings when compiling generated wrappers with certain - GCC warning options (Debian bug #436711). - -2011-11-28: olly - [PHP] Update keyword list to include keywords added in PHP releases up to 5.3. - -2011-11-25: wsfulton - [C#] Provide an easy way to override the default visibility for the proxy class pointer - constructors and getCPtr() method. The visibility is 'internal' by default and if multiple - SWIG modules are being used and compiled into different assemblies, then they need to be - 'public' in order to use the constructor or getCPtr() method from a different assembly. - Use the following macros to change the visibilities in the proxy and type wrapper class: - - SWIG_CSBODY_PROXY(public, public, SWIGTYPE) - SWIG_CSBODY_TYPEWRAPPER(public, public, public, SWIGTYPE) - - [Java] Provide an easy way to override the default visibility for the proxy class pointer - constructors and getCPtr() method. The visibility is 'protected' by default and if multiple - SWIG modules are being used and compiled into different packages, then they need to be - 'public' in order to use the constructor or getCPtr() method from a different package. - Use the following macros to change the visibilities in the proxy and type wrapper class: - - SWIG_JAVABODY_PROXY(public, public, SWIGTYPE) - SWIG_JAVABODY_TYPEWRAPPER(public, public, public, SWIGTYPE) - - The default for Java has changed from public to protected for the proxy classes. Use the - SWIG_JAVABODY_PROXY macro above to restore to the previous visibilities. - - *** POTENTIAL INCOMPATIBILITY *** - -2011-11-22: szager - [python] Bug 3440044: #ifdef out SWIG_Python_NonDynamicSetAttr if -builtin - isn't being used, to avoid unnecessary binary incompatibilities between - python installations. - -2011-11-17: wsfulton - Bug fix: Remove root directory from directory search list in Windows. - -2011-11-13: wsfulton - [Ruby] Apply patch #3421876 from Robin Stocker to fix #3416818 - same class name in - different namespaces confusion when using multiple modules. - -2011-11-11: wsfulton - Fix pcre-build.sh to work with non-compressed tarballs - problem reported by Adrian Blakely. - -2011-11-03: wsfulton - Expand special variables in typemap warnings, eg: - - %typemap(in, warning="1000:Test warning for 'in' typemap for $1_type $1_name") int "..." - -2011-11-01: wsfulton - Fix named output typemaps not being used when the symbol uses a qualifier and contains - a number, eg: - - %typemap(out) double ABC::m1 "..." - -2011-10-24: talby - [perl5] SF bug #3423119 - overload dispatch stack corruption fix. Better, but more research - is needed on a stable path for tail calls in XS. - - Also, fix for large long longs in 32 bit perl. - -2011-10-13: xavier98 - [octave] Allow Octave modules to be re-loaded after a "clear all". - -2011-09-19: wsfulton - Fix regression introduced in swig-2.0.1 reported by Teemu Ikonone leading to uncompilable code - when using typedef and function pointer references, for example: - - typedef int FN(const int &a, int b); - void *typedef_call1(FN *& precallback, FN * postcallback); - -2011-09-14: wsfulton - [Lua] Patch #3408012 from Raman Gopalan - add support for embedded Lua (eLua) - including options for targeting Lua Tiny RAM (LTR). - -2011-09-14: wsfulton - [C#] Add boost_intrusive_ptr.i library contribution from patch #3401571. - -2011-09-13: wsfulton - Add warnings for badly named destructors, eg: - - struct KStruct { - ~NOT_KStruct() {} - }; - - cpp_extend_destructors.i:92: Warning 521: Illegal destructor name ~NOT_KStruct. Ignored. - -2011-09-13: wsfulton - Fix %extend and destructors for templates. The destructor in %extend was not always wrapped, - for example: - - %extend FooT { - ~FooT() { delete $self; } // was not wrapped as expected - }; - template<class T> class FooT {}; - %template(FooTi) FooT<int>; - -2011-09-13: wsfulton - Fix special variables such as "$decl" and "$fulldecl" in destructors to include the ~ character. - -2011-09-10: talby - [perl5] SF bug #1481958 - Improve range checking for integer types. - Enhance li_typemaps_runme.pl - -2011-09-08: wsfulton - Fix %extend on typedef classes in a namespace using the typedef name, for example: - namespace Space { - %extend CStruct { - ... - } - typedef struct tagCStruct { ... } CStruct; - } - -2011-08-31: xavier98 - [octave] patches from Karl Wette: improvements to module loading behavior; - added example of friend operator to operator example; fixed octave panic/crash in 3.0.5; - documentation improvements - -2011-08-30: szager - [python] Bug 3400486, fix error signalling for built-in constructors. - -2011-08-26: wsfulton - [Go] Fix file/line number display for "gotype" when using typemap debugging options - -tmsearch and -tmused. - -2011-08-26: wsfulton - [C#, D] Fix %callback which was generating uncompilable code. - -2011-08-25: wsfulton - Fix constructors in named typedef class declarations as reported by Gregory Bronner: - - typedef struct A { - A(){} // Constructor which was not accepted by SWIG - B(){} // NOT a constructor --illegal, but was accepted by SWIG - } B; - - For C code, the fix now results in the use of 'struct A *' instead of just 'B *' in - the generated code when wrapping members in A, but ultimately this does not matter, as - they are the same thing. - -2011-08-23: wsfulton - Fix %newobject when used in conjunction with %feature("ref") as reported by Jan Becker. The - code from the "ref" feature was not always being generated for the function specified by %newobject. - Documentation for "ref" and "unref" moved from Python to the C++ chapter. - -2011-08-22: szager - [python] Fixed memory leak with --builtin option (bug 3385089). - -2011-08-22: wsfulton - [Lua] SF patch #3394339 from Torsten Landschoff - new option -nomoduleglobal to disable installing - the module table into the global namespace. Require call also returns the module table instead - of a string. - -2011-08-09: xavier98 - Fix bug 3387394; Octave patches for 3.4.0 compatibility, etc. (from Karl Wette) - -2011-08-04: wsfulton - Add in $symname expansion for director methods. - -2011-07-29: olly - [PHP] Don't generate "return $r;" in cases where $r hasn't been set. - This was basically harmless, except it generated a PHP E_NOTICE if - the calling code had enabled them. - -2011-07-26: wsfulton - Fix scoping of forward class declarations nested within a class (for C++). Previously the symbol - was incorrectly put into the outer namespace, eg - - namespace std { - template<class Key, class T> struct map { - class iterator; - }; - } - - iterator was scoped as std::iterator, but now it is correctly std::map<Key, T>::iterator; - - Also fixed is %template and template parameters that are a typedef when the template contains - default template parameters, eg: - - namespace Std { - template<class Key, class T, class C = int> struct Map { - typedef Key key_type; - typedef T mapped_type; - }; - } - typedef double DOUBLE; - %template(MM) Std::Map<int, DOUBLE>; - - All symbols within Map will be resolved correctly, eg key_type and mapped_type no matter if the - wrapped code uses Std::Map<int, double> or std::Map<int, DOUBLE> or Std::Map<int, double, int> - - Also fixes bug #3378145 - regression introduced in 2.0.4 - %template using traits. - -2011-07-20 szager - [python] Fix closure for tp_call slot. - -2011-07-16: wsfulton - [python] Fix director typemap using PyObject *. - -2011-07-13: szager - [python] SF patch #3365908 - Add all template parameters to map support code in std_map.i - -2011-07-13: szager - [python] Fix for bug 3324753: %rename member variables with -builtin. - -2011-07-01: wsfulton - Fix some scope and symbol lookup problems when template default parameters are being - used with typedef. For example: - - template<typename XX, typename TT = SomeType> struct Foo { - typedef XX X; - typedef TT T; - }; - template<typename TT> struct UsesFoo { - void x(typename Foo<TT>::T, typename Foo<TT>::X); - }; - - Also fixes use of std::vector<int>::size_type for Python as reported by Aubrey Barnard. - -2011-06-23: olly - [PHP] Fix director code to work when PHP is built with ZTS enabled, - which is the standard configuration on Microsoft Windows. - -2011-06-21: mutandiz - [allegrocl] - - various small tweaks and bug fixes. - - Avoid name conflicts between smart pointer wrappers and the wrappers for - the actual class. - - Fix default typemaps for C bindings, which were incorrectly attempting to - call non-existent destructors on user-defined types. - - New feature, feature:aclmixins, for adding superclass to the foreign class - wrappers. - - Improve longlong typemaps. - -2011-06-19: wsfulton - Fix incorrect typemaps being used for a symbol within a templated type, eg: - A<int>::value_type would incorrectly use a typemap for type A. - -2011-06-18: olly - [Tcl] Fix variable declarations in middle of blocks which isn't - permitted in C90 (issue probably introduced in 2.0.3 by patch #3224663). - Reported by Paul Obermeier in SF#3288586. - -2011-06-17: wsfulton - [Java] SF #3312505 - slightly easier to wrap char[] or char[ANY] with a Java byte[] - using arrays_java.i. - -2011-06-13: wsfulton - [Ruby, Octave] SF #3310528 Autodoc fixes similar to those described below for Python. - -2011-06-10: wsfulton - [Python] Few subtle bugfixes in autodoc documentation generation, - - Unnamed argument names fix for autodoc levels > 0. - - Display of template types fixed for autodoc levels > 1. - - Fix SF #3310528 - display of typedef structs for autodoc levels > 1. - - Add missing type for self for autodoc levels 1 and 3. - - autodoc levels 2 and 3 documented. - - Minor tweaks to autodoc style to conform with PEP8. - -2011-05-30: olly - [PHP] Fix handling of directors when -prefix is used. - -2011-05-24: olly - [PHP] Fix handling of methods of classes with a virtual base class (SF#3124665). - -Version 2.0.4 (21 May 2011) -=========================== - -2011-05-19: wsfulton - [Guile] Patch #3191625 fixing overloading of integer types. - -2011-05-19: wsfulton - [Perl] Patch #3260265 fixing overloading of non-primitive types and integers in - Perl 5.12 and later. - -2011-05-19: wsfulton - [Ruby] Fix %import where one of the imported files %include one of the STL include - files such as std_vector.i. - -2011-05-17: wsfulton - [Java] Apply #3289851 from Alan Harder to fix memory leak in directors when checking - for pending exceptions. - -2011-05-17: wsfulton - [Tcl] Apply #3300072 from Christian Delbaere to fix multiple module loading not - always sharing variables across modules. - -2011-05-16: xavier98 - [octave] Fix an incompatibility with never versions of Octave. Case on Octave - API >= 40 to handle rename of Octave_map to octave_map. - [octave] Add support for y.__rop__(x) operators when x.__op__(y) doesn't exist. - [octave] Allow global operators to be defined by SWIG-wrapped functions. - [octave] Fix several bugs around module namespaces; add -global, -noglobal, - -globals <name> command line options to the module. - -2011-05-14: wsfulton - %varargs when used with a numeric argument used to create an additional argument - which was intended to provide a guaranteed sentinel value. This never worked and now - the additional argument is not generated. - -2011-05-13: wsfulton - [python] Additional fixes for python3.2 support. - -2011-05-07: szager - [python] Fixed PyGetSetDescr for python3.2. - -2011-05-05: wsfulton - [Lua, Python, Tcl] C/C++ prototypes shown in error message when calling an overloaded - method with incorrect arguments improved to show always show fully qualified name - and if a const method. - - Also fixed other Lua error messages in generated code which weren't consistently - using the fully qualified C++ name - requested by Gedalia Pasternak. - -2011-04-29: szager - Bug 2635919: Convenience method to convert std::map to a python dict. - -2011-04-29: szager - [Python] Fixed bug 2811549: return non-const iterators from STL - methods begin(), end(), rbegin(), rend(). - -2011-04-25: szager - [Python] Fixed bug 1498929: Access to member fields in map elements - -2011-04-23: klickverbot - [D] nspace: Correctly generate identifiers for base classes when - not in split proxy mode. - -2011-04-13: szager - Fixed bug 3286333: infinite recursion with mutual 'using namespace' clauses. - -2011-04-12: szager - Fixed bug 1163440: vararg typemaps. - -2011-04-12: szager - Fixed bug #3285386: parse error from 'operator T*&()'. Added operator_pointer_ref - test case to demonstrate. - -2011-04-11: szager - [Python] Fixed PyVarObject_HEAD_INIT to eliminate VC++ compiler errors about - static initialization of struct members with pointers. - -2011-04-11: wsfulton - [Tcl] Apply patch #3284326 from Colin McDonald to fix some compiler warnings. - -2011-04-11: szager - [Python] Fixed PyVarObject_HEAD_INIT to eliminate VC++ compiler errors about - static initialization of struct members with pointers. - -2011-04-10: klickverbot - [D] Fixed wrapping of enums that are type char, for example: - enum { X = 'X'; } (this was already in 2.0.3 for C# and Java) - -2011-04-10: klickverbot - [D] nspace: Fixed referencing types in the root namespace when - not in split proxy mode. - -2011-04-09: szager - [Python] Applied patch #1932484: migrate PyCObject to PyCapsule. - -2011-04-09: szager - [Python] Added preprocessor guards for python functions PyUnicode_AsWideChar and - PySlice_GetIndices, which changed signatures in python3.2. - -2011-04-07: wsfulton - Fix wrapping of const array typedefs which were generating uncompilable code as - reported by Karl Wette. - -2011-04-03: szager - [Python] Fixed the behavior of %pythonnondynamic to conform to the spec in Lib/pyuserdir.swg. - -2011-04-03: szager - [Python] Merged in the szager-python-builtin branch, adding the -builtin feature - for python. The -builtin option may provide a significant performance gain - in python wrappers. For full details and limitations, refer to Doc/Manual/Python.html. - A small test suite designed to demonstrate the performance gain is in - Examples/python/performance. - -2011-04-01: wsfulton - Add in missing wrappers for friend functions for some target languages, mostly - the non-scripting languages like Java and C#. - -Version 2.0.3 (29 March 2011) -============================= - -2011-03-29: wsfulton - [R] Apply patch #3239076 from Marie White fixing strings for R >= 2.7.0 - -2011-03-29: wsfulton - [Tcl] Apply patch #3248280 from Christian Delbaere which adds better error messages when - the incorrect number or type of arguments are passed to overloaded methods. - -2011-03-29: wsfulton - [Tcl] Apply patch #3224663 from Christian Delbaere. - 1. Fix when function returns a NULL value, a "NULL" command will be created in the Tcl interpreter - and calling this command will cause a segmentation fault. - - 2. Previous implementation searches for class methods using a linear search causing performance issues - in wrappers for classes with many member functions. The patch adds a method hash table to classes and - changes method name lookup to use the hash table instead of doing a linear search. - -2011-03-26: wsfulton - [C#, Java] SF bug #3195112 - fix wrapping of enums that are type char, for example: - enum { X = 'X'; } - -2011-03-21: vadz - Allow setting PCRE_CFLAGS and PCRE_LIBS during configuration to override the values returned by - pcre-config, e.g. to allow using a static version of PCRE library. - -2011-03-17: wsfulton - [UTL] Add missing headers in generated STL wrappers to fix compilation with gcc-4.6. - -2011-03-17: wsfulton - Fix regression introduced in swig-2.0.2 where filenames with spaces were not found - when used with %include and %import. Reported by Shane Liesegang. - -2011-03-15: wsfulton - [UTL] Fix overloading when using const char[], problem reported by David Maxwell. - Similarly for char[ANY] and const char[ANY]. - -2011-03-15: wsfulton - [C#] Apply patch #3212624 fixing std::map Keys property. - -2011-03-14: olly - [PHP] Fix handling of overloaded methods/functions where some - return void and others don't - whether this worked or not depended - on the order they were encountered in (SF#3208299). - -2011-03-13: klickverbot - [D] Extended support for C++ namespaces (nspace feature). - -2011-03-12: olly - [PHP] Fix sharing of type information between multiple SWIG-wrapped - modules (SF#3202463). - -2011-03-09: wsfulton - [Python] Fix SF #3194294 - corner case bug when 'NULL' is used as the default value - for a primitive type parameter in a method declaration. - -2011-03-07: olly - [PHP] Don't use zend_error_noreturn() for cases where the function - returns void - now this issue can only matter if you have a function - or method which is directed and returns non-void. - -2011-03-06: olly - [PHP] Add casts to the typemaps for long long and unsigned long - long to avoid issues when they are used with shorter types via - %apply. - -2011-03-02: wsfulton - Templated smart pointers overloaded with both const and non const operator-> generated uncompilable - code when the pointee was a class with either public member variables or static methods. - Regression in 2.0.x reported as working in 1.3.40 by xantares on swig-user mailing list. - -Version 2.0.2 (20 February 2011) -================================ - -2011-02-19: wsfulton - [PHP] Add missing INPUT, OUTPUT and INOUT typemaps in the typemaps.i library - for primitive reference types as well as signed char * and bool *. - -2011-02-19: olly - [PHP] Address bug in PHP on some platforms/architectures which - results in zend_error_noreturn() not being available using - SWIG_ZEND_ERROR_NORETURN which defaults to zend_error_noreturn but - can be overridden when building the module by passing - -DSWIG_ZEND_ERROR_NORETURN=zend_error to the compiler. This may - result in compiler warnings, but should at least allow a module - to be built on those platforms/architectures (SF#3166423). - -2011-02-18: wsfulton - Fix #3184549 - vararg functions and function overloading when using the -fastdispatch option. - -2011-02-18: olly - [PHP] An overloaded method which can return an object or a - primitive type no longer causes SWIG to segfault. Reported by Paul - Colby in SF#3168531. - -2011-02-18: olly - [PHP] Fix invalid erase during iteration of std::map in generated - director code. Reported by Cory Bennett in SF#3175820. - -2011-02-17: wsfulton - Preprocessing now warns if extra tokens appear after #else and #end. - -2011-02-16: wsfulton - Fix #1653092 Preprocessor does not error out when #elif is missing an expression. - This and other cases of missing preprocessor expressions now result in an error. - -2011-02-14: wsfulton - [Ocaml] Apply patch #3151788 from Joel Reymont. Brings Ocaml support up to date - (ver 3.11 and 3.12), including std::string. - -2011-02-13: wsfulton - [Ruby] Apply patch #3176274 from James Masters - typecheck typemap for time_t. - -2011-02-13: wsfulton - Apply patch #3171793 from szager - protected director methods failing when -fvirtual is used. - -2011-02-13: wsfulton - Fix #1927852 - #include directives don't preprocess the file passed to it. The fix is for - #include with -importall or -includeall, %include and %import, for example: - #define FILENAME "abc.h" - %include FILENAME - -2011-02-12: wsfulton - Fix #1940536, overactive preprocessor which was expanding defined(...) outside of #if and #elif - preprocessor directives. - -2011-02-05: wsfulton - [MzScheme] SF #2942899 Add user supplied documentation to help getting started with MzScheme. - Update chapter name to MzScheme/Racket accounting for the rename of MzScheme to Racket. - -2011-02-05: wsfulton - [C#] SF #3085906 - Possible fix running test-suite on Mac OS X. - -2011-02-05: wsfulton - SF #3173367 Better information during configure about Boost prerequisite for running - the test-suite. - -2011-02-05: wsfulton - SF #3127633 Fix infinite loop in recursive typedef resolution. - -2011-02-04: wsfulton - [R] SF #3168676 Fix %rename not working for member variables and methods. - -2011-02-04: wsfulton - [clisp] SF #3148200 Fix segfault parsing nested unions. - -2011-02-01: wsfulton - [C#] Directors - a call to a method being defined in the base class, not - overridden in a subclass, but again overridden in a class derived from - the first subclass was not being dispatched correctly to the most derived class. - See director_alternating.i for an example. - -2011-02-01: wsfulton - [C#, Java] Any 'using' statements in the protected section of a class were previously - ignored with director protected (dirprot) mode. - -2011-01-30: wsfulton - Fix overloading with const pointer reference (SWIGTYPE *const&) parameters for a - number of scripting languages. - -2011-01-17: wsfulton - New warning for smart pointers if only some of the classes in the inheritance - chain are marked as smart pointer, eg, %shared_ptr should be used for all classes - in an inheritance hierarchy, so this new warning highlights code where this is - not the case. - - example.i:12: Warning 520: Base class 'A' of 'B' is not similarly marked as a smart pointer. - example.i:16: Warning 520: Derived class 'C' of 'B' is not similarly marked as a smart pointer. - -2011-01-14: wsfulton - Added some missing multi-argument typemaps: (char *STRING, size_t LENGTH) and - (char *STRING, int LENGTH). Documentation for this updated. Java patch from - Volker Grabsch. - -2011-01-11: iant - Require Go version 7077 or later. - -2010-12-30: klickverbot - [C#, D, Java] Check for collision of parameter names with target - language keywords when generating the director glue code. - - The situation in which the generated could would previously be - invalid is illustrated in the new 'director_keywords' test case. - -2010-12-23: wsfulton - [C#] Fix $csinput special variable not being expanded for csvarin typemaps - when used for global variables. Reported by Vadim Zeitlin. - -2010-12-14: wsfulton - Fix $basemangle expansion in array typemaps. For example if type is int *[3], - $basemangle expands to _p_int. - -2010-12-07: iant - Check that we are using a sufficiently new version of the - 6g or 8g Go compiler during configure time. If not, disable Go. - Minimum version is now 6707. - - *** POTENTIAL INCOMPATIBILITY *** - -2010-12-06: wsfulton - Fix #3127394 - use of network paths on Windows/MSys. - -2010-11-18: klickverbot - [D] Added the D language module. - -2010-11-12: vadz - Fix handling of multiple regex-using %renames attached to the same - declaration. For example, now - - %rename("%(regex:/^Set(.*)/put\\1/)s") ""; - %rename("%(regex:/^Get(.*)/get\\1/)s") ""; - - works as expected whereas before only the last anonymous rename was - taken into account. - -2010-10-17: drjoe - [R] Fix failure in overloaded functions which was breaking - QuantLib-SWIG - -2010-10-14: olly - [PHP] Allow compilation on non-conforming Microsoft C++ compilers - which don't accept: return function_returning_void(); - Reported by Frank Vanden Berghen on the SWIG mailing list. - -2010-10-12: wsfulton - Fix unary scope operator (::) (global scope) regression introduced in 2.0.0, reported by - Ben Walker. The mangled symbol names were incorrect, sometimes resulting in types being - incorrectly treated as opaque types. - - Also fixes #2958781 and some other type problems due to better typedef resolution, eg - std::vector<T *>::value_type didn't resolve to T * when it should have. The mangled type - was incorrectly SWIGTYPE_std__vectorT_Test_p_std__allocatorT_Test_p_t_t__value_type and now - it is correctly SWIGTYPE_p_Test. - -Version 2.0.1 (4 October 2010) -============================== - -2010-10-03: wsfulton - Apply patch #3066958 from Mikael Johansson to fix default smart pointer - handling when the smart pointer contains both a const and non-const operator->. - -2010-10-01: wsfulton - Add -pcreversion option to display PCRE version information. - -2010-10-01: olly - [Ruby] Avoid segfault when a method node has no parentNode - (SF#3034054). - -2010-10-01: olly - [Python] Allow reinitialisation to work with an embedded Python - interpreter (patch from Jim Carroll in SF#3075178). - -2010-09-28: wsfulton - [C#] Apply patch from Tomas Dirvanauskas for std::map wrappers to avoid - throwing exceptions with normal usage of iterators. - -2010-09-27: olly - [Python] Improve error message given when a parameter of the wrong - type is passed to an overloaded method (SF#3027355). - -2010-09-25: wsfulton - Apply SF patch #3075150 - Java directors using static variables in - named namespace. - -2010-09-24: wsfulton - More file and line error/warning reporting fixes where SWIG macros - are used within {} braces (where the preprocessor expands macros), - for example macros within %inline {...} and %fragment(...) {...} - and nested structs. - -2010-09-18: wsfulton - More file and line error/warning reporting fixes for various inherited - class problems. - -2010-09-15: wsfulton - A much improved debugging of SWIG source experience is now available and - documented in the "Debugging SWIG" section in the Doc/Devel/internals.html - file, including a swig.dbg support file for the gdb debugger. - -2010-09-11: wsfulton - Fix incorrect line number reporting in errors/warnings when a macro - definition ends with '/' and it is not the end of a C comment. - -2010-09-11: wsfulton - Fix incorrect line number reporting in errors/warnings after parsing - macro invocations with parameters given over more than one line. - -2010-09-10: wsfulton - Remove extraneous extra line in preprocessed output after including files - which would sometimes lead to error/warning messages two lines after the - end of the file. - -2010-09-10: wsfulton - Fix #2149523 - Incorrect line number reporting in errors after parsing macros - containing C++ comments. - -2010-09-08: olly - [PHP] Fix handling of OUTPUT typemaps (Patch from Ryan in SF#3058394). - -2010-09-03: wsfulton - Fix erroneous line numbers in error messages for macro expansions, for example, - the error message now points to instantiation of the macro, ie the last line here: - - #define MACRO2(a, b) - - #define MACRO1(NAME) MACRO2(NAME,2,3) - - MACRO1(abc) - -2010-09-02: wsfulton - Fix line numbers in error and warning messages for preprocessor messages within - %inline, for example: - - %inline %{ - #define FOOBAR 1 - #define FOOBAR "hi" - %} - -2010-09-02: wsfulton - Fix line numbers in error and warning messages which were cumulatively one - less than they should have been after parsing each %include/%import - bug - introduced in swig-1.3.32. Also fix line numbers in error and warning messages - when new line characters appear between the %include / %import statement and - the filename. - -2010-08-30: wsfulton - Fix line number and file name reporting for some macro preprocessor warnings. - The line number of the macro argument has been corrected and the line number - of the start of the macro instead of one past the end of the macro is used. - Some examples: - file.h:11: Error: Illegal macro argument name '..' - file.h:19: Error: Macro 'DUPLICATE' redefined, - file.h:15: Error: previous definition of 'DUPLICATE'. - file.h:25: Error: Variable-length macro argument must be last parameter - file.h:32: Error: Illegal character in macro argument name - file.i:37: Error: Macro 'SIT' expects 2 arguments - -2010-08-26: wsfulton - Fix __LINE__ and __FILE__ expansion reported by Camille Gillot. Mostly this - did not work at all. Also fixes SF #2822822. - -2010-08-17: wsfulton - [Perl] Fix corner case marshalling of doubles - errno was not being correctly - set before calling strtod - patch from Justin Vallon - SF Bug #3038936. - -2010-08-17: wsfulton - Fix make distclean when some of the more obscure languages are detected by - configure - fixes from Torsten Landschoff. - -2010-07-28: wsfulton - Restore configuring out of source for the test-suite since it broke in 1.3.37. - As previously, if running 'make check-test-suite' out of source, it needs to be - done by invoking configure with a relative path. Invoking configure with an - absolute path will not work. Running the full 'make check' still needs to be - done in the source tree. - -2010-07-16: wsfulton - Fix wrapping of function pointers and member function pointers when the function - returns by reference. - -2010-07-13: vadz - Removed support for the old experimental "rxspencer" encoder and - "[not]rxsmatch" in %rename (see the 01/16/2006 entry). The new and - officially supported "regex" encoder and "[not]regexmatch" checks - should be used instead (see the two previous entries). Please - replace "%(rxspencer:[pat][subst])s" with "%(regex:/pat/subst/)s" - when upgrading. Notice that you will also need to replace the back- - references of form "@1" with the more standard "\\1" and may need to - adjust your regular expressions syntax as the new regex encoder uses - Perl-compatible syntax and not (extended) POSIX syntax as the old one. - - *** POTENTIAL INCOMPATIBILITY *** - -2010-07-13: vadz - Add "regexmatch", "regextarget" and "notregexmatch" which can be - used to apply %rename directives to the declarations matching the - specified regular expression only. The first two can be used - interchangeably, both of the %renames below do the same thing: - - %rename("$ignore", regexmatch$name="Old$") ""; - %rename("$ignore", regextarget=1) "Old$"; - - (namely ignore the declarations having "Old" suffix). - - "notregexmatch" restricts the match to only the declarations which - do not match the regular expression, e.g. here is how to rename to - lower case versions all declarations except those consisting from - capital letters only: - - %rename("$(lowercase)s", notregexmatch$name="^[A-Z]+$") ""; - -2010-07-13: vadz - Add the new "regex" encoder that can be used in %rename, e.g. - - %rename("regex:/(\\w+)_(.*)/\\2/") ""; - - to remove any alphabetical prefix from all identifiers. The syntax - of the regular expressions is Perl-like and PCRE library - (http://www.pcre.org/) is used to implement this feature but notice - that backslashes need to be escaped as usual inside C strings. - - Original patch from Torsten Landschoff. - -2010-07-08: wsfulton - Fix #3024875 - shared_ptr of classes with non-public destructors. This also fixes - the "unref" feature when used on classes with non-public destructors. - -2010-06-17: ianlancetaylor - [Go] Add the Go language module. - -2010-06-10: wsfulton - [Lua] Fix SWIG_lua_isnilstring multiply defined when using multiple - modules and wrapping strings. Patch from 'Number Cruncher'. - -2010-06-10: olly - [PHP] Fix directors to correctly call a method with has a - different name in PHP to C++ (we were always using the C++ name - in this case). - -2010-06-03: wsfulton - Fix uncompilable code when %rename results in two enum items - with the same name. Reported by Vadim Zeitlin. - -Version 2.0.0 (2 June 2010) -=========================== - -2010-06-02: wsfulton - [C#] Fix SWIG_STD_VECTOR_ENHANCED macro used in std::vector to work with - types containing commas, for example: - - SWIG_STD_VECTOR_ENHANCED(std::pair< double, std::string >) - -2010-06-01: wsfulton - Add in std_shared_ptr.i for wrapping std::shared_ptr. Requires the %shared_ptr - macro like in the boost_shared_ptr.i library. std::tr1::shared_ptr can also be - wrapped if the following macro is defined: - - #define SWIG_SHARED_PTR_SUBNAMESPACE tr1 - %include <std_shared_ptr.i> - - shared_ptr is also documented in Library.html now. - -2010-05-27: wsfulton - Add the ability for $typemap special variable macros to call other $typemap - special variable macros, for example: - - %typemap(cstype) CC "CC" - %typemap(cstype) BB "$typemap(cstype, CC)" - %typemap(cstype) AA "$typemap(cstype, BB)" - void hah(AA aa); - - This also fixes C# std::vector containers of shared_ptr and %shared_ptr. - - Also added diagnostics for $typemap with -debug-tmsearch, for example, the - above displays additional diagnostic lines starting "Containing: ": - - example.i:34: Searching for a suitable 'cstype' typemap for: AA aa - Looking for: AA aa - Looking for: AA - Using: %typemap(cstype) AA - Containing: $typemap(cstype, BB) - example.i:31: Searching for a suitable 'cstype' typemap for: BB - Looking for: BB - Using: %typemap(cstype) BB - Containing: $typemap(cstype, CC) - example.i:29: Searching for a suitable 'cstype' typemap for: CC - Looking for: CC - Using: %typemap(cstype) CC - -2010-05-26: olly - Fix %attribute2ref not to produce a syntax error if the last - argument (AccessorMethod) is omitted. Patch from David Piepgras - in SF#2235756. - -2010-05-26: olly - [PHP] When using %throws or %catches, SWIG-generated PHP5 wrappers - now throw PHP Exception objects instead of giving a PHP error of - type E_ERROR. - - This change shouldn't cause incompatibility issues, since you can't - set an error handler for E_ERROR, so previously PHP would just exit - which also happens for unhandled exceptions. The benefit is you can - now catch them if you want to. - - Fixes SF#2545578 and SF#2955522. - -2010-05-25: olly - [PHP] Add missing directorin typemap for const std::string &. - Fixes SF#3006404 reported by t-Legiaw. - -2010-05-23: wsfulton - [C#] Fix #2957375 - SWIGStringHelper and SWIGExceptionHelper not always being - initialized before use in .NET 4 as the classes were not marked beforefieldinit. - A static constructor has been added to the intermediary class like this: - - %pragma(csharp) imclasscode=%{ - static $imclassname() { - } - %} - - If you had added your own custom static constructor to the intermediary class in - the same way as above, you will have to modify your approach to use static variable - initialization or define SWIG_CSHARP_NO_IMCLASS_STATIC_CONSTRUCTOR - See csharphead.swg. - - *** POTENTIAL INCOMPATIBILITY *** - -2010-05-23: wsfulton - Fix #2408232. Improve shared_ptr and intrusive_ptr wrappers for classes in an - inheritance hierarchy. No special treatment is needed for derived classes. - The proxy class also no longer needs to be specified, it is automatically - deduced. The following macros are deprecated: - SWIG_SHARED_PTR(PROXYCLASS, TYPE) - SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE) - and have been replaced by - %shared_ptr(TYPE) - Similarly for intrusive_ptr wrappers, the following macro is deprecated: - SWIG_INTRUSIVE_PTR(PROXYCLASS, TYPE) - SWIG_INTRUSIVE_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE) - and have been replaced by - %intrusive_ptr(TYPE) - -2010-05-21: olly - [PHP] Stop generating a bogus line of code in certain constructors. - This was mostly harmless, but caused a PHP notice to be issued, if - enabled (SF#2985684). - -2010-05-18: wsfulton - [Java] Fix member pointers on 64 bit platforms. - -2010-05-14: wsfulton - Fix wrapping of C++ enum boolean values reported by Torsten Landschoff: - typedef enum { PLAY = true, STOP = false } play_state; - -2010-05-14: olly - [PHP] Fix wrapping of global variables which was producing - uncompilable code in some cases. - -2010-05-12: drjoe - [R] Add two more changes from Wil Nolan. Get garbage - collection to work. Implement newfree - -2010-05-09: drjoe - Fix bug reported by Wil Nolan change creation of string so - that R 2.7.0+ can use char hashes - -2010-05-07: wsfulton - Apply patch #2955146 from Sergey Satskiy to fix expressions containing divide by - operator in constructor initialization lists. - -2010-05-05: wsfulton - [R] Memory leak fix handling const std::string & inputs, reported by Will Nolan. - -2010-05-01: wsfulton - Typemap matching enhancement for non-default typemaps. Previously all - qualifiers were stripped in one step, now they are stripped one at a time - starting with the left most qualifier. For example, int const*const - is first stripped to int *const then int *. - - *** POTENTIAL INCOMPATIBILITY *** - -2010-04-25: bhy - [Python] Fix #2985655 - broken constructor renaming. - -2010-04-14: wsfulton - Typemap fragments are now official and documented in Typemaps.html. - -2010-04-09: wsfulton - [Ruby] Fix #2048064 and #2408020. - Apply Ubuntu patch to fix Ruby and std::vector wrappers with -minherit. - https://bugs.launchpad.net/ubuntu/+source/swig1.3/+bug/522874 - -2010-04-09: wsfulton - [Mzscheme] Apply Ubuntu patch to fix std::map wrappers: - https://bugs.launchpad.net/ubuntu/+source/swig1.3/+bug/203876 - -2010-04-09: wsfulton - [Python] Apply patch #2952374 - fix directors and the -nortti option. - -2010-04-09: wsfulton - [Lua] Fix #2887254 and #2946032 - SWIG_Lua_typename using wrong stack index. - -2010-04-03: wsfulton - [Python] Fix exceptions being thrown with the -threads option based on patch from Arto Vuori. - Fixes bug #2818499. - -2010-04-03: wsfulton - Fix Makefile targets: distclean and maintainer-clean - -2010-04-02: wsfulton - [Lua] Fix char pointers, wchar_t pointers and char arrays so that nil can be passed as a - valid value. Bug reported by Gedalia Pasternak. - -2010-04-01: wsfulton - Numerous subtle typemap matching rule fixes when using the default type. The typemap - matching rules are to take a type and find the best default typemap (SWIGTYPE, SWIGTYPE* etc), - then look for the next best match by reducing the chosen default type. The type deduction - now follows C++ class template partial specialization matching rules. - - Below are the set of changes made showing the default type deduction - along with the old reduced type and the new version of the reduced type: - - SWIGTYPE const &[ANY] - new: SWIGTYPE const &[] - old: SWIGTYPE (&)[ANY] - - SWIGTYPE *const [ANY] - new: SWIGTYPE const [ANY] - old: SWIGTYPE *[ANY] - - SWIGTYPE const *const [ANY] - new: SWIGTYPE *const [ANY] - old: SWIGTYPE const *[ANY] - - SWIGTYPE const *const & - new: SWIGTYPE *const & - old: SWIGTYPE const *& - - SWIGTYPE *const * - new: SWIGTYPE const * - old: SWIGTYPE ** - - SWIGTYPE *const & - new: SWIGTYPE const & - old: SWIGTYPE *& - - Additionally, a const SWIGTYPE lookup is used now for any constant type. Some examples, where - T is some reduced type, eg int, struct Foo: - - T const - new: SWIGTYPE const - old: SWIGTYPE - - T *const - new: SWIGTYPE *const - old: SWIGTYPE * - - T const[] - new: SWIGTYPE const[] - old: SWIGTYPE[] - - enum T const - new: enum SWIGTYPE const - old: enum SWIGTYPE - - T (*const )[] - new: SWIGTYPE (*const )[] - old: SWIGTYPE (*)[] - - Reminder: the typemap matching rules can now be seen for any types being wrapped by using - either the -debug-tmsearch or -debug-tmused options. - - In practice this leads to some subtle matching rule changes and the majority of users - won't notice any changes, except in the prime area of motivation for this change: Improve - STL containers of const pointers and passing const pointers by reference. This is fixed - because many of the STL containers use a type 'T const&' as parameters and when T is - a const pointer, for example, 'K const*', then the full type is 'K const*const&'. This - means that the 'SWIGTYPE *const&' typemaps now match when T is either a non-const or - const pointer. Furthermore, some target languages incorrectly had 'SWIGTYPE *&' typemaps - when these should have been 'SWIGTYPE *const&'. These have been corrected (Java, C#, Lua, PHP). - - *** POTENTIAL INCOMPATIBILITY *** - -2010-03-13: wsfulton - [Java] Some very old deprecated pragma warnings are now errors. - -2010-03-13: wsfulton - Improve handling of file names and directories containing double/multiple path separators. - -2010-03-10: mutandiz (Mikel Bancroft) - [allegrocl] Use fully qualified symbol name of cl::identity in emit_defun(). - -2010-03-06: wsfulton - [Java] The intermediary JNI class modifiers are now public by default meaning these - intermediary low level functions are now accessible by default from outside any package - used. The proxy class pointer constructor and getCPtr() methods are also now public. - These are needed in order for the nspace option to work without any other mods. - The previous default of protected access can be restored using: - - SWIG_JAVABODY_METHODS(protected, protected, SWIGTYPE) - %pragma(java) jniclassclassmodifiers = "class" - -2010-03-06: wsfulton - [C#] Added the nspace feature for C#. Documentation for the nspace feature is now available. - -2010-03-04: wsfulton - Added the nspace feature. This adds some improved namespace support. Currently only Java - is supported for target languages, where C++ namespaces are automatically translated into - Java packages. The feature only applies to classes,struct,unions and enums declared within - a namespace. Methods and variables declared in namespaces still effectively have their - namespaces flattened. Example usage: - - %feature(nspace) Outer::Inner1::Color; - %feature(nspace) Outer::Inner2::Color; - - namespace Outer { - namespace Inner1 { - struct Color { - ... - }; - } - namespace Inner2 { - struct Color { - ... - }; - } - } - - For Java, the -package option is also required when using the nspace feature. Say - we use -package com.myco, the two classes can then be accessed as follows from Java: - - com.myco.Outer.Inner1.Color and com.myco.Outer.Inner2.Color. - -2010-02-27: wsfulton - [Python] Remove -dirvtable from the optimizations included by -O as it this option - currently leads to memory leaks as reported by Johan Blake. - -2010-02-27: wsfulton - License code changes: SWIG Source is GPL-v3 and library code license is now clearer - and is provided under a very permissive license. See https://www.swig.org/legal.html. - -2010-02-13: wsfulton - [Ruby] A few fixes for compiling under ruby-1.9.x including patch from 'Nibble'. - -2010-02-13: wsfulton - [Ruby] Apply patch from Patrick Bennett to fix RARRAY_LEN and RARRAY_PTR usage for Ruby 1.9.x - used in various STL wrappers. - -2010-02-13: wsfulton - [C#, Java] Fix incorrect multiply defined symbol name error when an enum item - and class name have the same name, as reported by Nathan Krieger. Example: - - class Vector {}; - namespace Text { - enum Preference { Vector }; - } - - This also fixes other incorrect corner case target language symbol name clashes. - -2010-02-11: wsfulton - Add the -debug-lsymbols option for displaying the target language layer symbols. - -2010-02-09: wsfulton - Fix -MM and -MMD options on Windows. They were not omitting files in the SWIG library as - they should be. - -2010-02-08: wsfulton - Fix #1807329 - When Makefile dependencies are being generated using the -M family of options - on Windows, the file paths have been corrected to use single backslashes rather than double - backslashes as path separators. - -2010-02-06: wsfulton - Fix #2918902 - language specific files not being generated in correct directory on - Windows when using forward slashes for -o, for example: - swig -python -c++ -o subdirectory/theinterface_wrap.cpp subdirectory/theinterface.i - -2010-02-05: wsfulton - Fix #2894405 - assertion when using -xmlout. - -2010-01-28: wsfulton - Fix typemap matching bug when a templated type has a typemap both specialized and not - specialized. For example: - - template<typename T> struct XX { ... }; - %typemap(in) const XX & "..." - %typemap(in) const XX< int > & "..." - - resulted in the 2nd typemap being applied for all T in XX< T >. - -2010-01-22: wsfulton - Fix #2933129 - typemaps not being found when the unary scope operator (::) is used to denote - global scope, the typemap is now used in situations like this: - - struct X {}; - %typemap(in) const X & "..." - void m(const ::X &); - - and this: - - struct X {}; - %typemap(in) const ::X & "..." - void m(const X &); - -2010-01-20: wsfulton - Fix some unary scope operator (::) denoting global scope problems in the types generated - into the C++ layer. Previously the unary scope operator was dropped in the generated code - if the type had any sort of qualifier, for example when using pointers, references, like - ::foo*, ::foo&, bar< ::foo* >. - -2010-01-13: olly - [PHP] Add datetime to the list of PHP predefined classes (patch - from David Fletcher in SF#2931042). - -2010-01-11: wsfulton - Slight change to warning, error and diagnostic reporting. The warning number is no - longer shown within brackets. This is to help default parsing of warning messages by - other tools, vim on Unix in particular. - - Example original display using -Fstandard: - example.i:20: Warning(401): Nothing known about base class 'B'. Ignored. - New display: - example.i:20: Warning 401: Nothing known about base class 'B'. Ignored. - - Also subtle fix to -Fmicrosoft format adding in missing space. Example original display: - example.i(20): Warning(401): Nothing known about base class 'Base'. Ignored. - New display: - example.i(20) : Warning 401: Nothing known about base class 'Base'. Ignored. - -2010-01-10: wsfulton - Fix a few inconsistencies in reporting of file/line numberings including modifying - the overload warnings 509, 512, 516, 474, 475 to now be two line warnings. - -2010-01-10: wsfulton - Modify -debug-tags output to use standard file name/line reporting so that editors - can easily navigate to the appropriate lines. - Was typically: - . top . include . include (/usr/share/swig/temp/trunk/Lib/swig.swg:312) - . top . include . include . include (/usr/share/swig/temp/trunk/Lib/swigwarnings.swg:39) - now: - /usr/share/swig/temp/trunk/Lib/swig.swg:312: . top . include . include - /usr/share/swig/temp/trunk/Lib/swigwarnings.swg:39: . top . include . include . include - -2010-01-03: wsfulton - Fix missing file/line numbers for typemap warnings and in output from the - -debug-tmsearch/-debug-tmused options. - -2010-01-03: wsfulton - Add typemaps used debugging option (-debug-tmused). When used each line displays - the typemap used for each type for which code is being generated including the file - and line number related to the type. This is effectively a condensed form of the - -debug-tmsearch option. Documented in Typemaps.html. - -2009-12-23: wsfulton - Fix for %javaexception and directors so that all the appropriate throws clauses - are generated. Problem reported by Peter Greenwood. - -2009-12-20: wsfulton - Add -debug-tmsearch option for debugging the typemap pattern matching rules. - Documented in Typemaps.html. - -2009-12-12: wsfulton - [Octave] Remove the -api option and use the new OCTAVE_API_VERSION_NUMBER - macro provided in the octave headers for determining the api version instead. - -2009-12-04: olly - [Ruby] Improve support for Ruby 1.9 under GCC. Addresses part of - SF#2859614. - -2009-12-04: olly - Fix handling of modulo operator (%) in constant expressions - (SF#2818562). - -2009-12-04: olly - [PHP] "empty" is a reserved word in PHP, so rename empty() method - on STL classes to "is_empty()" (previously this was automatically - renamed to "c_empty()"). - *** POTENTIAL INCOMPATIBILITY *** - -2009-12-03: olly - [PHP] Add typemaps for long long and unsigned long long, and for - pointer to method. - -2009-12-02: olly - [PHP] Fix warning and rename of reserved class name to be case - insensitive. - -2009-12-01: wsfulton - Revert support for %extend and memberin typemaps added in swig-1.3.39. The - memberin typemaps are ignored again for member variables within a %extend block. - Documentation inconsistency reported by Torsten Landschoff. - -2009-11-29: wsfulton - [Java, C#] Fix generated quoting when using %javaconst(1)/%csconst(1) for - static const char member variables. - - %javaconst(1) A; - %csconst(1) A; - struct X { - static const char A = 'A'; - }; - -2009-11-26: wsfulton - [Java, C#] Fix %javaconst(1)/%csconst(1) for static const member variables to - use the actual constant value if it is specified, rather than the C++ code to - access the member. - - %javaconst(1) EN; - %csconst(1) EN; - struct X { - static const int EN = 2; - }; - -2009-11-23: wsfulton - C++ nested typedef classes can now be handled too, for example: - struct Outer { - typedef Foo { } FooTypedef1, FooTypedef2; - }; - -2009-11-18: wsfulton - The wrappers for C nested structs are now generated in the same order as declared - in the parsed code. - -2009-11-18: wsfulton - Fix #491476 - multiple declarations of nested structs, for example: - struct Outer { - struct { - int val; - } inner1, inner2, *inner3, inner4[1]; - } outer; - -2009-11-17: wsfulton - Fix parsing of enum declaration and initialization, for example: - - enum ABC { - a, - b, - c - } A = a, *pC = &C, array[3] = {a, b, c}; - -2009-11-17: wsfulton - Fix parsing of struct declaration and initialization, for example: - - struct S { - int x; - } instance = { 10 }; - -2009-11-15: wsfulton - Fix #1960977 - Syntax error parsing derived nested class declaration and member - variable instance. - -2009-11-14: wsfulton - Fix #2310483 - function pointer typedef within extern "C" block. - -2009-11-13: wsfulton - Fix usage of nested template classes within templated classes so that compilable code - is generated. - -2009-11-13: olly - [php] Fix place where class prefix (as specified with -prefix) - wasn't being used. Patch from gverbruggen in SF#2892647. - -2009-11-12: wsfulton - Fix usage of nested template classes so that compilable code is generated - the nested - template class is now treated like a normal nested classes, that is, as an opaque type - unless the nestedworkaround feature is used. - -2009-11-12: wsfulton - Replace SWIGWARN_PARSE_NESTED_CLASS with SWIGWARN_PARSE_NAMED_NESTED_CLASS and - SWIGWARN_PARSE_UNNAMED_NESTED_CLASS for named and unnamed nested classes respectively. - - Named nested class ignored warnings can now be suppressed by name using %warnfilter, eg: - - %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner; - - but clearly unnamed nested classes cannot and the global suppression is still required, eg: - - #pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS - -2009-11-11: wsfulton - Added the nestedworkaround feature as a way to use the full functionality of a nested class - (C++ mode only). It removes the nested class from SWIG's type information so it is as if SWIG - had never parsed the nested class. The documented nested class workarounds using a global - fake class stopped working when SWIG treated the nested class as an opaque pointer, and - this feature reverts this behaviour. The documentation has been updated with details of how - to use and implement it, see the "Nested classes" section in SWIGPlus.html. - -2009-11-11: wsfulton - There were a number of C++ cases where nested classes/structs/unions were being handled - as if C code was being parsed which would oftentimes lead to uncompilable code as an - attempt was made to wrap the nested structs like it is documented for C code. Now all - nested structs/classes/unions are ignored in C++ mode, as was always documented. However, - there is an improvement as usage of nested structs/classes/unions is now always treated - as an opaque type by default, resulting in generated code that should always compile. - - *** POTENTIAL INCOMPATIBILITY *** - -2009-11-09: drjoe - Fix R for -fcompact and add std_map.i - -2009-11-08: wsfulton - Fix inconsistency for nested structs/unions/classes. Uncompilable code was being - generated when inner struct and union declarations were used as types within the - inner struct. The inner struct/union is now treated as a forward declaration making the - behaviour the same as an inner class. (C++ code), eg: - - struct Outer { - struct InnerStruct { int x; }; - InnerStruct* getInnerStruct(); - }; - -2009-11-08: wsfulton - Ignored nested class/struct warnings now display the name of the ignored class/struct. - -2009-11-07: wsfulton - Bug #1514681 - Fix nested template classes within a namespace generated uncompilable - code and introduced strange side effects to other wrapper code especially code - after the nested template class. Note that nested template classes are still ignored. - -2009-11-07: wsfulton - Add new debug options: - -debug-symtabs - Display symbol tables information - -debug-symbols - Display target language symbols in the symbol tables - -debug-csymbols - Display C symbols in the symbol tables - -2009-11-03: wsfulton - Fix some usage of unary scope operator (::) denoting global scope, for example: - - namespace AA { /* ... */ } - using namespace ::AA; - - and bug #1816802 - SwigValueWrapper should be used: - - struct CC { - CC(int); // no default constructor - }; - ::CC x(); - - and in template parameter specializations: - - struct S {}; - template <typename T> struct X { void a() {} }; - template <> struct X<S> { void b() {} }; - %template(MyTConcrete) X< ::S >; - - plus probably some other corner case usage of ::. - -2009-11-02: olly - [Python] Fix potential memory leak in initialisation code for the - generated module. - -2009-10-23: wsfulton - Fix seg fault when using a named nested template instantiation using %template(name) - within a class. A warning that these are not supported is now issued plus processing - continues as if no name was given. - -2009-10-20: wsfulton - [Python] Fix std::vector<const T*>. This would previously compile, but not run correctly. - -2009-10-20: wsfulton - Fixed previously fairly poor template partial specialization and explicit - specialization support. Numerous bugs in this area have been fixed including: - - - Template argument deduction implemented for template type arguments, eg this now - works: - template<typename T> class X {}; - template<typename T> class X<T *> {}; - %template(X1) X<const int *>; // Chooses T * specialization - - and more complex cases with multiple parameters and a mix of template argument - deduction and explicitly specialised parameters, eg: - template <typename T1, typename T2> struct TwoParm { void a() {} }; - template <typename T1> struct TwoParm<T1 *, int *> { void e() {} }; - %template(E) TwoParm<int **, int *>; - - Note that the primary template must now be in scope, like in C++, when - an explicit or partial specialization is instantiated with %template. - - *** POTENTIAL INCOMPATIBILITY *** - -2009-09-14: wsfulton - [C#] Add %csattributes for adding C# attributes to enum values, see docs for example. - -2009-09-11: wsfulton - Fix memmove regression in cdata.i as reported by Adriaan Renting. - -2009-09-07: wsfulton - Fix constant expressions containing <= or >=. - -2009-09-02: wsfulton - The following operators in constant expressions now result in type bool for C++ - wrappers and remain as type int for C wrappers, as per each standard: - - && || == != < > <= >= (Actually the last 4 are still broken). For example: - - #define A 10 - #define B 10 - #define A_EQ_B A == B // now wrapped as type bool for C++ - #define A_AND_B A && B // now wrapped as type bool for C++ - -2009-09-02: wsfulton - Fix #2845746. true and false are now recognised keywords (only when wrapping C++). - Constants such as the following are now wrapped (as type bool): - #define FOO true - #define BAR FOO && false - -Version 1.3.40 (18 August 2009) -=============================== - -2009-08-17: olly - [Perl] Add "#undef do_exec" to our clean up of Perl global - namespace pollution. - -2009-08-17: olly - [PHP] Fix to wrap a resource returned by __get() in a PHP object (SF#2549217). - -2009-08-17: wsfulton - Fix #2797485 After doing a 'make clean', install fails if yodl2man or yodl2html - is not available. - -2009-08-16: wsfulton - [Octave] Caught exceptions display the type of the C++ exception instead of the - generic "c++-side threw an exception" message. - -2009-08-16: wsfulton - [Java] When %catches is used, fix so that any classes specified in the "throws" - attribute of the "throws" typemap are generated into the Java method's throws clause. - -2009-08-16: wsfulton - [C#] Fix exception handling when %catches is used, reported by Juan Manuel Alvarez. - -2009-08-15: wsfulton - Fix %template seg fault on some cases of overloading the templated method. - Bug reported by Jan Kupec. - -2009-08-15: wsfulton - [Ruby] Add numerous missing wrapped methods for std::vector<bool> specialization - as reported by Youssef Jones. - -2009-08-14: wsfulton - [Perl] Add SWIG_ConvertPtrAndOwn() method into the runtime for smart pointer - memory ownership control. shared_ptr support still to be added. Patch from - David Fletcher. - -2009-08-14: olly - [PHP] PHP5 now wraps static member variables as documented. - -2009-08-14: olly - [PHP] Update the PHP "class" example to work with PHP5 and use - modern wrapping features. - -2009-08-13: wsfulton - [PHP] std::vector wrappers overhaul. They no longer require the - specialize_std_vector() macro. Added wrappers for capacity() and reserve(). - -2009-08-13: wsfulton - [PHP] Add const reference typemaps. const reference primitive types are - now passed by value rather than pointer like the other target languages. - Fixes SF#2524029. - -2009-08-08: wsfulton - [Python] More user friendly AttributeError is raised when there are - no constructors generated for the proxy class in the event that the - class is abstract - the error message is now - "No constructor defined - class is abstract" whereas if there are no - public constructors for any other reason and the class is not abstract, - the message remains - "No constructor defined". - [tcl] Similarly for tcl when using -itcl. - -2009-08-04: olly - [PHP] Fix generated code to work with PHP 5.3. - -2009-08-04: vmiklos - [PHP] Various mathematical functions (which would conflict - with the built-in PHP ones) are now automatically handled by - adding a 'c_' prefix. - -2009-08-03: wsfulton - [C#] The std::vector<T> implementation is improved and now uses $typemap such - that the proxy class for T no longer has to be specified in some macros - for correct C# compilation; the following macros are deprecated, where - CSTYPE was the C# type for the C++ class CTYPE: - - SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(CSTYPE, CTYPE) - usage should be removed altogether - - SWIG_STD_VECTOR_SPECIALIZE(CSTYPE, CTYPE) - should be replaced with: - SWIG_STD_VECTOR_ENHANCED(CTYPE) - - Some more details in csharp/std_vector.i - - *** POTENTIAL INCOMPATIBILITY *** - -2009-07-31: olly - [Python] Fix indentation so that we give a useful error if the - module can't be loaded. Patch from Gaetan Lehmann in SF#2829853. - -2009-07-29: wsfulton - Add $typemap(method, typelist) special variable macro. This allows - the contents of a typemap to be inserted within another typemap. - Fully documented in Typemaps.html. - -2009-07-29: vmiklos - [PHP] Static member variables are now prefixed with the - class name. This allows static member variables with the - same name in different classes. - -2009-07-29: olly - [Python] Add missing locks to std::map wrappers. Patch from - Paul Hampson in SF#2813836. - -2009-07-29: olly - [PHP] Fix memory leak in PHP OUTPUT typemaps. Reported by Hitoshi - Amano in SF#2826322. - -2009-07-29: olly - [PHP] Fix memory leak in PHP resource destructor for classes - without a destructor and non-class types. Patch from Hitoshi Amano - in SF#2825303. - -2009-07-28: olly - [PHP] Update warnings about clashes between identifiers and PHP - keywords and automatic renaming to work with the PHP5 class - wrappers. Fixes SF#1613679. - -2009-07-28: vmiklos - [PHP] If a member function is not public but it has a base - which is public, then now a warning is issued and the member - function will be public, as PHP requires this. - -2009-07-21: vmiklos - [PHP] Director support added. - -2009-07-15: olly - [Perl] Don't specify Perl prototype "()" for a constructor with a - different name to the class, as such constructors can still take - parameters. - -2009-07-12: xavier98 - [Octave] Add support for Octave 3.2 API - -2009-07-05: olly - [PHP] Update the list of PHP keywords - "cfunction" is no longer a - keyword in PHP5 and PHP 5.3 added "goto", "namespace", "__DIR__", - and "__NAMESPACE__". - -2009-07-03: olly - [Tcl] To complement USE_TCL_STUBS, add support for USE_TK_STUBS - and SWIG_TCL_STUBS_VERSION. Document all three in the Tcl chapter - of the manual. Based on patch from SF#2810380 by Christian - Gollwitzer. - -2009-07-02: vmiklos - [PHP] Added factory.i for PHP, see the li_factory testcase - for more info on how to use it. - -2009-07-02: wsfulton - Fix -Wallkw option as reported by Solomon Gibbs. - -2009-07-02: wsfulton - Fix syntax error when a nested struct contains a comment containing a * followed - eventually by a /. Regression from 1.3.37, reported by Solomon Gibbs. - -2009-07-01: vmiklos - [PHP] Unknown properties are no longer ignored in proxy - classes. - -2009-07-01: vmiklos - [PHP] Fixed %newobject behaviour, previously any method - marked with %newobject was handled as a constructor. - -2009-06-30: olly - [Ruby] Undefine close and connect macros defined by Ruby API - headers as we don't need them and they can clash with C++ methods - being wrapped. Patch from Vit Ondruch in SF#2814430. - -2009-06-26: olly - [Ruby] Fix to handle FIXNUM values greater than MAXINT passed for a - double parameter. - -2009-06-24: wsfulton - Fix wrapping methods with default arguments and the compactdefaultargs feature - where a class is passed by value and is assigned a default value. The SwigValueWrapper - template workaround for a missing default constructor is no longer used as the code - generated does not call the default constructor. - -2009-06-16: wsfulton - [Java,C#] Fix enum marshalling when %ignore is used on one of the enum items. - Incorrect enum values were being passed to the C++ layer or compilation errors resulted. - -2009-06-02: talby - [Perl] Resolved reference.i overload support problem - identified by John Potowsky. - -2009-05-26: wsfulton - [C#] Improved std::map wrappers based on patch from Yuval Baror. The C# proxy - now implements System.Collections.Generic.IDictionary<>. - - These std:map wrappers have a non-backwards compatible overhaul to make them - like a .NET IDictionary. Some method names have changed as following: - set -> setitem (use this[] property now) - get -> getitem (use this[] property now) - has_key -> ContainsKey - del -> Remove - clear -> Clear - - The following macros used for std::map wrappers are deprecated and will no longer work: - specialize_std_map_on_key - specialize_std_map_on_value - specialize_std_map_on_both - - *** POTENTIAL INCOMPATIBILITY *** - -2009-05-20: vmiklos - [PHP] Add the 'thisown' member to classes. The usage of it - is the same as the Python thisown one: it's 1 by default and - you can set it to 0 if you want to prevent freeing it. (For - example to prevent a double free.) - -2009-05-14: bhy - [Python] Fix the wrong pointer value returned by SwigPyObject_repr(). - -2009-05-13: mutandiz (Mikel Bancroft) - [allegrocl] Minor tweak when wrapping in -nocwrap mode. - -2009-05-11: wsfulton - [C#] Improved std::vector wrappers on the C# proxy side from Yuval Baror. These - implement IList<> instead of IEnumerable<> where possible. - -2009-04-29: wsfulton - [Java, C#] Add the 'notderived' attribute to the javabase and csbase typemaps. - When this attribute is set, the typemap will not apply to classes that are derived - from a C++ base class, eg - %typemap(csbase, notderived="1") SWIGTYPE "CommonBase" - -2009-04-29: olly - [Python] Don't attempt to acquire the GIL in situations where we - know that it will already be locked. This avoids some dead-locks - with mod_python (due to mod_python bugs which are apparently - unlikely to ever be fixed), and results in smaller wrappers which - run a little faster (in tests with Xapian on x86-64 Ubuntu 9.04, - the stripped wrapper library was 11% smaller and ran 2.7% faster). - -2009-04-21: wsfulton - [C#] Fix #2753469 - bool &OUTPUT and bool *OUTPUT typemaps initialisation. - -2009-04-09: wsfulton - Fix #2746858 - C macro expression using floating point numbers - -2009-03-30: olly - [PHP] The default out typemap for char[ANY] now returns the string up to a - zero byte, or the end of the array if there is no zero byte. This - is the same as Python does, and seems more generally useful than - the previous behaviour of returning the whole contents of the array - including any zero bytes. If you want the old behaviour, you can provide - your own typemap to do this: - - %typemap(out) char [ANY] - %{ - RETVAL_STRINGL($1, $1_dim0, 1); - %} - -Version 1.3.39 (21 March 2009) -============================== - -2009-03-19: bhy - [Python] Fix the memory leak related to Python 3 unicode and C char* conversion, - which can be shown in the following example before this fix: - - from li_cstring import * - i=0 - while True: - i += 1 - n = str(i)*10 - test3(n) - - This fix affected SWIG_AsCharPtrAndSize() so you cannot call this function with - a null alloc and non-null cptr argument in Python 3, otherwise a runtime error - will be raised. - -2009-03-18: wsfulton - [C#] std::vector<T> wrapper improvements for .NET 2 and also providing the - necessary machinery to use the std::vector<T> wrappers with more advanced features such - as LINQ - the C# proxy class now derives from IEnumerable<>. The default is now to - generate code requiring .NET 2 as a minimum, although the C# code can be compiled - for .NET 1 by defining the SWIG_DOTNET_1 C# preprocessor constant. See the - std_vector.i file for more details. - - *** POTENTIAL INCOMPATIBILITY *** - -2009-03-12: wsfulton - [Ruby] Fix #2676738 SWIG generated symbol name clashes. - -2009-03-01: bhy - [Python] Some fixes for Python 3.0.1 and higher support. In 3.0.1, the C API function - PyObject_Compare is removed, so PyObject_RichCompareBool is used for replacement. - Struct initilization of SwigPyObject and SwigPyObject_as_number changed to reflect - the drop of tp_compare and nb_long. - -2009-03-01: bhy - [Python] Fix SF#2583160. Now the importer in Python shadow wrapper take care of the - case that module already imported at other place. - -2009-02-28: bhy - [Python] Fix SF#2637352. Move struct declaration of SWIG_module in pyinit.swg before - the method calls, since some C compiler don't allow declaration in middle of function - body. - -2009-02-21: wsfulton - [Allegrocl] Fix seg fault wrapping some constant variable (%constant) types. - -2009-02-20: wsfulton - [CFFI] Fix seg faults when for %extend and using statements. - -2009-02-20: wsfulton - Fix SF #2605955: -co option which broke in 1.3.37. - -2009-02-20: wsfulton - New %insert("begin") section added. Also can be used as %begin. This is a new - code section reserved entirely for users and the code within the section is generated - at the top of the C/C++ wrapper file and so provides a means to put custom code - into the wrapper file before anything else that SWIG generates. - -2009-02-17: wsfulton - 'make clean-test-suite' will now run clean on ALL languages. Previously it only - ran the correctly configured languages. This way it is now possible to clean up - properly after running 'make partialcheck-test-suite'. - -2009-02-14: wsfulton - Extend attribute library support for structs/classes and the accessor functions use - pass/return by value semantics. Two new macros are available and usage is identical - to %attribute. These are %attributeval for structs/classes and %attributestring for - string classes, like std::string. See attribute.swg for more details. - -2009-02-13: wsfulton - Add support for %extend and memberin typemaps. Previously the memberin typemaps were - ignored for member variables within a %extend block. - -2009-02-12: wsfulton - Remove unnecessary temporary variable when wrapping return values that are references. - Example of generated code for wrapping: - - struct XYZ { - std::string& refReturn(); - }; - - used to be: - - std::string *result = 0 ; - ... - { - std::string &_result_ref = (arg1)->refReturn(); - result = (std::string *) &_result_ref; - } - - Now it is: - - std::string *result = 0 ; - ... - result = (std::string *) &(arg1)->refReturn(); - -2009-02-08: bhy - Change the SIZE mapped by %pybuffer_mutable_binary and %pybuffer_binary in pybuffer.i from - the length of the buffer to the number of items in the buffer. - -2009-02-08: wsfulton - Fix %feature not working for conversion operators, reported by Matt Sprague, for example: - %feature("cs:methodmodifiers") operator bool "protected"; - -2009-02-07: wsfulton - [MzScheme] Apply #2081967 configure changes for examples to build with recent PLT versions. - Also fixes Makefile errors building SWIG executable when mzscheme package is installed - (version 3.72 approx and later). - -2009-02-04: talby - [Perl] Fix SF#2564192 reported by David Kolovratnk. - SWIG_AsCharPtrAndSize() now handles "get" magic. - -Version 1.3.38 (31 January 2009) -================================ - -2009-01-31: bhy - [Python] Fix SF#2552488 reported by Gaetan Lehmann. Now %pythonprepend - and %pythonappend have correct indentation. - -2009-01-31: bhy - [Python] Fix SF#2552048 reported by Gaetan Lehmann. The parameter list - of static member function in generated proxy code should not have the - 'self' parameter. - -2009-01-29: wsfulton - Fix regression introduced in 1.3.37 where the default output directory - for target language specific files (in the absence of -outdir) was no - longer the same directory as the generated c/c++ file. - -2009-01-28: wsfulton - [Java, C#] Fix proxy class not being used when the global scope operator - was used for parameters passed by value. Reported by David Piepgrass. - -2009-01-15: wsfulton - [Perl] Fix seg fault when running with -v option, reported by John Ky. - -Version 1.3.37 (13 January 2009) -================================ - -2009-01-13: mgossage - [Lua] Added contract support for requiring that unsigned numbers are >=0 - Rewrote much of Examples/Lua/embed3. - Added a lot to the Lua documentation. - -2009-01-13: wsfulton - Fix compilation error when using directors on protected virtual overloaded - methods reported by Sam Hendley. - -2009-01-12: drjoe - [R] Fixed handling of integer arrays - -2009-01-10: drjoe - [R] Fix integer handling in r to deal correctly with signed - and unsigned issues - -2009-01-10: wsfulton - Patch #1992756 from Colin McDonald - %contract not working for classes - in namespace - -2009-01-05: olly - Mark SWIGPERL5, SWIGPHP5, and SWIGTCL8 as deprecated in the source - code and remove documentation of them. - -2008-12-30: wsfulton - Bug #2430756. All the languages now define a macro in the generated C/C++ - wrapper file indicating which language is being wrapped. The macro name is the - same as those defined when SWIG is run, eg SWIGJAVA, SWIGOCTAVE, SWIGCSHARP etc - and are listed in the "Conditional Compilation" section in the documentation. - -2008-12-23: wsfulton - [Java] Fix #2153773 - %nojavaexception was clearing the exception feature - instead of disabling it. Clearing checked Java exceptions also didn't work. - The new %clearjavaexception can be used for clearing the exception feature. - -2008-12-22: wsfulton - Fix #2432801 - Make SwigValueWrapper exception safe for when copy constructors - throw exceptions. - -2008-12-21: wsfulton - Apply patch #2440046 which fixes possible seg faults for member and global - variable char arrays when the strings are larger than the string array size. - -2008-12-20: wsfulton - The ccache compiler cache has been adapted to work with SWIG and - named ccache-swig. It now works with C/C++ compilers as well as SWIG - and can result in impressive speedups when used to recompile unchanged - code with either a C/C++ compiler or SWIG. Documentation is in CCache.html - or the installed ccache-swig man page. - -2008-12-12: wsfulton - Apply patch from Kalyanov Dmitry which fixes parsing of nested structs - containing comments. - -2008-12-12: wsfulton - Fix error message in some nested struct and %inline parsing error situations - such as unterminated strings and comments. - -2008-12-07: olly - [PHP] Fix warnings when compiling generated wrapper with GCC 4.3. - -2008-12-06: wsfulton - [PHP] Deprecate %pragma(php4). Please use %pragma(php) instead. - The following two warnings have been renamed: - WARN_PHP4_MULTIPLE_INHERITANCE -> WARN_PHP_MULTIPLE_INHERITANCE - WARN_PHP4_UNKNOWN_PRAGMA -> WARN_PHP_UNKNOWN_PRAGMA - - *** POTENTIAL INCOMPATIBILITY *** - -2008-12-04: bhy - [Python] Applied patch SF#2158938: all the SWIG symbol names started with Py - are changed, since they are inappropriate and discouraged in Python - documentation (from http://www.python.org/doc/2.5.2/api/includes.html): - - "All user visible names defined by Python.h (except those defined by - the included standard headers) have one of the prefixes "Py" or "_Py". - Names beginning with "_Py" are for internal use by the Python implementation - and should not be used by extension writers. Structure member names do - not have a reserved prefix. - - Important: user code should never define names that begin with "Py" or "_Py". - This confuses the reader, and jeopardizes the portability of the user - code to future Python versions, which may define additional names beginning - with one of these prefixes." - - Here is a brief list of what changed: - - PySwig* -> SwigPy* - PyObject_ptr -> SwigPtr_PyObject - PyObject_var -> SwigVar_PyObject - PySequence_Base, PySequence_Cont, PySequence_Ref -> - SwigPySequence_Base, SwigPySequence_Cont, SwigPySequence_Ref - PyMap* -> SwigPyMap* - - We provided a pyname_compat.i for backward compatibility. Users whose code having - these symbols and do not want to change it could simply include this file - at front of your code. A better solution is to run the converting tool on - your code, which has been put in SWIG's SVN trunk (Tools/pyname_patch.py) and - you can download it here: - https://swig.svn.sourceforge.net/svnroot/swig/trunk/Tools/pyname_patch.py - - *** POTENTIAL INCOMPATIBILITY *** - -2008-12-02: wsfulton - [Python] Apply patch #2143727 from Serge Monkewitz to fix importing base classes - when the package option is specified in %module and that module is %import'ed. - -2008-11-28: wsfulton - [UTL] Fix #2080497. Some incorrect acceptance of types in the STL, eg a double * element - passed into a vector<int *> constructor would be accepted, but the ensuing behaviour - was undefined. Now the type conversion correctly raises an exception. - -2008-11-24: wsfulton - Add -outcurrentdir option. This sets the default output directory to the current - directory instead of the path specified by the input file. This option enables - behaviour similar to c/c++ compilers. Note that this controls the output directory, - but only in the absence of the -o and/or -outdir options. - -2008-11-23: wsfulton - [ruby] Apply patch #2263850 to fix ruby/file.i ... rubyio.h filename change in - ruby 1.9. - -2008-11-23: wsfulton - Apply patch #2319790 from Johan Hake to fix shared_ptr usage in std::tr1 namespace. - -2008-11-21: wsfulton - The use of the include path to find the input file is now deprecated. - This makes the behaviour of SWIG the same as C/C++ compilers in preparation - for use with ccache. - -2008-11-16: wsfulton - Fix -nopreprocess option to: - - correctly report file names in warning and error messages. - - use the original input filename that created the preprocessed output when - determining the C++ wrapper file name (in the absence of -o). Previously - the name of the input file containing the preprocessed output was used. - -2008-11-11: wsfulton - [Java] Add patch #2152691 from MATSUURA Takanori which fixes compiles using the - Intel compiler - -2008-11-01: wsfulton - Add patch #2128249 from Anatoly Techtonik which corrects the C/C++ proxy - class being reported for Python docstrings when %rename is used. - -2008-11-01: wsfulton - Add the strip encoder patch from Anatoly Techtonik #2130016. This enables an - easy way to rename symbols by stripping a commonly used prefix in all the - function/struct names. It works in the same way as the other encoders, such as - title, lower, command etc outlined in CHANGES file dated 12/30/2005. Example - below will rename wxAnotherWidget to AnotherWidget and wxDoSomething to - DoSomething: - - %rename("%(strip:[wx])s") ""; - - struct wxAnotherWidget { - void wxDoSomething(); - }; - -2008-09-26: mutandiz - [allegrocl] - Lots of test-suite work. - - Fix ordering of wrapper output and %{ %} header output. - - Fix declarations of local vars in C wrappers. - - Fix declaration of defined constants in C wrappers. - - Fix declaration of EnumValues in C wrappers. - - add some const typemaps to allegrocl.swg - - add rename for operator bool() overloads. - -2008-09-25: olly - [PHP5] Fill in typemaps for SWIGTYPE and void * (SF#2095186). - -2008-09-22: mutandiz (Mikel Bancroft) - [allegrocl] - - Support wrapping of types whose definitions are not seen by - SWIG. They are treated as forward-referenced classes and if a - definition is not seen are treated as (* :void). - - Don't wrap the contents of unnamed namespaces. - - More code cleanup. Removed some extraneous warnings. - - start work on having the allegrocl mod pass the cpp test-suite. - -2008-09-19: olly - [PHP5] Add typemaps for long long and unsigned long long. - -2008-09-18: wsfulton - [C#] Added C# array typemaps provided by Antti Karanta. - The arrays provide a way to use MarshalAs(UnmanagedType.LPArray) - and pinning the array using 'fixed'. See arrays_csharp.i library file - for details. - -2008-09-18: wsfulton - Document the optional module attribute in the %import directive, - see Modules.html. Add a warning for Python wrappers when the - module name for an imported base class is missing, requiring the - module attribute to be added to %import, eg - - %import(module="FooModule") foo.h - -2008-09-18: olly - [PHP5] Change the default input typemap for char * to turn PHP - Null into C NULL (previously it was converted to an empty string). - The new behaviour is consistent with how the corresponding output - typemap works (SF#2025719). - - If you want to keep the old behaviour, add the following typemap - to your interface file (PHP's convert_to_string_ex() function does - the converting from PHP Null to an empty string): - - %typemap(in) char * { - convert_to_string_ex($input); - $1 = Z_STRVAL_PP($input); - } - -2008-09-18: olly - [PHP5] Fix extra code added to proxy class constructors in the case - where the only constructor takes no arguments. - -2008-09-18: olly - [PHP5] Fix wrapping of a renamed enumerated value of an enum class - member (SF#2095273). - -2008-09-17: mutandiz (Mikel Bancroft) - [allegrocl] - - Fix how forward reference typedefs are handled, so as not to conflict - with other legit typedefs. - - Don't (for now) perform an ffitype typemap lookup when trying to - when calling compose_foreign_type(). This is actually a useful thing - to do in certain cases, the test cases for which I can't currently - locate :/. It's breaking some wrapping behavior that is more commonly - seen, however. I'll readd in a more appropriate way when I can - recreate the needed test case, or a user complains (which means - they probably have a test case). - - document the -isolate command-line arg in the 'swig -help' output. - It was in the html docs, but not there. - - small amount of code cleanup, removed some unused code. - - some minor aesthetic changes. - -2008-09-12: bhy - [Python] Python 3.0 support branch merged into SWIG trunk. Thanks to - Google Summer of Code 2008 for supporting this project! By default - SWIG will generate interface files compatible with both Python 2.x - and 3.0. And there's also some Python 3 new features that can be - enabled by passing a "-py3" command line option to SWIG. These - features are: - - - Function annotation support - Also, the parameter list of proxy function will be generated, - even without the "-py3" option. However, the parameter list - will fallback to *args if the function (or method) is overloaded. - - Buffer interface support - - Abstract base class support - - For details of Python 3 support and these features, please see the - "Python 3 Support" section in the "SWIG and Python" chapter of the SWIG - documentation. - - The "-apply" command line option and support of generating codes - using apply() is removed. Since this is only required by very old - Python. - - This merge also patched SWIG's parser to solve a bug. By this patch, - SWIG features able to be correctly applied on C++ conversion operator, - such like this: - - %feature("shadow") *::operator bool %{ ... %} - -2008-09-02: richardb - [Python] Commit patch #2089149: Director exception handling mangles - returned exception. Exceptions raised by Python code in directors - are now passed through to the caller without change. Also, remove - the ": " prefix which used to be added to other director exceptions - (eg, those due to incorrect return types). - -2008-09-02: wsfulton - [Python] Commit patch #1988296 GCItem multiple module linking issue when using - directors. - -2008-09-02: wsfulton - [C#] Support for 'using' and 'fixed' blocks in the 'csin' typemap is now - possible through the use of the pre attribute and the new terminator attribute, eg - - %typemap(csin, - pre=" using (CDate temp$csinput = new CDate($csinput)) {", - terminator=" } // terminate temp$csinput using block", - ) const CDate & - "$csclassname.getCPtr(temp$csinput)" - - See CSharp.html for more info. - -2008-09-01: wsfulton - [CFFI] Commit patch #2079381 submitted by Boris Smilga - constant exprs put into - no-eval context in DEFCENUM - -2008-08-02: wuzzeb - [Chicken,Allegro] Commit Patch 2019314 - Fixes a build error in chicken, and several build errors and other errors - in Allegro CL - -2008-07-19: wsfulton - Fix building of Tcl examples/test-suite on Mac OS X reported by Gideon Simpson. - -2008-07-17: wsfulton - Fix SF #2019156 Configuring with --without-octave or --without-alllang - did not disable octave. - -2008-07-14: wsfulton - [Java, C#] Fix director typemaps for pointers so that NULL pointers are correctly - marshalled to C#/Java null in director methods. - -2008-07-04: olly - [PHP] For std_vector.i and std_map.i, rename empty() to is_empty() - since "empty" is a PHP reserved word. Based on patch from Mark Klein - in SF#1943417. - -2008-07-04: olly - [PHP] The deprecated command line option "-make" has been removed. - Searches on Google codesearch suggest that nobody is using it now - anyway. - -2008-07-04: olly - [PHP] The SWIG cdata.i library module is now supported. - -2008-07-03: olly - [PHP] The deprecated command line option "-phpfull" has been - removed. We recommend building your extension as a dynamically - loadable module. - -2008-07-02: olly - [PHP4] Support for PHP4 has been removed. The PHP developers are - no longer making new PHP4 releases, and won't even be providing - patches for critical security issues after 2008-08-08. - -2008-07-02: olly - [Python] Import the C extension differently for Python 2.6 and - later so that an implicit relative import doesn't produce a - deprecation warning for 2.6 and a failure for 2.7 and later. - Patch from Richard Boulton in SF#2008229, plus follow-up patches - from Richard and Haoyu Bai. - -Version 1.3.36 (24 June 2008) -============================= - -06/24/2008: wsfulton - Remove deprecated -c commandline option (runtime library generation). - -06/24/2008: olly - [PHP] Fix assertion failure when handling %typemap(in,numinputs=0) - (testcase ignore_parameter). - -06/24/2008: olly - [PHP] Fix segfault when wrapping a non-class function marked with - %newobject (testcase char_strings). - -06/22/2008: wsfulton - [Java] Add a way to use AttachCurrentThreadAsDaemon instead of AttachCurrentThread - in director code. Define the SWIG_JAVA_ATTACH_CURRENT_THREAD_AS_DAEMON macro, see - Lib/java/director.swg. - -06/21/2008: wsfulton - [Ruby] Fix crashing in the STL wrappers (reject! and delete_if methods) - -06/19/2008: wsfulton - [Java, C#] C# and Java keywords will be renamed instead of just issuing a warning - and then generating uncompilable code. Warning 314 gives the new name when a - keyword is found. - -06/19/2008: wsfulton - [R] Keyword handling added. R Keywords will be renamed as necessary. - Warning 314 gives the new name when a keyword is found. - -06/17/2008: mgossage - [Lua] Added missing support for bool& and bool*. Added runtest for li_typemaps testcase. - (Bug #1938142) - -06/07/2008: bhy - Added test case keyword_rename, then made the keyword renaming works properly - by fixing Swig_name_make() for a incomplete condition checking. - -06/02/2008: wsfulton - [Java, C#] Fix enum wrappers when using -noproxy. - -05/30/2008: bhy - Added std::wstring into Lib/typemaps/primtypes.swg, since it is also a primitive - type in SWIG - fixed SF #1976978. - -05/29/2008: wsfulton - [Java, C#] Fix variable wrappers when using -noproxy. - -05/29/2008: bhy - [Python] Fixed a typo of %#ifdef in Lib/python/pycontainer.swg, which is related - to -extranative SWIG option - SF #1971977. - -05/20/2008: wsfulton - New partialcheck makefile targets for partial testing of the test-suite. These - just invoke SWIG, ie no compilation and no runtime testing. It can be faster - when developing by just doing a directory diff of the files SWIG generates - against those from a previous run. Example usage from the top level directory: - - make partialcheck-test-suite - make partialcheck-java-test-suite - - This change also encompasses more flexibility in running the test-suite, eg - it is possible to prefix the command line which runs any target language test - with a tool. See the RUNTOOL, COMPILETOOL and SWIGTOOL targets in the common.mk - file and makefiles in the test-suite directory. For example it is possible to - run the runtime tests through valgrind using: - - make check RUNTOOL="valgrind --leak-check=full" - - or invoke SWIG under valgrind using: - - make check SWIGTOOL="valgrind --tool=memcheck" - -05/19/2008: drjoe - [R] Fixed define that was breaking pre-2.7. Checked in - patch from Soren Sonnenburg that creates strings in - version independent way - -05/15/2008: wsfulton - [Java] Fix variable name clash in directors - SF #1963316 reported by Tristan. - -05/14/2008: wsfulton - Add an optimisation for functions that return objects by value, reducing - the number of copies of the object that are made. Implemented using an - optional attribute in the "out" typemap called "optimal". Details in - Typemaps.html. - -05/11/2008: olly - [PHP] Check for %feature("notabstract") when generating PHP5 class - wrapper. - -05/11/2008: wsfulton - Fix SF #1943608 - $self substitution in %contract, patch submitted by - Toon Verstraelen. - -05/09/2008: olly - [PHP] Fix char * typemaps to work when applied to signed char * and - unsigned char * (uncovered by testcase apply_strings). - -05/09/2008: wsfulton - Fix wrapping of char * member variables when using allprotected mode. - Bug reported by Warren Wang. - -05/09/2008: olly - [PHP] Fix bad PHP code generated when wrapping an enum in a - namespace (uncovered by testcase arrays_scope). - -05/09/2008: olly - [PHP] SWIG now runs the PHP testsuite using PHP5, not PHP4. PHP4 - is essentially obsolete now, so we care much more about solid PHP5 - support. - -05/07/2008: wsfulton - STL fixes when using %import rather than %include and the Solaris Workshop - compiler and the Roguewave STL. - -05/07/2008: wsfulton - Fix wrapping of overloaded protected methods when using allprotected mode. - Bug reported by Warren Wang. - -05/03/2008: wsfulton - Commit patch #1956607 to add -MT support from Richard Boulton. - This patch mirrors the gcc -MT option which allows one to change the default - Makefile target being generated when generating makefiles with the -M family - of options. For example: - - $ swig -java -MM -MT overriddenname -c++ example.i - overriddenname: \ - example.i \ - example.h - -04/30/2008: mgossage - [Lua] Removed generation of _wrap_delete_XXXXX (wrappered destructor) - which was unused and causing warning with g++ -Wall. - Removed other unused warning in typemaps.i and other places. - Added Examples/lua/embed3, and run tests a few test cases. - -04/24/2008: olly - [Python] Fix generated code for IBM's C++ compiler on AIX (patch - from Goeran Uddeborg in SF#1928048). - -04/24/2008: olly - Rename BSIZE in Examples/test-suite/arrays_scope.i to BBSIZE to - avoid a clash with BSIZE defined by headers on AIX with Perl - (reported in SF#1928048). - -04/20/2008: wsfulton - Add the ability to wrap all protected members when using directors. - Previously only the virtual methods were available to the target language. - Now all protected members, (static and non-static variables, non-virtual methods - and static methods) are wrapped when using the allprotected mode. The allprotected - mode is turned on in the module declaration: - - %module(directors="1", allprotected="1") modulename - -Version 1.3.35 (7 April 2008) -============================= - -04/07/2008: wsfulton - [Lua] Add missing pointer reference typemaps - -04/06/2008: wsfulton - Fix stack overflow when using typemap warning suppression, eg - %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG) - -04/05/2008: wsfulton - [Python] Fix shared_ptr typemaps so that %pythonnondynamic can be used. Also corrects - display of the proxy class type. Reported by Robert Lupton. - -04/04/2008: olly - [Python] Add %newobject reference to python memory management subsection of manual - (patch from mdbeachy in SF#1894610). - -03/27/2008: wsfulton - [Python] Fix shared_ptr typemaps where the pointer type is a templated type with - with more than one parameter. Reported by Robert Lupton. - -03/27/2008: mgossage - [Lua] Added a typemap DISOWN for SWIGTYPE* and SWIGTYPE[], and support for %delobject feature. - Added Examples/lua/owner which demonstrates the use of the memory management. - -03/26/2008: wsfulton - [Java] Apply patch #1844301 from Monty Taylor to suppress enum constructor - unused warnings. - -03/26/2008: wsfulton - [Python] Apply patch #1924524 from Casey Raymondson which ensures the - "No constructor defined" message is displayed when attempting to call a - constructor on a class that doesn't have a constructor wrapper, eg if - the C++ class is abstract. - -03/26/2008: wsfulton - [Python] Apply patch #1925702 from Casey Raymondson which removes warning 512 - for std::vector wrappers. - -03/26/2008: olly - [Python] Apply GCC 4.3 warnings patch from Philipp Thomas - (SF#1925122). - -03/21/2008: wsfulton - [Python] Thread safety patch for STL iterators from Abhinandan Jain. - -03/17/2008: mgossage - [Lua] Added %luacode feature to add source code into wrappers. - Updated documentation to document this. - Added Examples/lua/arrays to show its use (and typemaps) - -03/17/2008: olly - Fix nonportable sed usage which failed on Mac OS X (and probably - other platforms). Fixes SF#1903612. - -03/17/2008: olly - Fix memory leak in SWIG's parser (based on patch from Russell - Bryant in SF#1914023). - -03/12/2008: wsfulton - Fix bug #1878285 - unnecessary cast for C struct creation wrappers. - -03/12/2008: wsfulton - [Python] Remove debugging info when using shared_ptr support - -03/06/2008: mgossage - [Lua] Updated documentation for Lua exceptions. - Added Examples/lua/exception and Examples/lua/embed2. - Small updates to the typemaps. - -03/04/2008: wsfulton - [Java, C#] Add char *& typemaps. - -03/04/2008: wsfulton - Fix occasional seg fault when attempting to report overloaded methods as being ignored. - -02/29/2008: wsfulton - [Perl] Fix #1904537 Swig causes a Perl warning "x used only once" in Perl 5.10 - reported by Ari Jolma - -02/29/2008: wsfulton - [Python] Add shared_ptr varin/varout typemaps for wrapping global variables. - -02/25/2008: wsfulton - Fix $wrapname to work in %exception (fixes some wrap:name assertions) - -Version 1.3.34 (27 February 2008) -================================= - -02/13/2008: wsfulton - [R] Fix wrapping of global function pointer variables. - -02/13/2008: wsfulton - Add new special variables for use within %exception: - $wrapname - language specific wrapper name - $overname - if a method is overloaded this contains the extra mangling used on - the overloaded method - $decl - the fully qualified C/C++ declaration of the method being wrapped - without the return type - $fulldecl - the fully qualified C/C++ declaration of the method being wrapped - including the return type - -02/12/2008: drjoe - [R] Now setting S4 flag in SWIG created objects. This - fixes R-SWIG for 2.6 and warning for 2.6 failure has been removed. - -02/11/2008: mgossage - [Lua] Added a patch by Torsten Landschoff to fix the unary minus issue - Ran 'astyle --style=kr -2' across lua.cxx to neaten it up - -02/10/2008: wsfulton - Bump SWIG_RUNTIME_VERSION to 4. This is because of the recently introduced API - change in the conversion functions, ie change in definition of swig_converter_func. - Anyone calling SWIG_TypeCast must pass in a valid value for the new additional - (third) parameter and then handle the newly created memory if the returned value - is set to SWIG_CAST_NEW_MEMORY else a memory leak will ensue. - -02/09/2008: wsfulton - [Python] Experimental shared_ptr typemaps added. Usage is the same as the recently - added Java and C# shared_ptr typemaps. Two macros are available, although these - may well change in a future version: - - For base classes or classes not in an inheritance chain: - SWIG_SHARED_PTR(PROXYCLASS, TYPE) - For derived classes: - SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE) - - The PROXYCLASS is the name of the proxy class, but is only required for Java/C#. - Example usage: - - %include "boost_shared_ptr.i" - - SWIG_SHARED_PTR(Klass, Space::Klass) - SWIG_SHARED_PTR_DERIVED(KlassDerived, Space::Klass, Space::KlassDerived) - - namespace Space { - struct Klass { ... }; - struct KlassDerived : Klass { ... }; - } - - Further details to follow in future documentation, but the following features - should be noted: - - - Not restricted to boost::shared_ptr, eg std::tr1::shared_ptr can also be used. - - Available typemap groups: - (a) Typemaps for shared_ptr passed by value, reference, pointer and pointer - reference. - - (b) Typemaps for passing by raw value, raw pointer, raw reference, raw pointer - reference. - - The code being wrapped does not even have to use shared_ptr, SWIG can use - shared_ptr as the underlying storage mechanism instead of a raw pointer due to - the typemaps in group (b) above. - - No array support as shared_ptr does not support arrays. - - This works quite differently to the usual SWIG smart pointer support when - operator-> is parsed by SWIG: - - An additional smart pointer class is not generated reducing code bloat in - the wrappers. - - Using smart pointers and raw pointers can be mixed seamlessly. - - Missing constructors for the smart pointers is no longer a problem and so - separate factory type functions do not have to be written and wrapped. - - The implicit C++ shared_ptr< derived class > to shared_ptr< base class > - cast also works in the target language. This negates the necessity to write - an explicit helper cast function providing the upcast which would need - calling prior to passing a derived class to a method taking a shared_ptr to - a base class. - -02/09/2008: wsfulton - [Python] Add support for overriding the class registration function via a new - "smartptr" feature. This is a very low level of customisation most users - would never need to know. The feature will typically be used for intrusive - smart pointers along with additional typemaps. Example usage of the feature: - - %feature("smartptr", noblock=1) Foo { boost::shared_ptr< Foo > } - class Foo {}; - - The generated Foo_swigregister function will then register boost::shared < Foo > - (SWIGTYPE_p_boost__shared_ptrTFoo_t instead of SWIGTYPE_p_Foo) as the underlying - type for instantiations of Foo. - -02/09/2008: wsfulton - Features now supports the optional 'noblock' attribute for all usage of %feature. - When specified, the { } braces are removed from the feature code. This is identical - in behaviour to usage of 'noblock' in typemaps and is used when the preprocessor - is required to operate on the code in the feature and the enclosing { } braces - are not required. Example: - - #define FOO foo - %feature("smartptr", noblock="1") { FOO::bar } - - The preprocessor then reduces this as if this had been used instead: - - %feature("smartptr") "foo::bar" - -02/01/2008: olly - [Python] Fix format string bug (SF#1882220). - -01/31/2008: wsfulton - Additions to the %types directive. Now the conversion / casting code can be - overridden to some custom code in the %types directive, like so: - - %types(fromtype = totype) %{ - ... code to convert fromtype to totype and return ... - %} - - The special variable $from will be replaced by the name of the parameter of the - type being converted from. The code must return the totype cast to void *. Example: - - class Time; - class Date; - Date &Time::dateFromTime(); - - %types(Time = Date) %{ - Time *t = (Time *)$from; - Date &d = t->dateFromTime(); - return (void *) &d; - %} - - resulting in the conversion / casting code looking something like: - - static void *_p_TimeTo_p_Date(void *x) { - Time *t = (Time *)x; - Date &d = t->dateFromTime(); - return (void *) &d; - } - - This is advanced usage, please use only if you understand the runtime type system. - -01/30/2008: mgossage - Small update to documentation in Typemaps.html, to warn about use of local - variables in typemaps for multiple types. - -01/25/2008: wsfulton - [Java] Fix bug reported by Kevin Mills in ARRAYSOFCLASSES typemaps where any - changes made to an array element passed from Java to C are not reflected back - into Java. - -01/24/2008: mgossage - More updates to the configure script for detecting lua. - Also looks in /usr/include/lua* - Also changed typemaps.i not to check for NULL before freeing a pointer - -01/21/2008: wsfulton - [Python] For STL containers, SWIG no longer attempts to convert from one - STL container to another, eg from std::vector<int> to std::vector<double> - or std::list<int> to std::vector<int> or even std::vector<Foo> to - std::vector<Bar> as it previously did. In fact SWIG no longer attempts to - convert any SWIG wrapped C++ proxy class that is also a Python sequence, - whereas previously it would. Any non-SWIG Python sequence will still be - accepted wherever an STL container is accepted. Overloaded methods using - containers should be faster. - -01/18/2008: wsfulton - [C#] Add 'directorinattributes' and 'directoroutattributes' typemap attributes - for the imtype typemap. These should contain C# attributes which will - be generated into the C# director delegate methods. - -01/18/2008: olly - Fix handling of byte value 255 in input files on platforms where - char is signed (it was getting mapped to EOF). Fixes SF#1518219. - -01/16/2008: wsfulton - Fix template member variables wrapped by a smart pointer. Bug reported - by Robert Lupton. - -01/14/2008: mgossage - Substantial changes to configure script for detecting lua. - Code can now link to liblua.a, liblua50.a or liblua51.a - It's also a lot neater now. - -12/16/2007: wsfulton - [Perl] Backed out #1798728 - numbers can be passed to functions taking char * - -12/16/2007: wsfulton - Fix #1832613 - Templates and some typedefs involving pointers or function pointers - -12/12/2007: wsfulton - [Java] Fix #1632625 - Compilation errors on Visual C++ 6 when using directors. - -12/12/2007: wsfulton - [Perl] Fix #1798728 - numbers can be passed to functions taking char *. - -12/12/2007: wsfulton - Fix #1819847 %template with just one default template parameter - - template<typename T = int> class Foo {...}; - %template(FooDefault) Foo<>; - -12/12/2007: mgossage - [Lua] Small correction on Lua.html - -12/09/2007: wsfulton - Apply patch #1838248 from Monty Taylor for vpath builds of SWIG. - -12/08/2007: wsfulton - [Lua] Fixes to remove gcc-4.2 warnings - -12/06/2007: wsfulton - Fix #1734415 - template template parameters with default arguments such as: - - template<typename t_item, template<typename> class t_alloc = pfc::alloc_fast > - class list_t : public list_impl_t<t_item,pfc::array_t<t_item,t_alloc> > { ... }; - -12/04/2007: mgossage - [lua] Fix a bug in the class hierachy code, where the methods were not propagated, - if the name ordering was in a certain order. - Added new example programs (dual, embed) and runtime tests for test-suite. - -11/30/2007: wsfulton - Fix using statements using a base class method where the methods were overloaded. - Depending on the order of the using statements and method declarations, these - were previously generating uncompilable wrappers, eg: - - struct Derived : Base { - virtual void funk(); - using Base::funk; - }; - -Version 1.3.33 (November 23, 2007) -================================== - -11/21/2007: mikel - [allegrocl] omit private slot type info in the classes/types - defined on the lisp side. Fix bug in mapping of C/++ types - to lisp types. Fix typo in modules generated defpackage form. - Have std::string *'s automatically marshalled between foreign - and lisp strings. - -11/20/2007: olly - [Python] Fill in Python Dictionary functions list (patch from - Jelmer Vernooij posted to swig-devel). - -11/20/2007: beazley - Fixed a bug in the C scanner related to backslash characters. - -11/19/2007: wsfulton - [Perl] Fix broken compilation of C++ wrappers on some compilers. - -11/16/2007: olly - [Python] Don't pass Py_ssize_t for a %d printf-like format as - that's undefined behaviour when sizeof(Py_ssize_t) != sizeof(int). - -Version 1.3.32 (November 15, 2007) -================================== - -11/14/2007: wsfulton - [R] Package name and dll name is now the same as the SWIG module - name. It used to be the module name with _wrap as a suffix. The package - and dll names can be modified using the -package and -dll commandline - options. - - *** POTENTIAL INCOMPATIBILITY *** - -11/11/2007: wsfulton - [R] Add support for Windows (Visual C++ 8 tested) - -11/10/2007: olly - [php] Fix makefile generated by -make (SF#1633679). Update - documentation to mark "-make" as deprecated (none of the other - SWIG backends seem to offer such a feature, it can't realistically - generate a fully portable makefile, and the commands to build an - extension are easy enough to write for the user's preferred build - tool). Also recommend against the use of "-phpfull" (it's only - really useful when static linking, and a dynamically loadable - module is virtually always the better approach). - -11/09/2007: olly - Fix --help output to note that `export SWIG_FEATURES' is required. - -10/29/2007: wsfulton - [R] Fix seg fault on Windows - [R] Examples R scripts are now platform independent - -10/30/2007: mgossage - [lua] fixed bug in template classes which cases template_default2 - and template_specialization_defarg to fail. - Added several warning filters into the overload's test cases. - Added runtime tests for several codes. - You can now make check-lua-test-suite with no errors and only a few warnings. - -10/30/2007: olly - [guile] Fix the configure test to put GUILELINK in LIBS not LDFLAGS - (SF#1822430). - -10/30/2007: olly - [guile] Fix the guile examples on 64-bit platforms. - -10/29/2007: wsfulton - [C#] Fix member pointers on 64 bit platforms. - -10/28/2007: olly - [lua] Fix swig_lua_class instances to be static to allow multiple - SWIG wrappers to be compiled into the same executable statically. - Patch from Andreas Fredriksson (posted to the swig mailing list). - -10/28/2007: olly - [lua] Fix Examples/lua to pass SRCS for C tests rather than CXXSRCS. - The code as it was happened to work on x86, but broke on x86_64 (and - probably any other platforms which require -fPIC). - -10/28/2007: wsfulton - [Java, C#] New approach for fixing uninitialised variable usage on error in director - methods using the new templated initialisation function SwigValueInit(). - -10/28/2007: wsfulton - [Perl] Use more efficient SvPV_nolen(x) instead of SvPV(x,PL_na) if SvPV_nolen is - supported. - -10/26/2007: wuzzeb - [Chicken] Fix global variables of class member function pointers. - Other minor fixes, so all tests in the chicken test suite now pass - -10/25/2007: olly - Fix UTL typecheck macro for a function taking char[] or const - char[] (SF#1820132). - -10/22/2007: mkoeppe - [Guile] Filter out -ansi -pedantic from CFLAGS while compiling test programs for Guile - in configure. This enables running the test suite for Guile if it is installed and - usable. - -10/22/2007: mkoeppe - [Guile -scm] Fix testcases apply_signed_char and apply_strings - by adding explicit casts to the appropriate $ltype. - -10/22/2007: wsfulton - [Java, C#] Fix uninitialised variable usage on error in director methods. - -10/19/2007: wsfulton - [Java, C#] Bug #1794247 - fix generated code for derived classes when csbase or javabase - typemaps are used with the replace="1" attribute. - -10/19/2007: wsfulton - [Python] Docs updated to suggest using distutils. Patch #1796681 from Christopher Barker. - -10/19/2007: olly - [perl5] Clear errno before calls to strtol(), strtoul(), strtoll() - and strtoull() which we check errno after to avoid seeing a junk - value of errno if there isn't an error in the call. - -10/16/2007: wsfulton - Deprecate %attribute_ref and replace with %attributeref. There is just an argument - order change in order to maintain consistency with %attribute, from: - - %attribute_ref(Class, AttributeType, AccessorMethod, AttributeName) - to - %attributeref(Class, AttributeType, AttributeName, AccessorMethod) - -10/16/2007: olly - [Tcl] Fix several occurrences of "warning: deprecated conversion - from string constant to 'char*'" from GCC 4.2 in generated C/C++ - code. - -10/16/2007: olly - [PHP] Fix many occurrences of "warning: deprecated conversion from - string constant to 'char*'" from GCC 4.2 in generated C/C++ code - when compiling with a new enough version of PHP 5 (tested with - PHP 5.2.3, but PHP 5.2.1 is probably the minimum requirement). - -10/15/2007: wsfulton - Patch #1797133 from David Piepgrass fixes %attribute when the getter has the same name - as the attribute name and no longer generate non-functional setter for read-only attributes. - -10/15/2007: olly - [Tcl] Prevent SWIG_Tcl_ConvertPtr from calling the unknown proc. - Add Examples/tcl/std_vector/ which this change fixes. Patch - is from "Cliff C" in SF#1809819. - -10/12/2007: wsfulton - [Java] Add DetachCurrentThread back in for directors. See entry dated 08/11/2006 and - search for DetachCurrentThread on the mailing lists for details. The crashes on Solaris - seem to be only present in jdk-1.4.2 and lower (jdk-1.5.0 and jdk-1.6.0 are okay), so - anyone using directors should use a recent jdk on Solaris, or define (see director.swg) - SWIG_JAVA_NO_DETACH_CURRENT_THREAD to the C++ compiler to get old behaviour. - -10/12/2007: wsfulton - [Java] Ensure the premature garbage collection prevention parameter (pgcpp) is generated - when there are C comments in the jtype and jstype typemaps. - -10/12/2007: wuzzeb - Added a testsuite entry for Bug #1735931 - -10/09/2007: olly - Automatically rerun autogen.sh if configure.in is modified. - -10/09/2007: olly - Enhance check-%-test-suite rule and friends to give a more helpful - error message if you try them for a language which doesn't exist - (e.g. "make check-php-test-suite" rather than the correct - "make check-php4-test-suite"). - -10/09/2007: olly - Add make rule to regenerate Makefile from Makefile.in if it has - changed. - -10/09/2007: olly - [php] Fix long-standing memory leak in wrapped constructors and - wrapped functions/methods which return an object. - -10/08/2007: olly - Fix Makefile.in to read check.list files correctly in a VPATH - build. - -10/07/2007: wsfulton - [C#, Java] Experimental shared_ptr typemaps added - -09/27/2007: mgossage - [lua] added more verbose error messages for incorrect typechecks. - Added a routine which checks the exact number of parameters passed to a function - (breaks operator_overloading for unary minus operator, currently disabled). - Reorganised the luatypemaps.swg to tidy it up. - Added a lot of %ignores on the operators not supported by lua. - Added support for constant member function pointers & runtest for member_pointer.i - Added first version of wchar.i - -09/25/2007: wsfulton - [C#, Java] throws typemaps for std::wstring using C# patch #1799064 from David Piepgrass - -09/24/2007: wsfulton - [Tcl] Apply #1771313 to fix bug #1650229 - fixes long long and unsigned long long - handling. - -09/20/2007: olly - [Java] Eliminate some unnecessary uses of a temporary buffer - allocated using new[]. SF#1796609. - -09/19/2007: wsfulton - [C#] The $csinput special variable can be used in the csvarin typemap where it is always - expanded to 'value'. - -09/19/2007: wsfulton - [C#] Fix bug reported by Glenn A Watson and #1795260 where the cstype typemap used the 'ref' - keyword in the typemap body, it produced uncompilable C# properties (variable wrappers). - The type for the property now correctly comes from the 'out' attribute in the cstype typemap. - -09/19/2007: wsfulton - [Java] Fix const std::wstring& typemaps - -09/19/2007: wsfulton - [Java] Ensure the premature garbage collection prevention parameter (pgcpp) is generated - where a parameter is passed by pointer reference, eg in the std::vector wrappers. The pgcpp - is also generated now when user's custom typemaps use a proxy class in the jstype typemap - and a 'long' in the jtype typemap. - -09/18/2007: olly - [php] Add typemaps for handling parameters of type std::string & - which are modified by the wrapped function. - -09/17/2007: olly - [python] Split potentially long string literals to avoid hitting - MSVC's low fixed limit on string literal length - patch from - SF#1723770, also reported as SF#1630855. - -09/17/2007: olly - [ocaml] Fix renaming of overloaded methods in the method_table - - my patch from SF#940399. - -09/17/2007: olly - [python] Simpler code for SWIG_AsVal_bool() which fixes a "strict - aliasing" warning from GCC - patch from SF#1724581 by Andrew - Baumann. - -09/17/2007: olly - [perl5] Use sv_setpvn() to set a scalar from a pointer and length - - patch from SF#174460 by "matsubaray". - -09/17/2007: olly - When wrapping C++ code, generate code which uses - std::string::assign(PTR, LEN) rather than assigning - std::string(PTR, LEN). Using assign generates more efficient code - (tested with GCC 4.1.2). - -09/07/2007: wsfulton - Fix %ignore on constructors which are not explicitly declared [SF #1777712] - -09/05/2007: wuzzeb (John Lenz) - - Change r_ltype in typesys.c to store a hashtable instead of a single value. - several very subtle bugs were being caused by multiple ltypes being mapped - to a single mangled type, mostly when using typedefed template parameters. - Now, r_ltype stores a hashtable of possible ltypes, and when generating the - type table, all the ltypes are added into the swig_type_info structure. - -08/31/2007: wsfulton - SF #1754967 from James Bigler. - - Fix bug in turning on warnings that were turned off by default. Eg 'swig -w+309' will now - turn on the normally suppressed warning 309. - - - New -Wextra commandline option which enables the extra warning numbers: - 202,309,403,512,321,322 (this is the list of warnings that have always been suppressed by - default). By specifying -Wextra, all warnings will be turned on, but unlike -Wall, - warnings can still be selectively turned on/off using %warnfilter, - #pragma SWIG nowarn or further -w commandline options, eg: - swig -Wextra -w309 - will turn on all warnings except 309. - -08/28/2007: wsfulton - - New debugging options, -debug-module <n> and -debug-top <n> to display the parse tree at - various stages, where <n> is a comma separated list of stages 1-4.For example, to - display top of parse tree at stages 1 and 3: - swig -debug-top 1,3 - - - Deprecate the following options which have equivalents below: - -dump_parse_module => -debug-module 1 - -dump_module => -debug-module 4 - -dump_parse_top => -debug-top 1 - -dump_top => -debug-top 4 - - - Renamed some commandline options for naming consistency across all options: - -debug_template => -debug-template - -debug_typemap => -debug-typemap - -dump_classes => -debug-classes - -dump_tags => -debug-tags - -dump_typedef => -debug-typedef - -dump_memory => -debug-memory - -08/25/2007: olly - [PHP5] Fix handling of double or float parameters with an integer - default value. - -08/25/2007: olly - [PHP5] Generate __isset() methods for setters for PHP 5.1 and later. - -08/20/2007: wsfulton - [Java C#] Fix director bug #1776651 reported by Stephane Routelous which occurred when - the director class name is the same as the start of some other symbols used within - the director class. - -08/17/2007: wsfulton - Correct behaviour for templated methods used with %rename or %ignore and the empty - template declaration - %template(). A warning is issued if the method has not been - renamed. - -08/16/2007: mutandiz (Mikel Bancroft) - [allegrocl] Name generated cl file based on input file rather than by - module name. It was possible to end up with a mypackage.cl and a test_wrap.c - when parsing a test.i input file. Confusing. Also, include external-format - templates for :fat and :fat-le automatically to avoid these being compiled - at runtime. - -08/15/2007: efuzzyone - [cffi] Apply patch #1766076 from Leigh Smith adding support for newly introduced - in cffi :long-long and :unsigned-long-long. - -08/10/2007: wsfulton - [Java] Add documentation patch #1743573 from Jeffrey Sorensen. It contains a neat - idea with respect to better memory management by the JVM of C++ allocated memory. - -08/10/2007: wsfulton - [Perl] Apply patch #1771410 from Wade Brainerd to fix typedef XS(SwigPerlWrapper) in - perlrun.swg for ActiveState Perl build 822 and Perl 5.8.9 and 5.10 branches. - -08/10/2007: wsfulton - [Lua] const enum reference typemaps fixed. - -08/09/2007: wsfulton - [C#] Added missing support for C++ class member pointers. - -08/09/2007: wsfulton - [C#, Java] Add support for $owner in the "out" typemaps like in the scripting - language modules. Note that $owner has always been supported in the "javaout" / "csout" - typemaps. - -08/01/2007: wsfulton - Fix smart pointer handling for classes that have templated methods within the smart - pointer type. Problem reported by craigdo at ee.washington.edu. - -07/31/2007: efuzzyone - [cffi] fixed memory access after being freed bug. thanks to Martin Percossi. - package name clos changed to cl. thanks to Ralf Mattes - -07/24/2007: wsfulton - Parallel make support added for the examples and test-suite for developers who have - more than one CPU. Now parallel make can be used for checking in addition to building - the SWIG executable. Some typical checking examples: - - make -j8 -k check - make -j4 check-java-test-suite - make -j2 check-java-examples - -07/19/2007: mgossage - Fixed bug that stopped configure working on mingw (applied dos2unix to configure.in) - -07/10/2007: mgossage - [lua] Extra compatibility with Lua 5.1 (updated SWIG_init, docs, examples, test suite) - Removed name clash for static link of multiple modules - -07/05/2007: mgossage - [lua] Fix a bug in SWIG_ALLOC_ARRAY() - improved the error messages for incorrect arguments. - Changed the output of swig_type() to use the human readable form of the type, - rather than the raw swig type. - -07/03/2007: wsfulton - [C#] Fix directors for some overloaded methods where the imtype resulted in identical - methods being generated in the C# director class, eg void foo(int *) and void foo(double *) - used to generated two of these: - - private void SwigDirectorfoo(IntPtr p) { ... } - -06/25/2007: wsfulton - [Java, C#] Some parameter name changes in std_vector.i allowing better targeting - of typemaps for method parameters (for memory management of containers of pointers). - -06/07/2007: mutandiz (Mikel Bancroft) - [allegrocl] - fix foreign-type constructor to properly look for ffitype typemap - bindings. fix inout_typemaps.i for strings. - -06/06/2007: olly - [Ruby] - Use whichever of "long" or "long long" is the same size as "void*" - to hold pointers as integers, rather than whichever matches off_t. - Fixes compilation on OS X and GCC warnings on platforms where - sizeof(void*) < sizeof(off_t) (SF patch #1731979). - -06/06/2007: olly - [PHP5] - Fix handling of a particular case involving overloaded functions - with default parameters. - -06/05/2007: mutandiz (Mikel Bancroft) - [allegrocl] - Fix case where we'd pass fully qualified identifiers - (i.e. NS1::NS2::FOO) to swig-insert-id. All namespaces - should be stripped. - - Fix bug in TypedefHandler introduced by last fix. - -06/05/2007: olly - Fix reporting of filenames in errors after %include (patch from - Leigh Smith in #1731040; also reported as #1699940). - -05/31/2007: olly - [Python] - Fix "missing initialiser" warning when compiling generated C/C++ - wrapper code with Python 2.5 with warnings enabled (patch from - bug#1727668 from Luke Moore). - -05/29/2007: olly - [Python] - Split docstrings into separate string literals at each newline when - generating C/C++ wrapper code (the C/C++ compiler will just combine - them back into a single string literal). This avoids MSVC - complaining that the strings are too long (problem reported by - Bo Peng on the mailing list). - -05/28/2007: olly - [Python] - Escape backslashes in docstrings. - -05/26/2007: olly - [Python] - Fix autodoc generation of enums to be more consistent with how the - enums are wrapped - patch #1697226 from Josh Cherry. - -05/26/2007: olly - [PHP5] - Fix wrapping of methods and functions which return a pointer to a - class (bug#1700788) and those which have overloaded forms returning - both classes and non-classes (bug#1712717, thanks to Simon - Berthiaume for the patch). - -05/25/2007: wsfulton - Fixed %rename inconsistency in conversion operators as reported by Zhong Ren. The matching - is now done on the operator name in the same way as it is done for parameters. For example: - - %rename(opABC) Space::ABC::operator ABC() const; - %rename(methodABC) Space::ABC::method(ABC a) const; - namespace Space { - class ABC { - public: - void method(ABC a) const {} - operator ABC() const { ABC a; return a; } - }; - } - - Note that qualifying the conversion operator previously may or may not have matched. - Now it definitely won't, so this will not match: - - %rename(opABC) Space::ABC::operator Space::ABC() const; - - in the same way that this does not match: - - %rename(methodABC) Space::ABC::method(Space::ABC a) const; - - The documentation has been improved with respect to %rename, namespaces and templates. - Conversion operators documentation too. - - *** POTENTIAL INCOMPATIBILITY *** - -05/16/2007: mutandiz - [allegrocl] - Fix bad generation of local var ltype's in functionWrapper(). - Try to work better with the backward order in which swig - unrolls nested class definitions. - cleaned up a little unnecessary code/debug printf's. - Remove warning when replacing $ldestructor for ff:foreign-pointer - -05/12/2007: olly - [Python] - swig -python -threads now generates C/C++ code which uses Python's - own threading abstraction (from pythread.h) rather than OS specific - code. The old code failed to compile on MS Windows. (See SF patch - tracker #1710341). - -05/04/2007: gga - [Ruby] - Changed STL renames to be global renames. This fixes - STL functions not being renamed when autorename is on. - This is a not a totally perfect work-around, but better. - Someone really needs to fix the template renaming code. - (See bug #1545634) - -05/04/2007 gga - [All] - Changed %rename("%(undercase)s") a little so that single - numbers at the end of a function are not undercased. That is: - getSomething -> get_something - get2D -> get_2d - get234 -> get_234 - BUT: - asFloat2 -> as_float2 - (Bug #1699714) - -05/03/2007: gga - [Ruby] - Made __swigtype__ => @__swigtype__ so it can be accessed - from the scripting language (and follows Ruby's official - documentation, just in case). - Made tracking => @__trackings__ for same reason. - Currently storing ivars without the @ seems valid, but - the PickAxe says this is not correct, so just in case... - -05/03/2007: gga - [Ruby] - Applied patch for -minherit bug and exception classes. - This issue should be revisited more closely, as Multiple - Inheritance in Ruby is still problematic. - (patch/bug #1604878) - -05/03/2007: gga - [Ruby] - Overloaded functions in ruby will now report to the user - the possible prototypes when the user mistypes the number or - type of a parameter. - -05/03/2007: gga - [Ruby] - Forgot to document the bug fixing of an old bug regarding - exceptions. - (bug #1458247) - -05/03/2007: gga - [Ruby] - Fixed Ruby documentation to use the proper css styles for - each section. Added autodoc section to Ruby's docs to - document the features supported by Ruby in documenting its modules. - Made rdoc documentation spit out the full name of the class + - method name. Albeit this will make the current rdoc not recognize - the method, this is still needed to disambiguate between different - classes with similar methods (rdoc was created to document the - ruby source which only contains one class per c file, unlike swig) - I have patched rdoc to make it more friendly to swig. This - patch needs to be merged in the ruby std library now. - -05/03/2007: gga - [Ruby] - Changed flag -feature to be -init_name to better reflect its - purpose and avoid confusion with -features. - -05/03/2007: gga - [Ruby] - Improved autodoc generation. - Added autodoc .swg files to Ruby library for easily adding - documentation to common Ruby methods and STL methods. - Fixed autodoc documenting of getters and setters and module. - Made test suite always generate autodocs. - -05/03/2007: gga - [Ruby] - Removed some warnings from STL and test suite. - -05/02/2007: mgossage - [Lua] Fixed issues with C++ classes and hierachies across multiple - source files. Fixed imports test case & added run test. - Added Examples/imports. - Added typename for raw lua_State* - Added documentation on native functions. - -05/02/2007: gga - [Ruby] - Docstrings are now supported. - %feature("autodoc") and %feature("docstring") are now - properly supported in Ruby. These features will generate - a _wrap.cxx file with rdoc comments in them. - -05/02/2007: gga - [Ruby] - STL files have been upgraded to follow the new swig/python - Lib/std conventions. - This means std::vector, std::set, std::map, set::multimap, - std::multiset, std::deque and std::string are now properly - supported, including their iterators, support for containing - ruby objects (swig::GC_VALUE) and several other ruby - enhancements. - std::complex, std::ios, std::iostream, std::iostreambuf and - std::sstream are now also supported. - std::wstring, std::wios, std::wiostream, std::wiostreambuf - and std::wsstream are supported verbatim with no unicode - conversion. - - std_vector.i now mimics the behavior of Ruby Arrays much more - closely, supporting slicing, shifting, unshifting, - multiple indexing and proper return values on assignment. - - COMPATABILITY NOTE: this changes the older api a little bit in - that improper indexing would previously (incorrectly) raise - exceptions. Now, nil is returned instead, following ruby's - standard Array behavior. - -05/02/2007: gga - [Ruby] - Changed the value of SWIG_TYPECHECK_BOOL to be 10000 (ie. higher - than that of all integers). - This is because Ruby allows typecasting - integers down to booleans which can make overloaded functions on - bools and integers to fail. - (bug# 1488142) - -05/02/2007: gga - [Ruby] - Fixed a subtle bug in multiple argouts that could get triggered if - the user returned two or more arguments and the first one was an - array. - -05/01/2007: gga - [Ruby] - Improved the documentation to document the new features - added, add directorin/out/argout typemaps, etc. - -05/01/2007: gga - [Ruby] - Added %initstack and %ignorestack directives for director - functions. These allow you to control whether a director - function should re-init the Ruby stack. - This is sometimes needed for an embedded Ruby where the - director method is used as a C++ callback and not called - by the user from ruby code. - Explanation: - Ruby's GC needs to be aware of the running OS stack in order to - mark any VALUE (Ruby objects) it finds there to avoid collection - of them. This allows the ruby API to be very simple and allows - you to write code like "VALUE a = sth" anywhere without needing - to do things like refcounting like python. - By default, the start of the stack is set when ruby_init() is - called. If ruby is inited within main(), as it usually is the - case with the main ruby executable, ruby will be able to calculate - its stack properly. However, when this is not possible, as when - ruby is embedded as a plugin to an application where main is not - available, ruby_init() will be called in the wrong place, and - ruby will be incorrectly tracking the stack from the function - that called ruby_init() forwards only, which can lead to - all sorts of weird crashes or to ruby thinking it has run out of - stack space incorrectly. - To avoid this, director (callback) functions can now be tagged - to try to reset the ruby stack, which will solve the issues. - NOTE: ruby1.8.6 still contains a bug in it in that its function - to reset the stack will not always do so. This bug is triggered - very rarely, when ruby is called from two very distinct places - in memory, like a branch of main() and another dso. This bug - has now been reported to ruby-core and is pending further - investigation. - (bug #1700535 and patch #1702907) - -04/30/2007: wsfulton - Fix #1707582 - Restore building from read-only source directories. - -04/30/2007: gga - [Ruby] - Ruby will now report the parameter index properly on type - errors as well as the class and value of the incorrect - argument passed. - (feature request #1699670) - -04/30/2007: gga - [Ruby] - Ruby no longer creates the free_Class function if the class - contains its own user defined free function (%freefunc). - (bug #1702882) - -04/30/2007: gga - [Ruby] - Made directors raise a ruby exception for incorrect argout - returned values if RUBY_EMBEDDED is set, instead of throwing - an actual SwigDirector exception. - This will prevent crashes when ruby is embedded and unaware - of the SwigDirector exception. - -04/30/2007: gga - [Ruby] - Removed the need for -DSWIGEXTERN. - Changed swig_ruby_trackings to be a static variable, but also - be kept within a hidden instance variable in the SWIG module. - This allows properly dealing with trackings across multiple - DSOs, which was previously broken. - (bug #1700535 and improvement to patch #1702907) - -04/29/2007: gga - [Ruby] Fixed GC memory issues with trackings that could lead - to segfaults when dealing, mainly, with static variables. - (bug #1700535 and patch #1702907) - -04/29/2007: gga - [Ruby] - Fixed String conversion using old ruby1.6 macros. Now - StringValuePtr() is used if available. This removes warnings - when converting strings with \0 in them. - (bug #1700535 and patch #1702907) - -04/29/2007: gga - [Ruby] - Fixed the argout count in directors for Ruby. Previously, - ignored or "numinputs=0" typemaps would incorrectly not get - counted towards the argout count. - (bug/patch #1545585) - -04/29/2007: gga - [Ruby] - Upgraded Ruby converter to recognize "numinputs=0". Previously, - only the old "ignore" flag was checked (which would currently - still work properly, but is deprecated). - -04/29/2007: gga - [Ruby - but should be made generic] - - %feature("numoutputs","0") added. - - This feature allows you to ignore the output of a function so - that it is not added to a list of output values - ( ie. argouts ). - This should also become a feature of %typemap(directorout) - as "numoutputs"=0, just like "numinputs"=0 exists. - - %feature("directors"=1) - - %include <typemaps.i> - - %feature("numoutputs","0") { Class::member_function1 }; - %typemap(out) MStatus { // some code, like check mstatus - // and raise exception if wrong }; - - %inline %{ - typedef int MStatus; - class Class { - - // one argument returned, but director out code added - // MStatus is discarded as a return (out) parameter. - virtual MStatus member_function1( int& OUTPUT ); - - // two arguments returned, director out code added - // MStatus is not discarded - virtual MStatus member_function2( int& OUTPUT ); - }; - %} - - -04/21/2007: olly - Fix parsing of float constants with an exponent (e.g. 1e-02f) - (bug #1699646). - -04/20/2007: olly - [Python] Fix lack of generation of docstrings when -O is used. - Also, fix generation of docstrings containing a double quote - character. Patch from Richard Boulton in bug#1700146. - -04/17/2007: wsfulton - [Java, C#] Support for adding in Java/C# code before and after the intermediary call, - specifically related to the marshalling of the proxy type to the intermediary type. - The javain/csin typemap now supports the 'pre' and 'post' attributes to achieve this. - The javain typemap also supports an optional 'pgcppname' attribute for premature garbage - collection prevention parameter naming and the csin typemap supports an optional 'cshin' - attribute for the parameter type used in a constructor helper generated when the type is used - in a constructor. Details in the Java.html and CSharp.html documentation. - -04/16/2007: olly - Don't treat `restrict' as a reserved identifier in C++ mode - (bug#1685534). - -04/16/2007: olly - [PHP5] Fix how zend_throw_exception() is called (bug #1700785). - -04/10/2007: olly - Define SWIGTEMPLATEDISAMBIGUATOR to template for aCC (reported on - swig-user that this is needed). - -04/04/2007: olly - [PHP5] If ZTS is enabled, release <module>_globals_id in MSHUTDOWN - to avoid PHP interpreter crash on shutdown. This solution was - suggested here: http://bugs.php.net/bug.php?id=40985 - -04/03/2007: olly - [PHP4] Add missing ZTS annotations to generated C++ wrapper code - to fix compilation failures when using ZTS enabled SWIG (Linux - distributions tend to disable ZTS, but notably the Windows build - uses it by default). - -04/01/2007: efuzzyone - [CFFI] Patch #1684261: fixes handling of unsigned int literals, thanks Leigh Smith. - Also, improved documentation. - -03/30/2007: olly - Avoid generating '<:' token when using SwigValueWrapper<> on a type - which starts with '::' (patch #1690948). - -03/25/2007: wuzzeb (John Lenz) - [perl5] Add SWIG_fail to the SWIG_exception macro. Fixes a few problems reported - on the mailing list. - -03/23/2007: wsfulton - String copying patch from Josh Cherry reducing memory consumption by about 25%. - -03/21/2007: wsfulton - [Java] Apply patch #1631987 from Ulrik Peterson - bool INOUT typemaps - fail on big endian machines. - -03/16/2007: wsfulton - Fix seg fault given dodgy C++ code: namespace abc::def { } - -03/16/2007: wsfulton - [Java] Fixes so that ARRAYSOFCLASSES and ARRAYSOFENUMS in arrays_java.i can be applied - to pointer types. - -03/03/2007: olly - [PHP5] When we know the literal numeric value for a constant, use - that to initialise the const member in the PHP wrapper class. - -03/02/2007: olly - [PHP5] Fix PHP wrapper code generated for certain cases of - overloaded forms with default arguments. - -02/26/2007: efuzzyone - [CFFI] Patch #1656395: fixed hex and octal values bug, thanks to Arthur Smyles. - -02/22/2007: mgossage - [Lua] Fixed bug in typemaps which caused derived_byvalue and rname test cases to fail. - Updated derived_byvalue.i to explain how to find and fix the problem - -01/25/2007: wsfulton - Fix #1538522 and #1338527, forward templated class declarations without a - name for the templated class parameters, such as: - - template <typename, class> class X; - -01/23/2007: mgossage - [Lua] Patch #1640862: <malloc.h> replaced by <stdlib.h> - Patch #1598063 Typo in typemaps.i - -01/22/2007: mgossage - [Lua] Added a lua specific carrays.i which adds the operator[] support. - modified the main code to make it not emit all the class member functions & accessors - Note: C structs are created using new_XXX() while C++ classes use XXX() (should be standardised) - Updated test case: li_carrays - Updated the documentation. - -01/12/2007: wsfulton - [Php] Add support for newfree typemaps (sometimes used by %newobject) - -01/12/2007: beazley - New command line option -macroerrors. When supplied, this will force - the C scanner/parser to report proper location information for code contained - inside SWIG macros (defined with %define). By default, SWIG merely reports - errors on the line at which a macro is used. With this option, you - can expand the error back to its source---something which may simplify - debugging. - -01/12/2007: beazley - [Internals] Major overhaul of C/C++ scanning implementation. For quite - some time, SWIG contained two completely independent C/C++ tokenizers-- - the legacy scanner in CParse/cscanner.c and a general purpose scanner - in Swig/scanner.c. SWIG still has two scanning modules, but the C parser - scanner (CParse/cscanner.c) now relies upon the general purpose - scanner found in Swig/scanner.c. As a result, it is much smaller and - less complicated. This change also makes it possible to maintain all - of the low-level C tokenizing in one central location instead of two - places as before. - - ***POTENTIAL FLAKINESS*** - This change may cause problems with accurate line number reporting - as well as error reporting more generally. I have tried to resolve this - as much as possible, but there might be some corner cases. - -01/12/2007: mgossage - [Lua] Added typemap throws for std::string*, typemap for SWIGTYPE DYNAMIC, - changed the existing throws typemap to throw a string instead of making a copy of - the object (updating a few test cases to deal with the change). - fixed test case: dynamic_casts, exception_partial_info, li_std_string, size_t - -01/03/2007: beazley - [Internals]. Use of swigkeys.c/.h variables is revoked. Please use - simple strings for attribute names. - -12/30/2006: beazley - Internal API functions HashGetAttr() and HashCheckAttr() have been revoked. - Please use Getattr() to retrieve attributes. The function Checkattr() can - be used to check attributes. Note: These functions have been revoked - because they only added a marginal performance improvement at the expense - code clarity. - -12/26/2006: mgossage - [Lua] Added more STL (more exceptions, map, size_t), - fixed test case: conversion_ns_template. - -12/21/2006: mgossage - [Lua] Update to throw errors when setting immutables, - and allowing user addition of module variables. - -12/20/2006: wsfulton - Fix typedef'd variable wrappers that use %naturalvar, eg, std::string. - -12/14/2006: wsfulton - [C#] Add std::wstring and wchar_t typemaps - -12/14/2006: olly - [php] Fix bug #1613673 (bad PHP5 code generated for getters and - setters). - -12/02/2006: wsfulton, John Lenz, Dave Beazley - Move from cvs to Subversion for source control - -11/30/2006: beazley - Cleaned up swigwarnings.swg file not to use nested macro - definitions. - -11/12/2006: wsfulton - [Java, C#] Fix for %extend to work for static member variables. - -Version 1.3.31 (November 20, 2006) -================================== - -11/12/2006: Luigi Ballabio - [Python] Alternate fix for Python exceptions bug #1578346 (the previous one broke Python - properties in modern classes) - -11/12/2006: wsfulton - -fakeversion commandline option now generates the fake version into the generated wrappers - as well as displaying it when the -version commandline option is used. - -14/11/2006: mgossage - [lua] update to typemap for object by value, to make it c89 compliant - -Version 1.3.30 (November 13, 2006) -================================== - -11/12/2006: wsfulton - [java] Remove DetachCurrentThread patch from 08/11/2006 - it causes segfaults - on some systems. - -11/12/2006: wsfulton - [python] Fix #1578346 - Python exceptions with -modern - -11/10/2006: wsfulton - Fix #1593291 - Smart pointers and inheriting from templates - -11/09/2006: wsfulton - Fix director operator pointer/reference casts - #1592173. - -11/07/2006: wsfulton - Add $self special variable for %extend methods. Please use this instead of just 'self' - as the C++ 'this' pointer. - -11/07/2006: mutandiz - [allegrocl] - allegrocl.swg: swig-defvar updated to allow specifying of - non-default foreign type (via :ftype keyword arg). - allegrocl.cxx: Specify proper access type for enum values. - -11/03/2006: wsfulton - [Java/C#] Fix const std::string& return types for directors as reported by - Mark Donselzmann - -10/29/2006: wsfulton - [Java] Remove DeleteLocalRef from end of director methods for now as it is causing a - seg fault when run on Solaris 8. - -10/29/2006: wuzzeb (John Lenz) - [Guile] Patch from Chris Shoemaker to clean up some warnings in the generated code. - -10/29/2006: wsfulton - [Java] Important fix to prevent early garbage collection of the Java proxy class - while it is being used in a native method. The finalizer could destroy the underlying - C++ object while it was being used. The problem occurs when the proxy class is no - longer strongly reachable after a native call. The problem seems to occur in - memory stress situations on some JVMs. It does not seem to occur on the - Sun client JVM up to jdk 1.5. However the 1.6 client jdk has a more aggressive garbage - collector and so the problem does occur. It does occur on the Sun server - JVMs (certainly 1.4 onwards). The fix entails passing the proxy class into the native - method in addition to the C++ pointer in the long parameter, as Java classes are not - collected when they are passed into JNI methods. The extra parameter can be suppressed - by setting the nopgcpp attribute in the jtype typemap to "1" or using the new -nopgcpp - commandline option. - - See Java.html#java_pgcpp for further details on this topic. - -10/24/2006: wsfulton - [C#] Fix smart pointer wrappers. The virtual/override/new keyword is not generated - for each method as the smart pointer class does not mirror the underlying pointer - class inheritance hierarchy. SF #1496535 - -10/24/2006: mgossage - [lua] added support for native methods & member function pointers. - fixed test cases arrays_dimensionless & cpp_basic. Added new example (functor). - tidied up a little of the code (around classHandler). - -10/17/2006: wsfulton - [C#, Java] directorout typemap changes to fall in line with the other director - languages. $result is now used where $1 used to be used. Please change your typemaps - if you have a custom directorout typemap. - -10/18/2006: wsfulton - Some fixes for applying the char array typemaps to unsigned char arrays. - -10/17/2006: wsfulton - [C#, Java] Add in const size_t& and const std::size_t& typemaps. - -10/15/2006: efuzzyone - [CFFI] Suppress generating defctype for enums, thanks to Arthur Smyles. Patch 1560983. - -10/14/2006: wuzzeb (John Lenz) - [Chicken] Minor fix to make SWIG work with the (as yet unreleased) chicken 2.5 - - [Guile,Chicken] Fix SF Bug 1573892. Added an ext_test to the test suite to test - this bug, but this test can not really be made generic because the external code must - plug into the target language interpreter directly. - See Examples/test-suite/chicken/ext_test.i and ext_test_external.cxx - - Added a %.externaltest to common.mk, and any interested language modules can - copy and slightly modify either the chicken or the guile ext_test.i - -10/14/2006: mgossage - [Lua] added OUTPUT& for all number types, added a long long type - fixed several test cases. - update: changed typemaps to use SWIG_ConvertPtr rather than SWIG_MustGetPointer - started spliting lua.swg into smaller parts to make it neater - -10/13/2006: wsfulton - [C#, Java] Marginally better support for multiple inheritance only in that you can - control what the base class is. This is done using the new 'replace' attribute in the - javabase/csbase typemap, eg in the following, 'Me' will be the base class, - no matter what Foo is really derived from in the C++ layer. - - %typemap(javabase, replace="1") Foo "Me" - %typemap(csbase, replace="1") Foo "Me" - - Previously it was not possible for the javabase/csbase typemaps to override the C++ base. - -10/12/2006: wsfulton - [Java] Remove potential race condition on the proxy class' delete() method - (it is now a synchronized method, but is now customisable by changing the - methodmodifiers attribute in the javadestruct or javadestruct_derived typemap) - - [C#] Remove potential race condition on the proxy class' Dispose() method, - similar to Java's delete() above. - - *** POTENTIAL INCOMPATIBILITY *** - -10/12/2006: wsfulton - [Ruby, Python] Remove redundant director code in %extend methods (%extend - methods cannot be director methods) - -10/12/2006: wsfulton - [Ruby, Python] Fix #1505594 - director objects not returned as director objects - in %extend methods. - -10/11/2006: wsfulton - [Java] Fix #1238798 - Directors using unsigned long long or any other type - marshalled across the JNI boundary using a Java class (where the jni typemap - contains jobject). - -10/06/2006: wsfulton - Fix #1162194 - #include/%include within a structure - -10/06/2006: wsfulton - Fix #1450661, string truncation in String_seek truncating Java/C# enums. - -10/06/2006: mgossage - [Lua] Fix #1569587. The name is now correct. - -10/04/2006: wsfulton - Director fixes for virtual conversion operators - -10/04/2006: olly - [php] Fix #1569587 for PHP. Don't use sizeof() except with string - literals. Change some "//" comments to "/* */" for portability. - -10/04/2006: mgossage - [Lua] Partial Fix #1569587. The type is now correct, but the name is still not correct. - -10/03/2006: wsfulton - [Ruby] Fix #1527885 - Overloaded director virtual methods sometimes produced - uncompilable code when used with the director:except feature. - -10/03/2006: wsfulton - Directors: Directors are output in the order in which they are declared in - the C++ class rather than in some pseudo-random order. - -10/03/2006: mmatus - Fix #1486281 and #1471039. - -10/03/2006: olly - [Perl] Fix for handling strings with zero bytes from Stephen Hutsal. - -09/30/2006: efuzzyone - [CFFI] Bitfield support and vararg support due to Arthur Smyles. - C expression to Lisp conversion, thanks to Arthur Smyles for the initial - idea, it now supports conversion for a whole range of C expressions. - -09/28/2006: wsfulton - Fix #1508327 - Overloaded methods are hidden when using -fvirtual optimisation. - Overloaded methods are no longer candidates for elimination - this mimics - C++ behaviour where all overloaded methods must be defined and implemented - in a derived class in order for them to be available. - -09/25/2006: wsfulton - [Ruby, Python, Ocaml] Fix #1505591 Throwing exceptions in extended directors - -09/25/2006: wsfulton - Fix #1056100 - virtual operators. - -09/24/2006: olly - Don't accidentally create a "<:" token (which is the same as "[" in C++). - Fixes bug # 1521788. - -09/23/2006: olly - [Ruby] Support building with recent versions of the Ruby 1.9 - development branch. Fixes bug #1560092. - -09/23/2006: olly - Templates can now be instantiated using negative numbers and - constant expressions, e.g.: - - template<int q> class x {}; - %template(x_minus1) x<-1>; - %template(x_1plus2) x<1+2>; - - Also, constant expressions can now include comparisons (>, <, >=, - <=, !=, ==), modulus (%), and ternary conditionals (a ? b : c). - - Fixes bugs #646275, #925555, #956282, #994301. - -09/22/2006: wsfulton - Fix %ignore on director methods - Bugs #1546254, #1543533 - -09/20/2006: wsfulton - Fix %ignore on director constructors - -09/20/2006: wsfulton - Fix seg faults and asserts when director methods are ignored (#1543533) - -09/20/2006: wsfulton - Fix out of source builds - bug #1544718 - -09/20/2006: olly - Treat a nested class definition as a forward declaration rather - than ignoring it completely, so that we generate correct code for - passing opaque pointers to the nested class (fixes SF bug #909387). - -09/20/2006: olly - *** POTENTIAL INCOMPATIBILITY *** - [php] Overload resolution now works. However to allow this, SWIG - generated wrappers no longer coerce PHP types (which reverts a change - made in 1.3.26). So for example, if a method takes a string, you - can no longer pass a number without explicitly converting it to a - string in PHP using: (string)x - -09/18/2006: mgossage - [ALL] fix on swiginit.swg, has been reported to crash on several test cases - found and fixed problem in imports under python (mingw) - -09/16/2006: wsfulton - [Python] Patch from Michal Marek for Python 2.5 to fix 64 bit array indexes on - 64 bit machines. - -09/13/2006: wsfulton - The explicitcall feature has been scrapped. This feature was introduced primarily - to solve recursive director method calls. Director upcall improvements made instead: - - [Python, Ruby, Ocaml] The swig_up flag is no longer used. The required mutexes - wrapping this flag are also no longer needed. The recursive calls going from C++ - to the target language and back again etc are now avoided by a subtlely different - approach. Instead of using the swig_up flag in each director method to indicate - whether the explicit C++ call to the appropriate base class method or a normal - polymorphic C++ call should be made, the new approach makes one of these calls - directly from the wrapper method. - - [Java, C#] The recursive call problem when calling a C++ base class method from - Java/C# is now fixed. The implementation is slightly different to the other languages - as the detection as to whether the explicit call or a normal polymorphic call is made - in the Java/C# layer rather than in the C++ layer. - -09/11/2006: mgossage - [ALL] updated swiginit.swg to allow multiple interpreters to use multiple - swig modules at once. This has been tested in Lua (mingw & linux), - perl5 & python (linux) only. - -09/11/2006: mgossage - [lua] added support for passing function pointers as well as native lua object - into wrappered function. - Added example funcptr3 to demonstrate this feature - -09/05/2006: olly - [php] Rename ErrorCode and ErrorMsg #define-s to SWIG_ErrorCode - and SWIG_ErrorMsg to avoid clashes with code the user might be - wrapping (patch from Darren Warner in SF bug #1466086). Any - user typemaps which use ErrorCode and/or ErrorMsg directly will - need adjusting - you can easily fix them to work with both old - and new SWIG by changing to use SWIG_ErrorMsg and adding: - - #ifndef SWIG_ErrorMsg - #define SWIG_ErrorMsg() ErrorMsg() - #endif - -08/29/2006: olly - [php] Move constant initialisation from RINIT to MINIT to fix a - warning when using Apache and mod_php. We only need to create - PHP constants once when we're first initialised, not for every HTTP - request. - -08/21/2006: mgossage - [Lua] - Bugfix #1542466 added code to allow mapping Lua nil's <-> C/C++ NULL's - updated various typemaps to work correctly with the changes - added voidtest_runme.lua to show the features working - -08/19/2006: wuzzeb (John Lenz) - [Guile] Add feature:constasvar to export constants as variables instead of functions - that return the constant value. - -08/11/2006: wsfulton - [Java] DetachCurrentThread calls have been added so that natively created threads - no longer prevent the JVM from exiting. Bug reported by Thomas Dudziak and - Paul Noll. - -08/10/2006: wsfulton - [C#] Fix director protected methods so they work - -07/25/2006: mutandiz - [allegrocl] - more additions to std::string, some tweaks and small bug fixes - -nocwrap mode. - -07/21/2006: mgossage - [Lua] - Bugfix #1526022 pdated std::string to support strings with '\0' inside them - updated typemaps.i to add support for pointer to pointers - -07/19/2006: mutandiz - [allegrocl] - - Add std_string.i support. - - Add newobject patch submitted by mkoeppe (thanks!) - - Fix type name mismatch issue for nested type definitions. - specifically typedefs in templated class defns. - -07/18/2006: mgossage - Bugfix #1522858 - updated lua.cxx to support -external-runtime command - -07/14/2006: wuzzeb (John Lenz) - Increment the SWIG_RUNTIME_VERSION to 3, because of the - addition of the owndata member in swig_type_info. - Reported by: Prabhu Ramachandran - -07/05/2006: wsfulton - Search path fixes: - - Fix search path for library files to behave as documented in Library.html. - - Fix mingw/msys builds which did not find the SWIG library when installed. - - Windows builds also output the mingw/msys install location when running - swig -swiglib. - - The non-existent and undocumented config directory in the search path has - been removed. - -07/05/2006: wsfulton - Fix $symname special variable expansion. - -07/04/2006: wuzzeb (John Lenz) - [Chicken] - Add %feature("constasvar"), which instead of exporting a constant as a - scheme function, exports the constant as a scheme variable. Update the - documentation as well. - -07/04/2006: wsfulton - [See entry of 09/13/2006 - explicitcall feature and documentation to it removed] - New explicitcall feature which generates additional wrappers for virtual methods - that call the method explicitly, not relying on polymorphism to make the method - call. The feature is a feature flag and is enabled like any other feature flag. - It also recognises an attribute, "suffix" for mangling the feature name, see - SWIGPlus.html#SWIGPlus_explicitcall documentation for more details. - - [Java, C#] - The explicitcall feature is also a workaround for solving the recursive calls - problem when a director method makes a call to a base class method. See - Java.html#java_directors_explicitcall for updated documentation. - -06/28/2006: joe (Joseph Wang) - [r] Initial support for R - -06/20/2006: wuzzeb (John Lenz) - [Chicken] - Minor fixes to get apply_strings.i testsuite to pass - Remove integers_runme.scm from the testsuite, because SWIG and Chicken does - handle overflows. - -06/19/2005: olly - [php] Add support for generating PHP5 class wrappers for C++ - classes (use "swig -php5"). - -06/17/2006: olly - [php] Added some missing keywords to the PHP4 keyword list, and - fixed __LINE__ and __FILE__ which were in the wrong category. - Also added all the keywords new in PHP5, and added comments - noting the PHP4 keywords which aren't keywords in PHP5. - -06/17/2006: olly - [php] Don't segfault if PHP Null is passed as this pointer (e.g. - Class_method(Null)) - give a PHP Error instead. - -06/15/2006: mutandiz - [allegrocl] - Add initial support for std::list container class. - Fix a few bugs in helper functions. - -05/13/2006: wsfulton - [Java] Replace JNIEXPORT with SWIGEXPORT, thereby enabling the possibility - of using gcc -fvisibility=hidden for potentially smaller faster loading wrappers. - -05/13/2006: wsfulton - Fix for Makefiles for autoconf-2.60 beta - -05/13/2006: wsfulton - Vladimir Menshakov patch for compiling wrappers with python-2.5 alpha. - -05/12/2006: wsfulton - Fix buffer overflow error when using large %feature(docstring) reported - by Joseph Winston. - -05/12/2006: wsfulton - [Perl] Operator overload fix from Daniel Moore. - -05/25/2006: mutandiz - [allegrocl] - Fix bug in generation of CLOS type declarations for unions - and equivalent types. - -05/24/2006: mutandiz - [allegrocl] - Don't require a full class definition to generate a CLOS wrapper. - -05/20/2006: olly - [php] GCC Visibility support now works with PHP. - -05/19/2006: olly - [php] Removed support for -dlname (use -module instead). Fixed - naming of PHP extension module to be consistent with PHP - conventions (no "php_" prefix on Unix; on PHP >= 4.3.0, handle Unix - platforms which use something other than ".so" as the extension.) - -05/13/2006: wsfulton - [C#] Director support added - -05/07/2006: olly - [php] Don't segfault if PHP Null is passed where a C++ reference - is wanted. - -05/05/2006: olly - [php] Fix wrappers generated for global 'char' variables to not - include a terminating zero byte in the PHP string. - -05/03/2006: wsfulton - Modify typemaps so that char * can be applied to unsigned char * or signed char * - types and visa versa. - -05/03/2006: efuzzyone - [cffi]Thanks to Luke J Crook for this idea. - - a struct/enum/union is replaced with :pointer only if - that slot is actually a pointer to that type. So,: - struct a_struct { int x; } and - struct b_struct { a_struct struct_1; }; - will be converted as: - (cffi:defcstruct b_struct - (struct_1 a_struct)) - - Other minor fixes in lispifying names. - -05/02/2006: wsfulton - Fix possible redefinition of _CRT_SECURE_NO_DEPRECATE for VC++. - -04/14/2006: efuzzyone - [cffi] - Thanks to Thomas Weidner for the patch. - - when feature export is set (export 'foo) is - generated for every symbol - - when feature inline is set (declaim (inline foo)) is - generated before every function definition - - when feature intern_function is set - #.(value-of-intern-function "name" "nodeType" package) - is emitted instead of the plain symbol. A sample swig-lispify - is provided. - - every symbol is prefixed by it's package. - -04/13/2006: efuzzyone - [cffi] - Fixed the generation of wrappers for global variables. - Added the option [no]swig-lisp which turns on/off generation - of code for swig helper lisp macro, functions, etc. - -Version 1.3.29 (March 21, 2006) -=============================== - -04/05/2006: mutandiz - [allegrocl] - Fix output typemap of char so it produces a character instead - of an integer. Also adds input/output typemaps for 'char *'. - - add command-line argument -isolate to generate an interface - file that won't interfere with other SWIG generated files that - may be used in the same application. - -03/20/2005: mutandiz - [allegrocl] - More tweaks to INPUT/OUTPUT typemaps for bool. - - Fix constantWrapper for char and string literals. - - find-definition keybindings should work in ELI/SLIME. - Output (in-package <module-name>) to lisp wrapper - instead of (in-package #.*swig-module-name*). - - slight rework of multiple return values. - - doc updates. - -03/17/2005: mutandiz - [allegrocl] - mangle names of constants generated via constantWrapper. - - When using OUTPUT typemaps and the function has a non-void - return value, it should be first in the values-list, followed - by the OUTPUT mapped values. - - Fix bug with boolean parameters, which needed to be - passed in as int values, rather than T or NIL. - -03/15/2006: mutandiz - [allegrocl] - Generate wrappers for constants when in C++ or -cwrap mode. - Make -cwrap the default, since it is most correct. Users - can use the -nocwrap option to avoid the creation of a .cxx - file when interfacing to C code. - - When in -nocwrap mode, improve the handling of converting - infix literals to prefix notation for lisp. This is very - basic and not likely to be improved upon since this only - applies to the -nocwrap case. Literals we can't figure out - will result in a warning and be included in the generated - code. - - validIdentifier now more closely approximates what may be - a legal common lisp symbol. - - Fix typemap error in allegrocl.swg - -03/12/2006: mutandiz - [allegrocl] - fix up INPUT/OUTPUT typemaps for bool. - Generate c++ style wrapper functions for struct/union members - when -cwrap option specified. - -03/10/2006: mutandiz - [allegrocl] - Fix bug in C wrapper generation introduced by last allegrocl - commit. - -03/10/2006: wsfulton - [Java] - Commit #1447337 - Delete LocalRefs at the end of director methods to fix potential leak - -03/10/2006: wsfulton - Fix #1444949 - configure does not honor --program-prefix. - Removed non-standard configure option --with-release-suffix. Fix the autoconf standard - options --program-prefix and --program-suffix which were being shown in the help, - but were being ignored. Use --program-suffix instead of --with-release-suffix now. - -03/10/2006: wsfulton - [Java] - Fix #1446319 with patch from andreasth - more than one wstring parameter in director methods - -03/07/2006: mkoeppe - [Guile] - Fix for module names containing a "-" in non-"shadow" mode. - Patch from Aaron VanDevender (#1441474). - -03/04/2006: mmatus - - Add -O to the main program, which now enables -fastdispatch - - [Python] - - - Add the -fastinit option to enable faster __init__ - methods. Setting 'this' as 'self.this.append(this)' in the python - code confuses PyLucene. Now the initialization is done in the - the C++ side, as reported by Andi and Robin. - - - Add the -fastquery option to enable faster SWIG_TypeQuery via a - python dict cache, as proposed by Andi Vajda - - - Avoid to call PyObject_GetAttr inside SWIG_Python_GetSwigThis, - since this confuses PyLucene, as reported by Andi Vajda. - -03/02/2006: wsfulton - [Java] - Removed extra (void *) cast when casting pointers to and from jlong as this - was suppressing gcc's "dereferencing type-punned pointer will break strict-aliasing rules" - warning. This warning could be ignored in versions of gcc prior to 4.0, but now the - warning is useful as gcc -O2 and higher optimisation levels includes -fstrict-aliasing which - generates code that doesn't work with these casts. The assignment is simply never made. - Please use -fno-strict-aliasing to both suppress the warning and fix the bad assembly - code generated. Note that the warning is only generated by the C compiler, but not - the C++ compiler, yet the C++ compiler will also generate broken code. Alternatively use - -Wno-strict-aliasing to suppress the warning for gcc-3.x. The typemaps affected - are the "in" and "out" typemaps in java.swg and arrays_java.swg. Users ought to fix - their own typemaps to do the same. Note that removal of the void * cast simply prevents - suppression of the warning for the C compiler and nothing else. Typical change: - - From: - %typemap(in) SWIGTYPE * %{ $1 = *($&1_ltype)(void *)&$input; %} - To: - %typemap(in) SWIGTYPE * %{ $1 = *($&1_ltype)&$input; %} - - From: - %typemap(out) SWIGTYPE * %{ *($&1_ltype)(void *)&$result = $1; %} - To: - %typemap(out) SWIGTYPE * %{ *($&1_ltype)&$result = $1; %} - -03/02/2006: mkoeppe - [Guile -scm] - Add typemaps for "long long"; whether the generated code compiles, however, depends - on the version and configuration of Guile. - -03/02/2006: wsfulton - [C#] - Add support for inner exceptions. If any of the delegates are called which construct - a pending exception and there is already a pending exception, it will create the new - exception with the pending exception as an inner exception. - -03/02/2006: wsfulton - [Php] - Added support for Php5 exceptions if compiling against Php5 (patch from Olly Betts). - -03/01/2006: mmatus - Use the GCC visibility attribute in SWIGEXPORT. - - Now you can compile (with gcc 3.4 or later) using - CFLAGS="-fvisibility=hidden". - - Check the difference for the 'std_containers.i' python - test case: - - Sizes: - - 3305432 _std_containers.so - 2383992 _std_containers.so.hidden - - Exported symbols (nm -D <file>.so | wc -l): - - 6146 _std_containers.so - 174 _std_containers.so.hidden - - Execution times: - - real 0m0.050s user 0m0.039s sys 0m0.005s _std_containers.so - real 0m0.039s user 0m0.026s sys 0m0.007s _std_containers.so.hidden - - Read http://gcc.gnu.org/wiki/Visibility for more details. - - -02/27/2006: mutandiz - [allegrocl] - Add support for INPUT, OUTPUT, and INOUT typemaps. - For OUTPUT variables, the lisp wrapper returns multiple - values. - -02/26/2006: mmatus - - [Ruby] add argcargv.i library file. - - Use it as follow: - - %include argcargv.i - - %apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) } - - %inline { - int mainApp(size_t argc, const char **argv) - { - return argc; - } - } - - then in the ruby side: - - args = ["asdf", "asdf2"] - n = mainApp(args); - - - This is the similar to the python version Lib/python/argcargv.i - -02/24/2006: mgossage - - Small update Lua documents on troubleshooting problems - -02/22/2006: mmatus - - Fix all the errors reported for 1.3.28. - - fix bug #1158178 - - fix bug #1060789 - - fix bug #1263457 - - fix 'const char*&' typemap in the UTL, reported by Geoff Hutchison - - fixes for python 2.1 and the runtime library - - fix copyctor + template bug #1432125 - - fix [ 1432152 ] %rename friend operators in namespace - - fix gcc warning reported by R. Bernstein - - avoid assert when finding a recursive scope inheritance, - emit a warning in the worst case, reported by Nitro - - fix premature object deletion reported by Paul in tcl3d - - fix warning reported by Nitro in VC7 - - more fixes for old Solaris compiler - - fix for python 2.3 and gc_refs issue reported by Luigi - - fix fastproxy for methods using kwargs - - fix overload + protected member issue reported by Colin McDonald - - fix seterrormsg as reported by Colin McDonald - - fix directors, now the test-suite runs again using -directors - - fix for friend operator and Visual studio and bug 1432152 - - fix bug #1435090 - - fix using + %extend as reported by William - - fix bug #1094964 - - fix for Py_NotImplemented as reported by Olly and Amaury - - fix nested namespace issue reported by Charlie - - and also: - - - allow director protected members by default - - delete extra new lines in swigmacros[UTL] - - cosmetic for generated python code - - add the factory.i library for UTL - - add swigregister proxy method and move __repr__ to a - single global module [python] - -02/22/2006: mmatus - - When using directors, now swig will emit all the virtual - protected methods by default. - - In previous releases, you needed to use the 'dirprot' - option to achieve the same. - - If you want, you can disable the new default behaviour, - use the 'nodirprot' option: - - swig -nodirprot ... - - and/or the %nodirector feature for specific methods, i.e.: - - %nodirector Foo::bar; - - struct Foo { - virtual ~Foo(); - - protected: - virtual void bar(); - }; - - - As before, pure abstract protected members are allways - emitted, independent of the 'dirprot/nodirprot' options. - - -02/22/2006: mmatus - Add the factory.i library for languages using the UTL (python,tcl,ruby,perl). - - factory.i implements a more natural wrap for factory methods. - - For example, if you have: - - ---- geometry.h -------- - struct Geometry { - enum GeomType{ - POINT, - CIRCLE - }; - - virtual ~Geometry() {} - virtual int draw() = 0; - - // - // Factory method for all the Geometry objects - // - static Geometry *create(GeomType i); - }; - - struct Point : Geometry { - int draw() { return 1; } - double width() { return 1.0; } - }; - - struct Circle : Geometry { - int draw() { return 2; } - double radius() { return 1.5; } - }; - - // - // Factory method for all the Geometry objects - // - Geometry *Geometry::create(GeomType type) { - switch (type) { - case POINT: return new Point(); - case CIRCLE: return new Circle(); - default: return 0; - } - } - ---- geometry.h -------- - - - You can use the %factory with the Geometry::create method as follows: - - %newobject Geometry::create; - %factory(Geometry *Geometry::create, Point, Circle); - %include "geometry.h" - - and Geometry::create will return a 'Point' or 'Circle' instance - instead of the plain 'Geometry' type. For example, in python: - - circle = Geometry.create(Geometry.CIRCLE) - r = circle.radius() - - where 'circle' now is a Circle proxy instance. - - -02/17/2006: mkoeppe - [MzScheme] Typemaps for all integral types now accept the full range of integral - values, and they signal an error when a value outside the valid range is passed. - [Guile] Typemaps for all integral types now signal an error when a value outside - the valid range is passed. - -02/13/2006: mgossage - [Documents] updated the extending documents to give a skeleton swigging code - with a few typemaps. - [Lua] added an extra typemap for void* [in], so a function which requires a void* - can take any kind of pointer - -Version 1.3.28 (February 12, 2006) -================================== - -02/11/2006: mmatus - Fix many issues with line counting and error reports. - -02/11/2006: mmatus - [Python] Better static data member support, if you have - - struct Foo { - static int bar; - }; - - then now is valid to access the static data member, ie: - - f = Foo() - f.bar = 3 - - just as in C++. - - -02/11/2006: wsfulton - [Perl] - Fixed code generation to work again with old versions of Perl - (5.004 and later tested) - -02/04/2006: mmatus - [Python] Add the %extend_smart_pointer() directive to extend - SWIG smart pointer support in python. - - For example, if you have a smart pointer as: - - template <class Type> class RCPtr { - public: - ... - RCPtr(Type *p); - Type * operator->() const; - ... - }; - - you use the %extend_smart_pointer directive as: - - %extend_smart_pointer(RCPtr<A>); - %template(RCPtr_A) RCPtr<A>; - - then, if you have something like: - - RCPtr<A> make_ptr(); - int foo(A *); - - you can do the following: - - a = make_ptr(); - b = foo(a); - - ie, swig will accept a RCPtr<A> object where a 'A *' is - expected. - - Also, when using vectors - - %extend_smart_pointer(RCPtr<A>); - %template(RCPtr_A) RCPtr<A>; - %template(vector_A) std::vector<RCPtr<A> >; - - you can type - - a = A(); - v = vector_A(2) - v[0] = a - - ie, an 'A *' object is accepted, via implicit conversion, - where a RCPtr<A> object is expected. Additionally - - x = v[0] - - returns (and sets 'x' as) a copy of v[0], making reference - counting possible and consistent. - - %extend_smart_pointer is just a collections of new/old - tricks, including %typemaps and the new %implicitconv - directive. - -02/02/2006: mgossage - bugfix #1356577, changed double=>lua_number in a few places. - added the std::pair wrapping - -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 <std_string.i> - - that will tell swig to use 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 clashes 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/09/2006: mutandiz - [Allegrocl] - - Fixes a number of SEGVs primarily in the handling of - various anonymous types. Found in a pass through the - swig test-suite. Still more to do here, but this is a - good checkpoint. - - Adds -cwrap and -nocwrap as an allegrocl specific - command-line argument. Controls generating of a C - wrapper file when wrapping C code. By default only a - lisp file is created for C code wrapping. - - Doc updates for the command-line arguments and fixes as - pointed out on swig-devel - -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 unnecessary 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. - -Version 1.3.27 (October 15, 2005) -================================= - -10/15/2005: wsfulton - [Java] Fix for typesafe enum wrapping so that it is possible to - overload a method with 2 different enum types. - -10/15/2005: wsfulton - Fix for %feature("immutable","0") attempting to generate setters - for constants. - - Restored %immutable and %makedefault to clear the feature as it - behaved in SWIG-1.3.25 and earlier. - -10/14/2005: mmatus - Fix bug in anonymous typedef structures which was leading to - strange behaviour. - -10/13/2005: mmatus - Several minor changes: - - - Improve the wchar_t type support - - Add a warning for when you define the 'in' typemap but - you don't define the 'typecheck' one. Very common mistake. - - Add proper default rule for function pointers, now you - can define a typemap such as: - - %typemap(in) SWIGTYPE ((*)(ANY)) {...} - - That will apply to all the pointer to functions. The - rule in C++ also apply to the function 'reference', ie, - in both cases - - typedef int (*fptr)(int a); - typedef int (func)(int a); - - This was needed since it seems to be 'illegal' in C++ to - do something like: - - void *ptr = static_cast<void *>(fptr); - - and probably, as for member functions, it is not - warrantied that the pointer sizes will match. - - - Add the #error/#warning directives to swig's cpp. - - - Add the noblock option for typemaps, which is used as - follows: supposed you a typemap, like this - - - %typemap(in,noblock=1) Hello { - .... - } - - then the typemap will be inserted without the block - imposed by the brackets, similar to - - %typemap(in) Hello "..." - - So, why you don't just use the quote style?, because: - - 1.- The quote style doesn't get preprocessed, for example - - %typemap(in) Hello "$1= SWIG_macro($1);" - - here, SWIG_macro doesn't get expanded - - 2.- Inside a quote typemap, you have to use - quotes carefully - - %typemap(in) Hello "$1 = \"hello\" " - - 3.- You can't make emacs and/or other editors - to indent inside a string!. - - - So, why do you want to remove the block?, because an extra - block when not needed (no local variables in it): - - 1.- makes the code harder to read - 2.- makes the code larger - 3.- or in short, for the same reason we have the quote style. - -Version 1.3.26 (October 9, 2005) -================================ - -10/08/2005: wsfulton - [Php] Added 'throws' typemaps. - -10/08/2005: wsfulton - Fixes for languages that don't support multiple inheritance. The - first non-ignored class in the public base class list is used for inheritance. - by the proxy class. Previously, if the first class in the list was ignored, then - the proxy class wouldn't have any base classes. - -10/07/2005: mmatus - Update more features to follow new convention, including: - - callback - ref/unref - except - - All of them use not only the feature as a flag, but also - as code value. To deal with those features, we use now - GetFlagAttr, which is similar to GetFlag, but instead or - returning 1 or 0, it returns the attr value, if happens - to be different of "0" of course. - - Now there are also more uniform directive names for the - ones based in features, for example, for the old - %newobject directive now we have tree directives defined: - - - #define %newobject %feature("new") - #define %nonewobject %feature("new","0") - #define %clearnewobject %feature("new","") - - and so on for all the other feature directives. - - *** POTENTIAL INCOMPATIBILITY *** - -09/30/2005: wsfulton - Subtle change to some features. Previously it was not possible to disable many - features once they had been enabled. This was for most features that behave as - flags. These features now work as follows: - - %feature("name") // enables the feature - %feature("name", "1") // enables the feature - %feature("name", "0") // disables the feature - %feature("name", "") // clears the feature - - In fact any non-empty value other than "0" will enable the feature (like C boolean logic). - Previously "1", "0" or any other non-empty value would enable the feature and it would - only be possible to disable the feature by clearing it (assuming there was no global enable). - - The following features are affected: - - allowexcept - compactdefaultargs - classic (Python) - cs:const (C#) - director - exceptionclass (Python) - ignore - immutable - java:const (Java) - java:downcast (Java) - kwargs - modern (Python) - new - noautodoc (Python) - nodefault - nodirector - noref - notabstract - nounref - novaluewrapper - python:maybecall (Python) - python:nondynamic (Python) - modula3:multiretval (Modula3) - predicate (Ruby) - trackobjects (Ruby) - valuewrapper - - It is now possible, for example to ignore all methods/classes in a header file, except for a - few targetted methods, for example: - - %feature("ignore"); // ignore all methods/classes - %feature("ignore","0") some_function(int, double); // do not ignore this function - %feature("ignore","0") SomeClass; // do not ignore this Class - %feature("ignore","0") SomeClass::method; // do not ignore this method - %include "bigheader.h" - - Removed %pythondynamic - it never worked properly. Use %pythonnondynamic instead. - Removed %feature("nokwargs") - it wasn't fully implemented - use %feature("kwargs","0") instead. - - *** POTENTIAL INCOMPATIBILITY *** - -09/25/2005: mkoeppe - [Guile] Add "throws" typemaps. - -09/24/2005: cfisavage - [Ruby] Adds new %trackobjects functionality that maps C++ objects to - Ruby objects. This functionality makes it much easier to implement - mark functions for the garbage collector. For more information - refer to the update documentation and examples. - -09/20/2005: wsfulton - [Perl] Patch 1116431 from Josh Cherry. Fixes non member functions inadvertently - being called instead of member functions. - -09/20/2005: wsfulton - [Lua] Patch from Mark Gossage to add support for Lua-5.1, std::string, - std::vector, std::exception and documentation. - -09/14/2005: mmatus - [Python] Add -nocppcast. Now the default behavior is to - always use the cppcast operators. Before that was the case - only when you used the -cppcast option. - - If this seems to break your code... your welcome!, it - means it was broken before, and you never notice. - - If you thing the error is due to one of the SWIG typemaps, - send us an example. - - Use -nocppcast only with very old C++ compilers that - do not support the cppcast operations. - - So, here applies: - - This change doesn't break compatibility, it was broken before. - -09/13/2005: wsfulton - [Java] Fix for director methods when a class is passed by value as a - parameter. - -09/11/2005: mmatus - Adding the module option to the %import directive. Now you - can use it as - - %import(module="BigModule") foo.i - - where subfile could (or not) define the module name via - the %module directive. The module option take precedence - and it has the same effects than having the directive - - %module BigModule - - inside the imported file foo.i. - - You can use the option in mainly two cases: - - 1.- You used the -module option when you generated the - module to be imported, and hence the module name in - the imported %module directive is not really useful. - - 2.- The module you want to import is very large, and it - has several .i/.h files. Then, if you just one to - import a class or so from the module, says 'foo', and - not the entire module via importing the main - BigModule.i file, then you just do: - - %import(module="BigModule") foo.h - - or - - %import(module="BigModule") foo.i - - where foo.i contains the 'foo' declaration and maybe a - couple of extra %include directives, as needed. - - -09/11/2005: mmatus - Fix bug #1282637, about the -module option not having effect - in places where it was needed. - -09/11/2005: wsfulton - When wrapping variables, ensure that none of the typemaps used for the - set wrappers are used when generating the get wrappers. I doubt this was a - problem for any languages except for the recently introduced null attribute - in the out typemap (C# only). - -09/08/2005: wsfulton - More descriptive error messages when files fail to open. - -09/06/2005: mmatus - - Allow a %define a macro inside another %define macro, for example - - %define hello(name, Type) - %define name ## a(Type) - %typemap(in) Type "hello;" - %enddef - %enddef - - To learn how to use this new features in your own typemaps library, see - python/cstring.i, python/cwstring.i and python/cwstrbase.i. - - [Python] Normalize the cstring.i implementation to use fragments, and add - cwstring.i, which implements the same typemaps but for wchar_t strings. - - [Python] Bug fixed: 1247477, 1245591, 1249878 and others. - -08/18/2005: wsfulton - [Ruby] Implement support for SWIGTYPE* DISOWN typemap (like in Python) for - better control of memory management, eg when adding an object created in Ruby - to a C++ container. Patch #1261692 from Charlie Savage. - -08/18/2005: wsfulton - [Tcl] 64 bit platform fixes for the varargs handling in SWIG_GetArgs. This is an - improved fix for bug #1011604 as suggested by Jeremy Lin. - -08/18/2005: wsfulton - [Tcl] Bug #1240469 - %newobject support for Tcl. Patch from Bob Marinier. - -08/16/2005: wsfulton - [Perl] Bug #1254494 - Fix for global namespace pollution by perl header files - (bool define) prevented STL headers from being used on some systems, eg - Windows with Visual Studio. - -08/16/2005: wsfulton - [Java] Bug #1240937 - Redefinition of __int64 typedef for Intel compilers. - -08/15/2005: wsfulton - [Xml] Bug #1251832 - C++ template may generate invalid XML file - -08/15/2005: wsfulton - [Lua] Support added for Lua. Patch #1242772 from Mark Gossage. - It supports most C/C++ features (functions, struct, classes, arrays, pointers, - exceptions), as well as lots of documentation and a few test cases & examples. - -08/14/2005: wsfulton - [Xml] Fix incorrect xml escaping in base class name when base class is a template. - -08/13/2005: efuzzyone - [CLISP] Added support for handling enums. Does not adds the return type declaration - to the function definition, if a function returns void. - -08/09/2005: mkoeppe - New language module, Common Lisp with UFFI, from Utz-Uwe Haus. - -08/09/2005: mkoeppe - Fix the Lisp s-expression output module; it no longer complains about "unknown targets". - -07/27/2005: wsfulton - Modifications to STL wrappers so that it is possible for a user's %exception directive - to be applied to the STL wrapper methods. Previously the following global %exception - directive would not be used on the wrapper methods: - - %exception { - try { - $action - } catch (...) { - // handle uncaught exceptions - } - } - - This has been implemented by replacing %exception directives for specific STL wrapper - methods with an exception specification declared on the wrapper methods. throws typemaps - are now supplied for handling the STL exception specification. These can also be easily - overridden, for example the std::out_of_range exception, which is used a lot in the STL - wrappers, can be customised easily: - - %include "std_vector.i" - %typemap(throws) std::out_of_range { - // custom exception handler - } - %template(VectInt) std::vector<int>; - -07/22/2005: efuzzyone - [CLISP] The clisp module for SWIG: - - It can only handle C, clisp currently does not supports ffi bindings to C++. - - It has two options, (a) -extern-all this will generate wrappers for all functions - and variablestions, (b) -generate-typedef this will generate wrappers "def-c-type" - wrappers for typedefs - - Can handle pointers to functions, complex types such as n-dimensional arrays of - pointers of depth d - - Generates wrappers for constants as well as variables - - Correctly distinguishes between the declaration of variables in structures and functions - - Creates a defpackage "declaration" with the module name as the package name, the created - package exports both functions and variables - - tries to guess when should a pointer variable be declared as c-ptr or c-pointer - -07/22/2005: wsfulton - [C#] Changes to support C# structs returned by value. The changes required are: - - Using an optional 'null' attribute in the out typemap. If this attribute is specified, - then it is used for the $null special variable substitution. - - The ctype used in the C/C++ wrappers is no longer initialised to 0 on declaration. - Both of these changes fix the situations where an attempt was made to assign 0 to the - returned struct. Marshalling structs as value types still requires user defined typemaps. - See documentation for an example. - -07/22/2005: wsfulton - [C#, Java] Fix SWIG_exception usage to work with compilers that don't support empty macro - arguments. Unfortunately this fix will stop usage of SWIG_exception being used within typemaps - that use "" or %{ %} delimiters, but continues to work with typemaps using {} delimiters. - Please use the SWIG_CSharpSetPendingExceptionArgument or SWIG_JavaThrowException methods instead - as SWIG_exception is really intended as a platform independent macro for the SWIG library writers. - -07/16/2005: mkoeppe - [Allegro CL] Use specific foreign types rather than (* :void). - Use *swig-identifier-converter*. - -06/27/2005: wsfulton - Functions declared as 'extern' no longer have an additional function declaration added to the - wrapper files. There are some cases where SWIG does not get this right, eg bug #1205859 (extern - functions with default arguments declared in a namespace). Also SWIG cannot get non-standard - calling conventions correct, eg Windows calling conventions are usually handled like this: - - %{ - #define DLLIMPORT __declspec(dllimport) - #define STDCALL __stdcall - %} - #define DLLIMPORT - #define STDCALL - %inline %{ - DLLIMPORT extern STDCALL void function(int); - %} - - SWIG incorrectly generates: - - extern void function(int); - - To which there is no solution as SWIG doesn't handle non-standard calling conventions. The extra - 'extern' function that SWIG generates is superfluous unless a user has forgotten to add the function - declaration into the wrappers. - - The -noextern commandline argument is now redundant and a new commandline argument -addextern can - be used to obtain the original behaviour. This shouldn't be necessary unless the header file - containing the function declaration was inadvertently not added to the wrappers. To fix this - add the function declaration into your wrappers, For example, replace: - - extern void foo(int); - - with: - - %inline %{ - extern void foo(int); - %} - - *** POTENTIAL INCOMPATIBILITY *** - -06/22/2005: wsfulton - [C#, Java, Modula3, Ocaml] - The intermediary function names have been changed when wrapping variables to - match the other language modules so that %extend for a member variable works - uniformly across all language modules, eg: - - %extend ExtendMe { - Var; - }; - - %{ - void ExtendMe_Var_set(ExtendMe *, double) {...} - double ExtendMe_Var_get(ExtendMe *) {...} - %} - - The methods implementing the get/set used to be: - - %{ - void set_ExtendMe_Var(ExtendMe *, double) {...} - double get_ExtendMe_Var(ExtendMe *) {...} - %} - - This also changes the name of variable wrapper functions when using -noproxy. - The original names can be generated with the -oldvarnames commandline option. - - *** POTENTIAL INCOMPATIBILITY *** - -Version 1.3.25 (June 11, 2005) -============================== - -06/11/2006: mkoeppe - [Guile] Fix handling of anonymous-enum variables. - -06/10/2005: mkoeppe - [Guile] Fix for function arguments that are passed by - copy-of-value. Fix for global "const char *" variables. - Fix testcases arrays_dimensionless, arrays_global. - -06/08/2005: wsfulton - Fix for when a base class defines a symbol as a member variable and a derived class defines - the same symbol as a member method. - -06/08/2005: wsfulton - [C#] More fixes for virtual/new/override modifiers - when a method has protected access - in base and public access in derived class. - -06/02/2005: wsfulton - Fix #1066363 - Follow convention of release tarball name matching directory name. - -06/02/2005: wsfulton - [C#, Java] Fix #1211353 - typesafe enums (and Java proper enums) wrappers when enum value - is negative. - -05/27/2005: wsfulton - Modernised and tidied up Windows macros --> SWIGEXPORT, SWIGSTDCALL. They can be overridden - by users via -D compiler directives if need be. - -05/26/2005: wsfulton - %csmethodmodifiers can be applied to variables as well as methods now. - - In addition to the default 'public' modifier that SWIG generates, %csmethodmodifiers will also - replace the virtual/new/override modifiers that SWIG thinks is appropriate. This feature is - useful for some obscure cases where SWIG might get the modifiers incorrect, for example - with multiple inheritance and overriding a method in the base class. - - *** POTENTIAL INCOMPATIBILITY FOR C# MODULE *** - -05/25/2005: wsfulton - Added missing constructors to std::pair wrappers (std_pair.i) for all languages. - -05/25/2005: wsfulton - [C#] Added std::pair wrappers in std_pair.i - -05/25/2005: wsfulton - [C#] The C# 'new' and 'override' modifiers will be generated when a C++ class inherits methods - via a C++ 'using' declaration. - -05/25/2005: wsfulton - Fix for exception specifications previously being ignored in classes that inherited methods - from 'using' declarations, eg calls to Derived::bar below will convert C++ exceptions into - a target language exception/error, like it always has done for Base::Bar. - - class Base { - virtual bar() throw (std::string); - }; - class Derived : public Base { - using Base::bar; - }; - -05/23/2005: wsfulton - Fixes for detecting virtual methods in %extend for the -fvirtual option and C# override and new - method modifiers. - -05/23/2005: wsfulton - [C#] The 'new' modifier is now generated on the proxy method when a method in a derived - class is not polymorphic and the same method exists in the derived class (ie it hides - the base class' non-virtual method). - -05/23/2005: wsfulton - [Java, C#] Fixes to detection of covariant return types - when the class hierarchy is more - than 2 classes deep. - -05/21/2005: wsfulton - [Java] std::wstring typemaps moved from std_string.i to std_wstring.i - -05/21/2005: wsfulton - Fix for crash in DohStrstr, bug #1190921 - -05/21/2005: wsfulton - [TCL] Fix for methods with similar names when showing list of names on error - bug #1191828. - Patch from Jeroen Dobbelaere. - -05/21/2005: wsfulton - [TCL] long long overloading fix - bug #1191835, patch from Jeroen Dobbelaere. - -05/21/2005: wsfulton - Fix bug #1196755 to remove debug from swigtcl8.swg. - -05/19/2005: wsfulton - [C# and -fvirtual option] Fix for the override key not being generated in the derived class when a - virtual method's return type was a typedef in either the base or derived class. Also ensures the - method is eliminated when using the -fvirtual option. For example, Derived.method now has the C# - override keyword generated: - - typedef int* IntegerPtr; - - struct Base { - virtual IntegerPtr method(); - }; - - struct Derived : Base { - int * method() const; - }; - - [C#] Fix for the override key being incorrectly generated for virtual methods when a base class - is ignored with %ignore. - -05/13/2005: wsfulton - [Java] Fixes to remove "dereferencing type-punned pointer will break strict-aliasing rules" - warnings in C wrappers when compiling C code with 'gcc -Wall -fstrict-aliasing'. Patch from - Michael Cahill. This modifies many of the casts slightly, for example - arg1 = *(DB_ENV **)&jarg1; - to - arg1 = *(DB_ENV **)(void *)&jarg1; - -05/12/2005: wsfulton - [C#] Support for C# attributes. C# attributes can be generated: - 1) On a C/C++ type basis by specifying an inattributes and/or outattributes typemap attribute - in the imtype or cstype typemaps (for C# return type or C# parameter type attributes). - 2) On a wrapped method or variable by specifying a csattributes feature (%feature). - 3) On a wrapped proxy class or enum by specifying a csattributes typemap. - - Examples are in the C# documentation (CSharp.html). - -04/29/2005: wsfulton - New configure option to turn off the default maximum compiler warning as - they couldn't be removed even when overriding CFLAGS and CXXFLAGS with configure - (./configure CFLAGS= CXXFLAGS=). To turn the maximum warnings off, run: - - ./configure --without-maximum-compile-warnings - -04/28/2005: wsfulton - Patch from Scott Michel which reworks the Java constructor and finalize/destructor typemaps, - for directors to reduce the number of overall Java typemaps. Added the director_take and - director_release typemaps to emulate other modules' __disown__ functionality. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA DIRECTORS *** - -04/28/2005: wsfulton - [C#] Fixed problems due to the over eager garbage collector. Occasionally the - garbage collector would collect a C# proxy class instance while it was being used - in unmanaged code if the object was passed as a parameter to a wrapped function. - Needless to say this caused havoc as the C# proxy class calls the C++ destructor - when it is collected. Proxy classes and type wrapper classes now use a HandleRef, - which holds an IntPtr, instead of a plain IntPtr to marshal the C++ pointer to unmanaged - code. There doesn't appear to be any performance degradation as a result of this - modification. - - The changes are in the proxy and type wrapper classes. The swigCPtr is now of type HandleRef - instead of IntPtr and consequently the getCPtr method return type has also changed. The net - effect is that any custom written typemaps might have to be modified to suite. Affected users - should note that the implementation uses the new 'out' attribute in the imtype typemap as the - input type is now a HandleRef and the output type is still an IntPtr. - - *** POTENTIAL INCOMPATIBILITY FOR C# MODULE *** - -04/28/2005: wsfulton - [C#] Support for asymmetric type marshalling added. Sometimes the output type needs to be - different to the input type. Support for this comes in the form of a new optional 'out' - attribute for the ctype, imtype and cstype typemaps. If this typemap attribute is not - specified, then the type used for both input and output is the type specified in the - typemap, as has always previously been the case. If this typemap attribute is specified, - then the type specified in the attribute is used for output types and the type specified - in the typemap itself is used for the input type. An output type is a return value from - a wrapped method or wrapped constant and an input type is a parameter in a wrapped method. - - An example shows that char * could be marshalled in different ways, - - %typemap(imtype, out="IntPtr") char * "string" - char * function(char *); - - The output type is thus IntPtr and the input type is string. The resulting intermediary C# code is: - - public static extern IntPtr function(string jarg1); - -04/22/2005: mkoeppe (Matthias Koeppe) - [Guile] Fix generation of "define-method" for methods of - classes with a constructor. Reported by Luigi Ballabio. - -04/15/2005: wuzzeb (John Lenz) - [Chicken] - For wrapped functions that return multiple values (using argout), - SWIG CHICKEN now returns them as multiple values instead of as - a list. They can then be accessed using (call-with-values). - -04/14/2005: wuzzeb (John Lenz) - [Chicken] - + Added a whole bunch of new _runme scripts into the chicken test - suite. Also fix some bugs these new scripts turned up. - - + Added optimization when returning a wrapped proxy class. Before, - a minor garbage collection was invoked every time a function returned. - - + All the chicken Examples should now run correctly - -04/14/2005: wsfulton - [C#] More fixes for typemap matching when wrapping variables, in particular - std::string, so that std::string variables can be easily marshalled with - a C# string property using: - - %include "std_string.i" - %apply const std::string & { std::string *variable_name }; - std::string variable_name; - - (Recall that all class variables are wrapped using pointers) - -04/05/2005: wuzzeb (John Lenz) - [Chicken] - + Added Examples/chicken/egg, an example on how to build a chicken - extension library in the form of an egg. Also updated the - documentation on the different linking options. - - + chicken test-suite now has support to check SWIG with the -proxy - argument if there exists a _proxy_runme.ss file. - - + More fixes for overloaded functions and -proxy - -03/31/2005: wsfulton - Turned on extra template features for all languages which were - previously only available to Python. - - This enables typemaps defined within a templated class to be used as - expected. Requires %template on the templated class, %template() will - also pick up the typemaps. Example: - - template <typename T> struct Foo { - ... - %typemap(in) Foo "in typemap for Foo<T> " - or - %typemap(in) Foo<T> "in typemap for Foo<T> " - }; - - %template(Foo_i) Foo<int>; - %template() Foo<double>; - - will generate the proper 'in' typemaps wherever Foo<int> and Foo<double> - are used. - -03/30/2005: mkoeppe (Matthias Koeppe) - [MzScheme] Patch from Hans Oesterholt for supporting MzScheme 30x. - -03/29/2005: wuzzeb (John Lenz) - [Chicken] - + Reallow older versions of chicken (1.40 to 1.89) by passing -nocollection - argument to SWIG - + %import now works correctly with tinyclos. (declare (uses ...)) will be - exported correctly. - + TinyCLOS proxy classes now work correctly with overloaded functions - and constructors. - -03/29/2005: wsfulton - [Java] Patch from Scott Michel for directorout typemaps. Java directors - require the directorout typemaps like the other languages now. The new - typemaps provide fixes for methods where the return type is returned - by reference (this cannot automatically be made thread safe though). - -03/22/2005: wsfulton - Enum casting fixes. Visual C++ didn't like the C type casting SWIG produced - when wrapping C++ enum references, as reported by Admire Kandawasvika. - -03/21/2005: wsfulton - [Perl] SF #1124490. Fix Perl macro clashes when using Visual Studio's STL string, - so now projects can #include <string>. - -03/21/2005: wsfulton - Fixed %varargs which got broken with the recent default argument changes. - Also works for Java and C# for the first time now. - -03/17/2005: wuzzeb (John Lenz) - [Chicken] - + Fix a whole bunch of bugs in the chicken module. The entire - test suite now compiles, with the exception of the tests that require - std_vector.i, std_deque.i, and so on, which chicken does not have yet. - - + Add support for %exception and %typemap(exceptions). Exceptions are - thrown with a call to (abort) and can be handled by (handle-exceptions) - -03/15/2005: wsfulton - [Java] Patch from Scott Michel for directors. Modifications to the typemaps - giving users fine control over memory ownership and lifetime of director classes. - Director classes no longer live forever by default as they are now collectable - by the GC. - -03/15/2005: wuzzeb (John Lenz) - [Chicken] Add support for adding finalizers garbage collected objects. - Functions that return new objects should be marked with %newobject and - input arguments which consume (or take ownership) of a pointer should - be marked with the DISOWN typemap. - - Also add support for correctly checking the number of arguments passed - to a function, and raising an error if the wrong number are passed. - -03/14/2005: wuzzeb (John Lenz) - Add --without-alllang option to configure.in, which is the same as - passing all the --without-python --without-perl5 etc... that Matthias added. - -03/09/2005: wsfulton - [Php] Memory leak fix for functions returning classes/structs by value. - -03/08/2005: wsfulton - [Perl] Fix for Perl incorrectly taking memory ownership for return types that - are typedefs to a struct/class pointer. Reported by Josh Cherry. - -03/07/2005: wsfulton - [C#] Various exception changes for the std::vector wrappers. These now more - accurately mirror the same exceptions that System.Collections.ArrayList throw. - -03/07/2005: wsfulton - [C#] Fix undefined behaviour after any of the std::vector methods - throw an exception. - -03/07/2005: wsfulton - [C#] When null is passed for a C++ reference or value parameter, the - exception thrown has been corrected to an ArgumentNullException instead - of NullReferenceException as recommended in the .NET Framework documentation. - - The default throws typemaps turn a C++ exception into an ApplicationException, - not a SystemException now. - -03/07/2005: wsfulton - [C#] Numerous changes in C# exception handling have been made over the past - few weeks. A summary follows: - - The way in which C++ exceptions are mapped to C# exceptions is quite different. - The change is to fix C# exceptions so that the C++ exception stack is correctly - unwound as previously C++ exceptions were being thrown across the C PInvoke layer - into the managed world. - - New typemap attributes (canthrow and excode) have been introduced to control the - mapping of C++ to C# exceptions. Essentially a callback into the unmanaged world - is made to set a pending exception. The exception to throw is stored in thread local - storage (so the approach is thread-safe). The typemaps are expected to return - from unmanaged code as soon as the pending exception is set. Any pending exceptions - are checked for and thrown once managed code starts executing. There should - be minimal impact on execution speed during normal behaviour. Full details will be - documented in CSharp.html. - - The SWIG_CSharpThrowException() function has been removed and replaced with the - SWIG_CSharpSetPendingExceptionArgument() and SWIG_CSharpSetPendingException() - functions. The original name has been deliberately changed to break old code as - the old approach was somewhat flawed. Any user defined exceptions that follow the - same pattern as the old approach should also be fixed. - - Numerous new .NET framework exceptions are now available for easy throwing from - unmanaged code. The complete list is: - - ApplicationException, ArithmeticException, DivideByZeroException, - IndexOutOfRangeException, InvalidOperationException, IOException, - NullReferenceException, OutOfMemoryException, OverflowException, - SystemException, ArgumentException, ArgumentNullException and - ArgumentOutOfRangeException. - - *** POTENTIAL INCOMPATIBILITY FOR C# MODULE *** - -05/05/2005: mmatus - - Fix several memory leaks around. Even when we survive knowning - swig is a memory leak factory, it was a little out of - control. To run std_containers.i in the python test-suite, - swig was using ~260MB, now it uses 'only' ~40MB, which is - the same ammount that g++ uses, so, is not that bad. - In the process, I found a couple of extra Deletes, which - in some cases could trigger seg. faults and/or - DOH/asserts. - - [python] Better support for directors + exception. More - verbose errors and added an unexpected exception handler. - - [python] Fix memory leak for the - - std::vector<std::vector<int> > - - case,reported by Bo Peng. - - [python] Fix SwigPyObject compare problem reporte by - Cameron Patrick. - - [python] Fix several warnings in the generated code - for gnu-gcc, Intel and VC7.1 compilers. - - -02/25/2005: wuzzeb (John Lenz) - Update documentation to use CSS and <div> instead of <blockquote> - I used a script to convert the docs, and it set all the box classes - to be "code". There are actually 4 different classes, - "shell", "code", "targetlang", and "diagram". We need to go through - and convert the divs depending on what they contain. - -02/23/2005: mmatus - - [Python] Added option -nortti to disable the use of native - C++ RTTI with directors (dynamic_cast<> is not used). - - Add more code for directors to detect and report errors in - the python side. - - Extend the use of SWIGINTERN whenever is possible. - - Remove template warnings reported by VC7.1. - - Remove warnings reported by gcc/g++. Finally you can - compile using - - g++ -W -Wall -c mymodule_wrap.cxx - - and no spurious errors will be generated in the wrapper - code. - -02/23/2005: wuzzeb (John Lenz) - Added -external-runtime argument. This argument is used to dump - out all the code needed for external access to the runtime system, - and it replaces including the files directly. This change adds - two new virtual functions to the Language class, which are used - to find the language specific runtime code. I also updated - all languages that use the runtime to implement these two functions. - -02/22/2005: mmatus - Fix %template + private error SF#1099976. - -02/21/2005: mmatus - - Fix swigrun.swg warnings reported when using "gcc -W -Wall" - (static/inline not used in front of a function - declaration), and add SWIGUNUSED attribute to avoid - unused warnings elsewhere. - - Fix unused variable warnings. - - [Python] Use new SWIGUNUSED attribute to avoid warnings in - SWIGINTERN methods. - - [Python] Fix PyOS_snprintf for python versions < 2.2 (SF #1104919). - - [Python] Fix map/multimap to allow empty maps (reported by - Philippe Hetroy). - - [Docs] Add some documentation to Python.html and - SWIGPlus.html, including for example the fact that - 'friends' are now supported. - -02/21/2005: wsfulton - [PHP] Patch from Olly Betts, so that wrappers compile with Zend thread safety enabled. - -02/17/2005: wsfulton - Memory leak fix in some of the scripting language modules when using default - arguments in constructors. The scripting language was not taking ownership of the - C++ object memory when any of the constructors that use default arguments was called. - -02/16/2005: wsfulton - SF #1115055: Failed make install. Patch from Rob Stone. - -02/16/2005: wsfulton - [Java] SF #1123416 from Paul Moore. Correct memory allocation for STRINGARRAY - typemaps in various.i. - -02/15/2005: wsfulton - Disabled typemap search changes for now (see entry 19/12/2004). It breaks - old typemaps, lengthens the execution time by about 25% and introduces - inconsistencies. - -02/15/2005: wsfulton - swig -help follows other software by printing to stdout instead of stderr now. - swig -version also displays to stdout instead of stderr now. - Behaviour reported by Torsten Landschoff. - -02/15/2005: wsfulton - [Ruby] Fix for the less commonly used ordering of %include and #include, so - that the generated code compiles. Bug reported by reported by Max Bowsher. - %include foo.h - %{ - #include foo.h - %} - -02/15/2005: wsfulton - [C#, Java] SWIG_exception macro will now return from unmanaged code / native code - as soon as it is called. Fixes possible JVM crashes and other code unexpectedly - being executed. Note SWIG_exception is only occasionally used by SWIG library - writers, and is best avoided by SWIG users. - -02/15/2005: wsfulton - [C#, Java] Typemaps can now be targeted at global variable names - and static member variable names. Previously the typemaps for - the setters were ignored, for example: - - %typemap(in) int globalint "..." - int globalint; - -02/13/2005: mkoeppe (Matthias Koeppe) - [Guile] Add %typecheck for SWIGTYPE, add %typecheck for ptrdiff_t, fix - typemaps for size_t. - - [Pike] Merge patch from Torsten Landschoff for improved Pike configuration. - -02/12/2005: mkoeppe (Matthias Koeppe) - New configure switches --without-tcl, --without-python etc. allow to - disable the search for installed languages. - -01/31/2005: wuzzeb (John Lenz) - - Add DohSortList to DOH - - - Improve the runtime type system: - + Speed. Type loading is now O(n log n) instead of O(N^2), which - for large modules is a huge improvement. - + A whole bunch of functions in swigrun.swg no longer need the - swig_type_list_handle passed to them. The only one left is - TypeQuery. This also makes runtime.swg a lot smaller. - + Split up swig_type_info structure into two structures - (swig_type_info and swig_cast_info) - + Store a pointer to a swig_type_info rather than just the type - name string in the linked list of casts. First off, this makes - the guile module a little faster, and second, the - SWIG_TypeClientData() function is faster too. - + Add the idea of a module into the type system. Before, all the - types were stored in one huge linked list. Now, another level is - added, and the type system stores a linked list of modules, each - of which stores an array of types associated with it. - + For more information of how the runtime type system now works, - please see Doc/Manual/typemaps.html and Doc/Devel/runtime.txt - - - Update all language modules to use the new type system. The changes - to each language module are minor. All languages are now able to - use runtime.swg for external access to the type system. Before - only python and perl did. - - - [guile, mzscheme, ocaml, and php4] These languages opened up the - init function inside the .cxx code, and any code in the .swg files - in the init section was inside this function. This was a problem - for swiginit.swg, which needs to be inserted before the SWIG_init - function is opened. Thus I changed these languages to be like - python or perl, where the init function is declared in the .swg - file. - - - [Ruby] Instead of moving the init function to the .swg file, I - added a new section initbeforefunc, and then added - %insert(initbeforefunc) "swiginit.swg" - - - [MzScheme] Fix enums and fix Examples/Makefile.in so that if - multiple -I arguments are specified in the INCLUDES variable, each - gets a ++ccf. - - - [Guile GH] Update Guile GH to use the new type system. See - Doc/Manual/Guile.html for how smobs are now used. - -01/11/2005: wsfulton - [C#] New typemap called 'csconstruct'. The code in this typemaps was previously hard - coded and could not be customised by a user. This typemap contains the code that is - generated into a proxy class's constructor. - - [Java] New typemap called 'javaconstruct'. The code in this typemaps was previously hard - coded and could not be customised by a user. This typemap contains the code that is - generated into a proxy class's constructor. Another typemap named 'javaconstruct_director' - is used instead when the proxy class is a director class. - - [C#, Java] If a C++ class did not have a default constructor, a protected default constructor - was automatically generated by SWIG. This seems is unnecessary and has been removed - and thereby giving the user almost complete control over the generated code along with the - new typemaps above. - -19/12/2004: mmatus - [Disabled, see entry 02/15/2004] - - Fix typemap search, now the "out" typemap search is done as follows - - int *Foo::foo(int bar) -> int *Foo::foo(int bar) - -> int *Foo::foo - -> int *foo(int bar) - -> int *foo - -> int * - - then, now you can be more specific, and define - - /* apply only for 'Foo::foo' method */ - %typemap(out) int * Foo::foo(int *bar) ...; - - /* apply for all 'foo' functions/methods */ - %typemap(out) int * foo(int *bar) ...; - - %inline { - struct Foo { - int *foo(int *bar); - }; - } - - -15/12/2004: mmatus - - More fixes for templates and template default args. - See template_default.i for scary cases that now are - supported, besides the already ugly STL/std cases. - - - Cosmetics and more use of 'const' where it was implicit. - - Other fixes for OSS, which is now working again with 1.3.25. - -Version 1.3.24 (December 14, 2004) -================================== - -12/12/2004: wuzzeb (John Lenz) - [Chicken] Fix a bunch of bugs relating to -proxy support - + non-class variables now export properly using -proxy - + static member functions now export properly using -proxy - + member class variables now export properly using -proxy - + added a -nounit argument, which does not export the (declare (unit ...)) - + correctly install swigclosprefix.scm - + constants (enums, defines) now correcly export when using -proxy - -12/11/2004: wsfulton - configure fix for when more than one version of jni_md.h is found - in the Java include directory (was generating lots of sed error - messages). - -12/08/2004: wsfulton - [Java] Fixes to arrays_java.i so that one can apply the array - typemaps to functions taking pointers as input, eg - - %include "arrays_java.i" - %apply int[] {int*}; - void foo(int *a); - -12/05/2004: wsfulton - [Java] Director mods contributed by Scott Michel. New typemaps - directordisconnect and directordisconnect_derived for the - swigDirectorDisconnect() method. Also fix to get the javapackage - typemap working again. - -12/05/2004: mmatus - - Finishing the fixes for templates + default template - args + specializations. - - - [Python] Now we use the new templates + default template - args in the std/STL library. That means the internal - swig files are getting uglier since we now support the - original declarations: - - template<class _Tp, class _Alloc = std::allocator< _Tp > > - class vector { - .... - }; - - template<class _Key, class _Tp, class _Compare = std::less<_Key >, - class _Alloc = std::allocator<std::pair<const _Key, _Tp > > > - class map { - .... - }; - - and the user can use the %template directive as - - %template() std::vector<int>; - %template() std::vector<int, std::allocator<int> >; - %template() std::vector<int, MyAllocator<int> >; - - Now we are closer to the cleaning/rewriting of the - python std/STL support, such that we recover support for - MSVC++ 6.0, and we can add support for other languages - too. - - -12/02/2004: wsfulton - [Java] Fix for directors when wrapping methods using a member enum - and typesafe/proper enums enabled. - -12/01/2004: mmatus - - Fix typemaps to work with templates and default template - args, ie - - template <class A, class B = int> - struct Foo { - }; - - %typemap(in) Foo<int> *{...} - %typemap(out) Foo<int,int> *{...} - - Foo<int> * foo( Foo<int> *f1, Foo<int,int> *f2); - - now 'f1', 'f2' and the return value resolve the provided - typemaps properly. - - This is highly needed for proper STL support, see new - std_basic_string.i, std_sstream.i, etc. - - - Added std_sstream.i, and fix std_basic_string.i to use - the new typemaps + template def. arg mechanism. Also, - added the needed std_alloc.i. Now, all the containers - can be modified to support std::allocator, like in: - - template<class T, class A = std::allocator<T > > - class vector { - public: - .... - }; - - This change is only completed by now for basic_string. - - - Fix for smart pointers + members + extensions: - - %extend Foo { - int extension(int i, int j) { return i; } - int extension() { return 1; } - } - - %inline %{ - - class Foo { - public: - int y; - static const int z; - }; - - class Bar { - Foo *f; - public: - Bar(Foo *f) : f(f) { } - Foo *operator->() { - return f; - } - }; - - now you can - - f = Foo() - f.y = 3 - a = f.z - f->extension() - - b = Bar(f) - b.y = 3 - a = b.z - b->extension() - - - Other small errors fixes, mostly python. - -11/25/2004: wsfulton - [Java] Numerous director bug fixes so that the correct java types - and canonicalized types in the JNI code are emitted. Use of the - $javaclassname special variables in the director typemaps now - consistent with the non-director typemaps. The types used for - typemap lookups are also corrected in a few places. If you - previously had your own director typemaps, ensure they are using the - correct C++ type. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA DIRECTORS *** - -11/25/2004: wsfulton - const enum SWIGTYPE & typemaps added. These wrap const enum references - as if they were passed by value. Const enum references thus work the - same as const reference primitive types such as const double &, - const int & etc. Typemaps added for Java, C#, Ruby, Tcl, Perl and Pike. - -11/25/2004: wsfulton - [Java, C#] New special variable: $*javaclassname, similar to $javaclassname - and $&javaclassname. The new one removes a pointer from the C type before - obtaining the Java class name. One or more of $javaclassname, - $&javaclassname or $*javaclassname may now appear in a typemap. Likewise for - C# using csclassname instead of javaclassname. - -11/25/2004: wsfulton - The last vestiges of enums being handled as integers removed from the - internals. The wrapper methods use the enum type rather than an int - now. The net result is added type safety for enums when handled as - pointers, references etc. Previously in situations such as a method - taking a pointer to an enum, a pointer to an int or a pointer to an - enum of some other type could inadvertantly be passed to the method. - This is now fixed as the descriptor for an enum is no longer based on - an int, but the enum type instead. Anonymous enums are still handled - as integers. - - The consequence for scripting language users in correct usage of enums - should not be noticeable. There is no change for any of the languages - where enums are passed by value - most of the scripting languages will - still accept an integer for an enum value and the strongly typed - languages still use either typesafe enums, integers or proper enums - depending on what the user configures. For Java and C# users a change - in the typewrapper class name has occurred (for enum pointers, - references etc). For example: - - enum Numbers { one=1, two }; - enum Numbers* number(); - - In Java and C# this must now be coded as - - SWIGTYPE_p_Numbers n = modulename.number(); - - rather than - - SWIGTYPE_p_int n = modulename.number(); - - *** POTENTIAL INCOMPATIBILITY *** - -11/21/2004: wsfulton/mmatus - Added missing deprecated warning for %name and remove remaining %name - usage in the SWIG libraries. - -11/21/04: mmatus - - [Python] Adding the PySwigObject to be used for carrying - the instance C/C++ pointers. This is used instead of - string and PyCObjects. - - The new PySwigObject is even safer than PyCObject, and - more friendly than plain strings: - - now you can do - - print a.this - <Swig Object at _00691608_p_A> - - print str(a.this) - _00691608_p_A - - print long(a.this) - 135686400 - - print "%s 0x%x" % (a.this, a.this) - _00691608_p_A 0x8166900 - - the last one is very useful when debugging the C/C++ - side, since is the pointer value you will usually get - from the debugger. - - Also, if you have some old code that uses the string - representation "_00691608_p_A", you can use it now again - using 'str(ptr)', or by calling 'str = PyObject_Str(obj)' - in the C/C++ side. - - This change is mainly for nostalgic swig users that miss - the string representation, but also allows to say again - - if a.this == b.this: - return "a is b" - - and well, since the change were really simple, maybe in - the future we will be able to do - - next = a.this + 1 - - or add native python iteration over native C/C++ arrays, - ie, no need to create/copy new tuples when returning and - array or vector. - - Also, a PySwigPacked object was adding to carry a member - method pointer, but this is probably a temporal solution - until a more general object for methods is added. - - Be aware that to simplify maintaining and compatibility - with other tools, the old string and PyCObjects - representation could disappear very soon, and the - SWIG_COBJECTS_TYPES or SWIG_NO_OBJECT_TYPES macros will - have no effect at compilation time. Still, the three - mechanisms are present in the code just for testing, - debugging and comparison purposes. - -11/21/04: mmatus - - - [Python] Adding back support for using the swig runtime code - inside the user code. We just allow the user to include - the minimal code needed to implement the runtime - mechanism statically, just as in done in the swig - modules. - - To use the swig runtime code, for example with python, - the user needs include the following: - - #include <Python.h> // or using your favorite language - #include <swigrun.swg> - #include <python/pyrun.swg> // or using your favorite language - #include <runtime.swg> - - the files swigrun.swg, pyrun.swg and runtime.swg can - be checked out by using swig -co, or they can simply - be found by adding the swig lib directory to the - compiler include directory list, for example - - SWIGLIB=`swig -swiglib` - c++ -I${SWIGLIB} .. - - of better, using the CPPFLAGS, but that depends on your - environment. - - This change can be ported to the other languages too, - you just need to isolate the needed runtime code in - a single file like 'pyrun.swg', and provide the - SWIG_Runtime_GetTypeList() method. Look at the - Lib/python/pyrun.swg file and the Examples/python/swigrun - example. - -11/15/04: mmatus - - Fix mixed_types.i + gcc-3.4, ie, arrays + references + - typedefs - - - Fix multidim arrays + typedefs,ie - - typedef char character[1]; - typedef character word[64]; - - - Process protected/private bases in the same way before - we process protected/private members, ie, we check - for constructors, operator new, virtual members, etc. - - - Fix Ruby/Java to work (or ignore) multi-inheritance + - directors. Allow other languages to define if it is - supported or not. - - - Now you can run - - SWIG_FEATURES="-directors -dirprot" - make check-ruby-test-suite - make check-python-test-suite - make check-java-test-suite - make check-ocaml-test-suite - - and you will get only 'real' errors. ruby and python - compile with no errors, java shows some problems. - -Version 1.3.23 (November 11, 2004) -================================== - -11/05/2004: wsfulton - Patch #982753 from Fabrice Salvaire: Adds dependencies generation for - constructing makefiles. New command line options -MF -MD -MMD to work - with the current options -M and -MM. These options are named the same - and work the same as in gcc. - -11/05/2004: wsfulton - %ignore/%rename changes for methods with default arguments to mirror - %feature behaviour. See previous entry. - - *** POTENTIAL INCOMPATIBILITY *** - -11/04/2004: wsfulton - %feature improvements for fine tuning when wrapping methods with - default arguments. Any %feature targeting a method with default arguments - will apply to all the extra overloaded methods that SWIG generates if the - default arguments are specified in the feature. If the default arguments are - not specified in the feature, then the feature will match that exact - wrapper method only and not the extra overloaded methods that SWIG generates. - For example: - - %feature("except") hello(int i=0, double d=0.0); - void hello(int i=0, double d=0.0); - - will apply the feature to all three wrapper methods, that is: - - void hello(int i, double d); - void hello(int i); - void hello(); - - If the default arguments are not specified in the feature: - - %feature("except") hello(int i, double d); - void hello(int i=0, double d=0.0); - - then the feature will only apply to this wrapper method: - - void hello(int i, double d); - - and not these wrapper methods: - - void hello(int i); - void hello(); - - This has been introduced to make %feature more powerful to ease the migration - to new default arguments wrapping approach. - - *** POTENTIAL INCOMPATIBILITY *** - - If you previously had a %feature and didn't specify the default arguments, - you will have to add them in now or you can obtain the original behaviour - by using %feature("compactdefaultargs"). - -11/04/2004: wsfulton - [C#] Typemaps for std::vector added into std_vector.i. The proxy classes - generated are modelled on the .NET ArrayList class. This isn't quite - ready for general consumption yet, but will work with vectors of primitive - types and some classes. - -10/3/2004: wuzzeb (John Lenz) - [GUILE] The -scm interface is now the default. The old GH interface can - still be enabled by passing -gh to SWIG. - -10/2/2004: mmatus - - - More fixes for namespace + class declarations. - As an extra bonus, we get %template support for static/members class - methods, ie, now you can say: - - namespace space { - struct A - { - template <class Y> - static void fooT(Y y) { } - }; - } - - struct B - { - template <class Y> - void barT(Y y) {} - }; - - %template(foo) space::A::fooT<double>; - %template(foo) space::A::fooT<int>; - %template(foo) space::A::fooT<char>; - - %template(bar) B::barT<double>; - %template(bar) B::barT<int>; - %template(bar) B::barT<char>; - - and call - - A.foo(1) - b = B() - b.bar(1) - - note the methods are emitted inside the classes, - and hence, the %template name refers to the 'member' - method name, not a global namespace name. - -10/31/2004: mmatus - - Solve namespace + class declarations, as in - - namespace foo { - struct Bar; - struct Foo { - }; - } - - struct foo::Bar : Foo { - }; - - see namespace_class.i for more examples. - - - Fix %template directive to properly use namespaces, - including the case: - - namespace one - { - template <typename T> - struct Ptr {}; - } - - namespace one - { - struct Obj1 {}; - typedef Ptr<Obj1> Obj1_ptr; - %template(Obj1_ptr) Ptr<Obj1>; - } - - namespace two - { - struct Obj2 {}; - typedef one::Ptr<Obj2> Obj2_ptr; - %template(Obj2_ptr) one::Ptr<Obj2>; - } - - this is done by using the namespace name 'one' to create - a namespace node to emit the template instantiation, - just as before, but the template parameters are resolved - and qualified in the current namespace ('one' or 'two'). - This is same way that typedef works. - - This resolve the smart_pointer_namespace2.i case, and at - the same time, several other ones where before swig was - generating the - - "Can't instantiate template 'xx' inside namespace 'yy'" - - error message. In fact, that error doesn't exist - anymore. You can only get an error if you use a bad - namespace name or so. - -10/30/2004: mmatus - - [ruby] Directors fixes: - - enums and std::strings are working now (several - reports in bug track system) - - added patch 1025861 for director + exceptions - - *** Attention ***: ruby with directors + protected - members work with version 1.7+. Older versions seems to - have a broken signature for'rb_protect'. - - If you need to use an old version, look at - - http://excruby.sourceforge.net/docs/html/ruby__hacks_8hpp-source.html - for workarounds. - - - [ruby] Fix memory allocation problem in typemap (bug 1037259) - - - [tcl] Fix (enums|constants) + namespace option - (reported by jason.m.surprise@intel.com). - - - [perl] Add patch 962168 for multiple inheretance - - - Fix 'defined' as variable name. - -10/29/2004: wsfulton - Seg fault fix for global scope operator used for friend methods: - - class B { - friend void ::globalscope(); - ... - }; - -10/28/2004:mmatus - - Added module and swig option "templatereduce" to force swig - to reduce any type needed with templates, ie, in these cases - - %module("templatereduce") test - - template <class T> struct A { }; - - typedef int Int; - %template(A_Int) A<Int> ==> %template(A_Int) A<int> - - typedef B* Bp; - %template(A_Bp) A<Bp> ==> %template(A_Bp) A<B*> - - swig reduces the types Int and Bp to their primitives - int and B*. This is closer to the usual compiler - resolution mechanism, and it is really needed sometimes - when you mix templates + typedefs + specializations. - - Don't use it if you don't have any problem already, - since the type reduction can interfere with some - user typemaps, specially if you defined something like - - typedef int Int; - %typemap(in) Int ...; - - in this case, when you use the "templatereduce" option, - swig will ignore the user typemap, since the "typedef int Int" - will take precedence, and the usual "int" typemap will be - applied. - - Note that the previous case is not common, and should be - avoided, ie, is not recommended to use a typedef and a - typemap at the same time, specially if you are going to - use templates + specializations. - - - Directors: - - virtual destructor is always emitted now, this doesn't - cause any harm, and could solve some nasty and - mysterious errors, like the one mentioned by Scott. - - also the destructor is not in-lined, so, that can solve - some other mysterious errors when mixing directors + - imports + embedded applications + some specific compilers. - -10/27/2004: wsfulton - [C#] typemaps.i library file with INPUT, OUTPUT and INOUT typemaps added. - -10/27/2004: wsfulton - [Java] std::wstring typemap fixes in std_string.i from Russell Keith-Magee. - -10/25/2004: mmatus - - - Using + namespace is working now (using_namespace.i). - - - Derived + nested classes is working now - (deriver_nested.i), but of course, we are still waiting - for the nested class support. - - - Directors: - - unnamed parameters support, - - - protected constructor support (automatic and with - dirprot mode), - - - detection of really needed protected declarations - (members and constructors) now is done automatically. - Even if you don't use the 'dirprot' mode, swig will - wrap what is minimally needed (and protected) for the - code to compile. - - what is public, as usual, is always wrapped, and if - you use the 'dirport' - - - - Final fixes for the OSS to compile with SWIG 1.3.23 (my - very very ugly C++ + templates + everything mounters wrap). - -10/25/2004: wsfulton - [C#] New commandline option -dllimport. This enables one to specify - the name of the DLL for the DllImport attribute. Normally this name - comes from the module name, so now it is possible to override this: - - swig -csharp -dllimport xyz example.i - - will generate for all the wrapped PInvoke methods: - - [DllImport("xyz", EntryPoint="...")] - public static extern ... - - The wrappers from many different SWIG invocations can thus be compiled - into one DLL. - - A new special variable $dllimport can also be used in typemaps, pragmas, - features etc. This will get translated into the value specified by -dllimport - if specified, otherwise the module name. - -10/22/2004: wsfulton - [Java] Patch #1049496 from Scott Michel fixes directors methods with - enums when wrapped with typesafe or proper Java enums. - -10/21/2004: wsfulton - Fixes for default arguments in director constructors (Python, Ruby, Ocaml). - -10/21/2004: mmatus - - [Python] Add the '-cpluscast' option to enable the 'new' - C++ casting operators, such as 'static_cast', inside the - typemaps. By default swig use the old C cast style, even - when parsing C++. - - - [Python] Add the '-new_vwm' option to enable the new - SwigValueWrapper mode. Now this is mainly for testing - that the typemaps are really safe for any future - solution, but you can use it if you have a very strange - error with default cosntructors missing + %apply + - %typemap, and if everything else fails (see - valuwrapper_opaque.i for alternative and current - solutions). If you are a user that don't know what is - SwigValueWrapper, don't even try it. - - - [Python] Add the '-noh' option to be used with directors - and when you prefer to disable the generation of the - director header file. If not used, swig will work as - usual generating both the wrap.cxx and wrap.h files. If - you use it, swig will only generate wrap.cxx. - -10/21/2004: wuzzeb (John Lenz) - - If you define SWIG_TYPE_TABLE when compiling a wrapper file, - the runtime types will be stored in the given type table name. - Using this, you can seperate different modules to share their - own type systems. -DSWIG_TYPE_TABLE=Mytable - - - [Python] If you define SWIG_STATIC_RUNTIME then the type information - will be static to this wrapper. Nothing will be shared with any - other modules - - - [Python] If you define SWIG_LINK_RUNTIME, then instead of using - the new way of sharing type information, the wrapper will expect - to be linked against the Lib/linkruntime.c file. Any modules compiled - with SWIG_LINK_RUNTIME and linked against linkruntime.c will all - share type information. - -10/20/2004: mmatus - - [Python] Initial fix for python/import example. Please - update the Makefile (autoconf, configure, etc, expert), - since now probably is only working with g++, icc and a - few other compilers that have the -shared option. - - We need to create additional shared libraries for the - virtual destructors. Old and usually forgotten C++ - requirement. - - Same fix need to be used in perl, I think. - - - [Python] Fix generation of header file for directors, - now directors.swg is also included, so, it can be really - used from C++, and it solves some problem with compiler - that require that, even with the simple swig inclusion. - - - [Python] Reordering the methods and moving some bodies - outside the class declaration. This is needed due to - some gcc-2.96 internal compiler errors. It seems the - PYTHON class is getting too large to been declared and - defined at the same time. - - - Add the -oh option to change the output header file name - if needed: - - swig -c++ -python test.i -o test.CC -oh test.HH - - this is mainly needed when using directors, and if the - current default header file name is not good for you, - which is generated as follow: - - swig -c++ -python test.i => test_wrap.h - swig -c++ -python test.i -o test.CC => test.h - - -10/20/2004: wsfulton - 1) Compact default arguments feature added. This feature allows one - to use the default argument code generation that was used in - SWIG-1.3.22 and earlier versions. It produces more compact wrappers - as only one wrapper method is generated for any method with default - arguments. So the advantage is it generates less code but has the - original limitations, like it it does not work with all default arguments - and default arguments cannot be taken advantage of in the strongly typed - languages (C# and Java). It is implemented via the usual %feature mechanism: - - %feature("compactdefaultargs"); - - 2) Keyword arguments (kwargs) are working again for default arguments - in the languages that support it, ie, Python and Ruby. The new default - argument wrapping approach using overloaded methods cannot support kwargs - so the compact default argument feature is automatically turned on when - kwargs are specified, by %feature("kwargs"). - - 3) Compact default arguments are also automatically turned on when wrapping - C (not C++) code. This is to support the bizarre notion of default arguments - for C code. - -10/20/2004: wsfulton - Overloaded templated functions in namespaces also working now. - Templated functions with default arguments in namespaces too. - -10/19/2004: mmatus - - - Allow to disable the new SwigValueWrapper mechanism, - if you add the following line in your language main. - - /* Turn on safe value wrapper use mode */ - Swig_value_wrapper_mode(1); - - - Now is only active in python. All the other languages - are using the old resolution, but they can also use the - "valuewrapper"/"novaluewrapper" features to fix some - of the old broken cases. Note, however, that not all - the broken cases can be solved in that way. - - The new mechanism seems to be working fine in perl, ruby - and tcl, but failing in some typemaps in java. - - Hence, is upto the language maintainer to test it, and - decide to enable it or not. - - Look at the valuewrapper_opaque.i for examples. - - - Fix more SwigValueWrapper cases when the new mechanism - is active. Now it also check for local typemap - variables, see valuewrapper_opaque.i for an example when - this is needed. But again, this extra checking will only - be activated when using the new value wrapper mode. - - - [Python] Fix variable wrapping of classes with private - assign operators. It should be easy to fix in all the - other modules, instead of checking - - if (!Getattr(n,"immutable")) ... - - you need to verify - - if (is_assignable(n)) ... - - Look at the private_assign.i for an example. - -10/18/2004: mmatus - - %features "director"/"nodirector" now work as expected. - - General fixes in %feature to resolve function decl - properly, - - %feature("hello") foo(); - char foo() -> f() // was working - char *foo() -> f().p // it wasn't - - - - Template + specialization + default template args now is - working, (don't confuse with template + default arg - values, that was solved before), now this ugly case is - working: - - template <class T, class A = Alloc<T> > - struct Vector - { - Vector(T a){} - }; - - template <> - struct Vector<double> - { - Vector(){} - int foo() { return 0; } - }; - - %template(V_c) Vector<char, Alloc<char> >; - %template(V_i) Vector<int>; // picks Vector<int,Alloc<int> > - %template(V_d) Vector<double>; // picks the specialization - - this is needed for automatic STL support (later will - be). - - - Fix the template + typedef errors in test-suite, which - probably will fix another group of strange template + - namespaces + typedefs errors. - - - %warnfilter is working better now, parser.y tries to use - them when needed. - - - **** New default type resolution method (stype.c) ***** - - It preserves the original mixed types, then it goes - 'backward' first deleting the qualifier, then the inner - types, for example: - - typedef A *Aptr; - const Aptr&; - r.q(const).Aptr -> r.q(const).p.SWIGTYPE - r.q(const).p.SWIGTYPE -> r.p.SWIGTYPE - r.p.SWIGTYPE -> r.SWIGTYPE - r.SWIGTYPE -> SWIGTYPE - - enum Hello {}; - const Hello& hi; - r.q(const).Hello -> r.q(const).enum SWIGTYPE - r.q(const).enum SWIGTYPE -> r.enum SWIGTYPE - r.enum SWIGTYPE -> r.SWIGTYPE - r.SWIGTYPE -> SWIGTYPE - - int a[2][4]; - a(2).a(4).int -> a(ANY).a(ANY).SWIGTYPE - a(ANY).a(ANY).SWIGTYPE -> a(ANY).a().SWIGTYPE - a(ANY).a().SWIGTYPE -> a(ANY).p.SWIGTYPE - a(ANY).p.SWIGTYPE -> a(ANY).SWIGTYPE - a(ANY).SWIGTYPE -> a().SWIGTYPE - a().SWIGTYPE -> p.SWIGTYPE - p.SWIGTYPE -> SWIGTYPE - - before it always stops after finding ref/pointer/enum/array/etc. - - Now, then, you can define (use and apply) 'higher' typemaps such as: - - %typemap(in) SWIGTYPE* const& - %typemap(out) char FIXSIZE[ANY] - %typemap(in) SWIGTYPE* const& - %typemap(in) const enum SWIGTYPE& - %typemap(in) SWIGTYPE[ANY][ANY] - %typemap(in) const char (&)[ANY] - - It is possible with this change that previous typemaps - that were defined (but ignored), now will start to work. - - Also, it is necessary check for the '%typemap(varin) SWIGTYPE[]', - before it was usually not defined (but char[] was), - and that can produce some inconsistencies. - - *** POTENTIAL INCOMPATIBILITY *** - - This change was needed for STL, since std::vector<enum Hello> - std::vector<A*>, etc, will always generate methods that - mix const references with the vector type. - - Now that is working, all the std::container<T*> - specialization will not be needed anymore, well, in - theory. - - In the practice, everythin is working as before until - the proper mixed types are defined and the libraries - simplified to use them. - - - Change the behavior of extern "java"/"fortran"/"etc", - now swig produces a warning, and use extern "C" instead. - The warning can also be disable with the "-w 313" flag. - (WARN_PARSE_UNDEFINED_EXTERN). - - - SwigValueWrapper is now more selective (lang.cxx). - - [Perl/Tcl] - - Fix some typemaps (perl/tcl) to work properly with - SwigValueWrapper. This was not a problem with - SwigValueWrapper, but with the typemaps that now are - safe to use with %apply. - - [Python] - - - Fix %callback/%pythoncallback work now as before after - the def args changes. Also, %callback now is an alias - for %pythoncallback, so, they do the same. - - [Python/Ruby] - - %callback is more usable and uniform: - - %callback("%s_cb") foo(); // for both, python/ruby - %callback("%s_cb"); // for both, python/ruby - %callback(1) foo(); // only in python. - -10/17/2004: arty - [OCAML] - - Tweak to enum typing for soundness in the presence of multiple - modules. - - global functions are now unambiguous in multiple loaded modules. - - Fixed test case code to build multimodule test cases correctly. - - There is no way to share overload resolution across modules - because of soundness issues. If the user wants to call some - function foo from an arbitrary module bar, they will have to - use Bar._foo to call it correctly. Later I will fix the - camlp4 module to do something clever in this case. - - Promided performance overhaul of class mechanism. - - Removed symbol hack for ocaml-3.07 and below which is not needed - for ocaml-3.08 and above. - -10/16/2004: wuzzeb (John Lenz) - [CHICKEN] - - Completly change how chicken.cxx handles CLOS and generic code. - chicken no longer exports -clos.scm and -generic.scm. The clos - code is exported directly into the module.scm file if -proxy is passed. - - The code now always exports a unit. Running the test-suite is now - majorly broken, and needs to be fixed. - - CLOS now generates virtual slots for member variables similar to how - GOOPS support works in the guile module. - - chicken no longer prefixes symbols by the module name, and no longer - forces all names to lower case. It now has -useclassprefix and -closprefix - similar to how guile handles GOOPS names. - -10/16/2004: wsfulton - Templated functions with default arguments working with new default argument - wrapping approach. The new approach no longer fails with the following default - argument pattern (previously failed with some primitive types, like - unsigned primitive types): - - template<typename T> int foo(const T& u = T()); - %template(foo) foo<unsigned int>; - - This relies on the templated function overloading support just added, so all - the combinations of overloading by template parameters and normal parameters - as well as overloading with default parameters works. - -10/16/2004: wsfulton - Added support for the large range of templated function overloading that C++ - supports. - - - Overloaded templated functions, eg - - template<typename T> int overload(T t); - template<typename T> int overload(T t, const T &r); - - - Fixes where the templated type is not used in the parameter list, eg - - template<typename T> void xyz(); - template<> void xyz<double>(); - - - Fixes for overloading of plain functions by a templated function: - - void abc(double d); - template<typename T> void abc(T t); - - - Overloading by templated parameters fixed: - - template<typename T> void foo(T t) {} - template<typename T, typename U> void foo(T t, U u) {} - - %template(foo) foo<double, double>; - - - All combinations of the above also working including specializations, eg: - - void abc(double d); - template<typename T> void abc(T t); - template<> void abc<double>(double t); - template<> void abc(int t); - -10/16/2004: wuzzeb (John Lenz) - - Remove the ability to share type information by using c linking. - All type sharing happens through a global variable in the target language. - + Remove SWIG_NOIMPORT, SWIG_RUNTIME, and related defines. - + Deprecate -runtime, -noruntime command line options - + Update test-suite common.mk to correctly build multicpptest - + Remove reference to precommon.swg - + Update the guile_gh interface to share data by a global var instead - of c linkage. - - - Remove Advanced.html, since everything in it is now obsolete - -10/09/2004: mmatus - - Split the python std/STL C++ library files, now - all the language independent definitions are under - the directory - - Lib/std - - and hence, can be used from other languages. - - - Add more documentation to the Python STL, and - clean unnecessary code. - - - Add initial C99 complex support, and some fixes - for long double. - -10/08/2004: mmatus - - Fix the SwigValueWrapper for opaque types, now it is - applied for opaque templates and classes, for which we - don't know if there is or not a default constructor, ie - - struct A { - A(int); - }; - - Still, if you know that you class has a default - constructor, and for some very very particular reason - you want to avoid the SwigValueWrapper, and you don't - want or can't expose the class to swig, now you can - say - - %feature("novaluewrapper") A; - class A; - - or the other way around, if the class has a default - constructor, but you want to use the value wrapper, you - can say - - %feature("valuewrapper") A; - struct A { - A(); - .... - }; - - - Fix for char > 128, ie - - const char tilde_a = '\341'; - - - Add patch 1041858 for $lextype, which carries the - literal type of a symbol. See lextype.i in the - test-suite for more details. - - - - -10/07/2004: wsfulton - {Ruby, Java] Fix director + 'empty' throws - - struct A { - A() throw(); - virtual ~A() throw(); - int foo() throw(); - }; - - -10/06/2004: wuzzeb (John Lenz) - [TCL] - - Fix bug reported by William A. Hoffman propagating clientdata - between modules. Added clientdata_prop.multicpptest to check for - this bug. The fix involved the following changes: - + SwigType_clientdata_collect does not need to check - types in r_resolved because we only want to propagate clientdata - to typedefed classes, and r_mangled already takes care of typedefs. - - + SWIG_TypeRegister now copies the clientdata field correctly - - + Move SWIG_Guile_PropagateClientData function from guile module - into common.swg, because we need to call it from both guile and tcl. - - + Add base_names to swig_class to delay the lookup of bases. SWIG - now exports the base names and only when the base swig_class is - needed is SWIG_TypeQuery(name)->clientdata looked up. - - - conversion_ns_template testsuite test was failing because - the name of the wrapped constructor function was not calculated - correctly for structs. Fixed. - -10/06/2004: wsfulton - Fixes for default arguments used in directors - in virtual - methods and director constructors. - -10/06/2004: mmatus - Fix the __cplusplus macro, and bug 1041170. - Now it is working as supposed, ie, you can safely use - - #ifdef __cplusplus - ... - - all over swig, including inside %defines and %{ %} bodies. - - - *** POTENTIAL INCOMPATIBILITY *** - - The old trick of using - - #if __cplusplus - - doesn't work any more. So, if you have your own typemaps - using that syntax, you will need to migrate them to use - "#ifdef __cplusplus". - -10/05/2004: wuzzeb (John Lenz) - - Reorganize how runtime type information is stored and shared - between modules. For chicken and mzscheme, I removed - the ability to use runtime libraries, while perl, tcl, python, and - ruby default to using the new method but can go back to the old - method by declaring SWIG_ALLOW_RUNTIME. - - - line 582 in mzscheme.cxx was generating a segfault on - imports.multicpptest, so I fixed it. - -10/05/2004: wsfulton - Fixes for %extend and overloaded static methods with default - arguments. - -10/05/2004: mmatus - - [python] Fix director + method with 'empty' throw, ie - - struct A { - virtual int foo() throw(); - }; - - other languages should also easy to fix, look for - Getattr(n,"throw") in python.cxx. - - - Fix director + destructor with 'empty' throw - - struct A { - virtual ~A() throw(); - }; - - - Now SWIG_FEATURES parse all and the same options you - can pass to swig in the command line. - - - New command line flag: -features <list>, as in - - swig -features autodoc=3,director - - ie, any global feature can be initialized from the - command line. This is mainly for testing, but users - can also take advantage of it. - -10/04/2004: mmatus - - Properly qualify type in syntax as 'long(2)' or 'Foo()', - this solve old problem with default args, and probably - other problems around. However, the default arg problem - was also already solved by William (see below). - - - Fix feature_set and feature_get methods. Before - they look from particular to general and keep the first - feature found. This didn't work well with templates. - Now the methods look from general to particular, and - override any found feature. - - - Previously a feature could not be applied to constructors - or destructors that weren't explicitly declared in the class. - This is now fixed, for example: - - %feature("featurename") Foo() "..." - %feature("featurename") ~Foo() "..." - class Foo { - // implicit Foo() and ~Foo() - }; - - - Fix missing features for default const/dest, by really - 'creating' the methods and applying the features. - - - Fix return_const_value.i case by adding SwigValueWrapper<const T> - specialization. - - - Fix %extend + overload, including overloading actual - class methods. - - - Adding more cases in related files in the test-suite. - -10/04/2004: wsfulton - Changes to the way default arguments are wrapped. Previously a single - method was generated for each method that had default arguments. If - a method had 5 arguments, say, of which 1 had a default argument - then the call to the wrapped method would pass 5 arguments. The default - value was copied into the wrapper method and used if the scripting - language passed just 4 arguments. However, this was flawed as the - default argument sometimes does not have global access, for example - SWIG would generate code that couldn't compile when wrapping: - - class Tricky { - public: - void foo(int val = privatevalue); - void bar(int val = Tricky::getDefault()); - private: - static int getDefault(); - enum { privatevalue = 200 }; - }; - - Also bugs in resolving symbols generated code that wouldn't compile, for example - (probably fixable though): - - namespace Space { - class Klass { - }; - Klass constructorcall(const Klass& k = Klass()); - } - - The approach also does not work for statically typed languages (C# and Java) - as these languages do not allow methods to have variable number of arguments. - Although C# has a mechanism to pass a variable number of arguments they - must be of the same type and are more like varargs. - - The new approach solves the above problems and wraps methods with default - arguments as if the method was overloaded. So SWIG will now treat - - void foo(int val=0); - - as if it had parsed: - - void foo(int); - void foo(); - - The code generated is then exactly the same as if SWIG had parsed the two - overloaded methods. The scripting languages count the arguments passed and call - the appropriate method, just like overloaded methods. C# and Java are now able - to properly wrap methods with default arguments by generating extra methods, - again as if the method was overloaded, so for: - - void bar(string s="hello", double d=10.0, int i=0); - - the following proxy methods are generated: - - void bar(string s, double d, int i); - void bar(string s, double d); - void bar(string s); - void bar(); - - The new approach comes with a couple of minor knock on effects. - - 1) SWIG support for default arguments for C (not C++) code no longer works. - Previously you could have this interface: - - %{ - void foo(int val); - %} - void foo(int val=0); - - and call the wrapped method from a scripting language and pass no arguments - whereupon the default of 0 was used. You can get the same behaviour for C - code by using the "default" typemap: - - %typemap(default) int val "$1 = 0;" - %{ - void foo(int val); - %} - void foo(int val); - - or you could of course compile your code as C++ if you want C++ features :) : - - %{ - void foo(int val=0); - %} - void foo(int val=0); - - A couple of SWIG's libraries used this C extension and these have been modified - to use the "default" typemap. The "default" typemap is thus unchanged (and still - is not and is not fully supported by C# and Java, and is likely to remain so). - - - 2) All features (%feature, %rename, %ignore etc) no longer work as if the method - with default arguments is just one method. For example, previously - - %ignore foo(int); - - would have ignored the method completely. Now it will only ignore foo(int) but - not the extra foo() method. Instead use: - - %ignore foo; - - to ignore them all. or - - %ignore foo(int); - %ignore foo(); - - This of course allows one to fine tune the wrapping, for example one could use: - - %rename(fooint) foo(int); - %rename(foodefaults) foo(); - void foo(int val=0); - - and call them from any language like so: - - fooint(200) - foodefaults() - - or for example ignore the extra overloaded method, so the defaults cannot be used: - - %ignore foo(); - void foo(int val=0); - - *** POTENTIAL INCOMPATIBILITY *** - -10/2/2004: mmatus - [Python] - - More cleaning up and uniformation on the Python Lib - - - Added Robin's docstring patch, plus some fixes, plus - some extensions, see autodoc.i example in the test-suite, - and try using %feature("autodoc","extended"). - - This patch is not a complete solution for the - documentation problem, just enough to inform python about - the parameter list. - - The expected swig documentation support is far far away yet. - - -10/1/2004: mmatus - - Fix the %callback feature (only used in ruby and python examples, - by now, but it should be generic), now member callbacks - are working again - - - Fix wrapping of functions pointers like - - std::ostream& std::endl(std::ostream&); - - ie, the ones that return references or enums. - - [Python] Add the %pythoncallback directive, which is - an improved version of %callback, ie, - - %pythoncallback(1) foo; - %pythoncallback(1) A::bar; - %pythoncallback(1) A::barm; - - int foo(int a) { - return a; - } - - struct A - { - static int bar(int a); - int barm(int a); - - }; - - int foobar(int a, int (*pf)(int a)); - - in python you can use - - foo(2) - foobar(2,foo) - A.bar(2) - foobar(2,A.bar) - - ie, no additional pointer elements are created, and - the original 'foo' and 'A.bar' can be used as parameters. - - In the case of member function however, still you need - to use the special variable Class::<fnc_name>_cb_ptr, ie: - - foobarm(3, a, A.barm_cb_ptr) - - we will try to fix this situation also, but later. - - [Python] Add more elements from the STL library, now - you can use - - import std - std.cout << "hello " << 123 << std.endl - - [Python] Fix in/out return mechanism, now swig will behave - as 1.3.21 but using a python list when needed. The problem - is that the types std::pair,std::vector,etc, use tuples, - and they interfer with the previous inout tuple type. - - By using lists we solve the conflicts, swig acts as before, - but returns a list when more than one parameter are using - the OUT typemap. See the new inout.i example in the - test-suite. - - *** POTENTIAL INCOMPATIBILITY FOR PYTHON MODULE *** - - [Python] Much better error messages for bad arguments, now - you always get the argument number where the error occurred. - -09/27/2004: wsfulton - Patch from Bill Clarke - - 1) Warning emitted when -importall and -includeall is used together, - with -includeall taking precedence. - 2) Ensure SWIGIMPORTED is always defined when a file is being - imported with %import. Note that this is not the same as SWIGIMPORT, - which gets defined in all generated wrapper files. - -09/26/2004: mmatus - - - add %feature("exceptionclass") to identify a class used - as exception. Before swig identified and marked a class - using the "cplus:exceptionclass" attribute. However, the - class needed to appear on an throw() statement. Now - swig keeps trying to identify the exception classes, as - before, but it also allows the user to mark a class by - using the %feature explicitly. (mostly relevant for - python and chicken) - - [Python] - - - fix -modern option + exceptions, which mix old class - style with the new one. So, we always need to emit - the "nonmodern" python code. - - - add the "python:nondynamic" feature and its handler - - now if you have - - %pythonnondynamic A; - - struct A { - int a; - int b; - }; - - then, in the python side - - aa = A() - - aa.a = 1 # ok - aa.b = 2 # ok - aa.c = 3 # error, the class can not be extended dynamically. - - - Since this is a feature, you can use - - %pythonnondynamic; - - or - - %pythondynamic; [ Note: %pythondynamic since deprecated ] - - to force all the wrapped classes to be "nondynamic" ones. - - The default, as in regular python, is that all the wrapped - classes are dynamics. So, careful with your spelling. - -09/14/2004: mmatus - - Support the -I- option. - - - Differentiate between %include <file> and %include "file". - This fix several corner cases. - - - [Python] Several patches: - - - Normalize the Lib file names: - *.swg internal files, - *.i user files. - - - Fix Char[ANY] typemaps, so they also delete any extra '\0' chars, - now they behave as before (1.3.21). Still, you can use - the SWIG_PRESERVE_CARRAY_SIZE macro if you need to - preserve the original size (see pystrbase.swg). - - - Add the Char FIXSIZE[ANY] typemaps, to preserve the - original C array sizes (see above). Though, you can't - use them yet since %apply and arrays are not working - together. - - - Add pyfragments.swg, now the user can add fragments - to override the default ones. - -09/10/2004: wsfulton - Patch from Bill Clarke which fixes spurious preprocessor bug which - shows on Solaris and gcc, eg: - Warning(202): Could not evaluate '!defined(SWIGJAVA) && - !(defined(SWIGCSHARP)' - Also fixes a bug where '#if "a" == "b" == 1' wouldn't have worked - -09/10/2004: wsfulton - Restored multiple build directories for the test-suite. Patch from - Bill Clarke. - -09/06/2004: wsfulton - Added the missing runtime.dsp Visual Studio project files for the - import examples to work. - - -Version 1.3.22 (September 4, 2004) -================================== - -09/03/2004: wsfulton - The swig.m4 macro for use with the Autoconf/Automake/Libtool has - been removed and is no longer installed. Please use the new and better - maintained version derived from swig.m4 in the Autoconf macro archive. - See http://www.gnu.org/software/ac-archive/htmldoc/ac_pkg_swig.html and - http://www.gnu.org/software/ac-archive/htmldoc/ac_python_devel.html. - -09/01/2004: wsfulton - [Perl] Applied patch #1019669 from Christoph Flamm. Adds support - for %feature("shadow") in the same way as it works in Python. This - enables one to override the generated shadow/proxy methods, including - constructors and destructors. For example: - - /* Let's make the constructor of the class Square more verbose */ - - %feature("shadow") Square(double w) - %{ - sub new { - my $pkg = shift; - my $self = examplec::new_Square(@_); - print STDERR "Constructed an @{[ref($self)]}\n"; - bless $self, $pkg if defined($self); - } - %} - - class Square { - public: - Square(double w); - ... - }; - -08/31/2004: mmatus - [Python] Incompatibility reported by Bill Clarke (llib@computer.org): - - If you are using Sun Studio 8 (and possibly earlier - versions) to compile the output produced by swig - 1.3.22rc1, and you are using C++ and STL templates then - you need to use either "-runtime" or "-noruntime". If you - use neither of these options then you will probably get - compiler errors when trying to compile the wrapper file; - the error message will be like this: The name - SWIG_Python_ConvertPtr[...] is unusable in static - swigpy::traits_asptr[...] If you get this error message, - you need to regenerate your wrapper file using 'swig - -runtime' or 'swig -noruntime'. - - You shouldn't get this problem with Sun Studio 9. - - *** POTENTIAL INCOMPATIBILITY FOR PYTHON MODULE *** - -08/26/2004: wsfulton - [Perl] Applied #932333 from Ikegami Tsutomu. Fixes long long *OUTPUT - and unsigned long long *OUTPUT typemaps in typemaps.i. - -08/26/2004: wsfulton - Applied patch #857344 from Art Yerkes. Workaround for autoconf bug when - running 'make install'. - -08/26/2004: wsfulton - [Perl] Part of patch #982753 applied. This implements a %perlcode directive. - It allows one to add Perl code to the generated .pm file. Works the same - as %pythoncode. - -08/26/2004: wsfulton - [Java] Fix for directors when wrapping virtual methods with exception - specifications that were not simple types. Previously code was generated that - didn't compile, for example when the exception specification was a pointer. - -08/25/2004: wsfulton - [C#] Typemap fix for methods that return char *. The CLR would incorrectly - delete the memory pointed to by char *. Also applied the same correction to - the char array typemaps. - -08/24/2004: wsfulton - Fixes for -fmicrosoft error/warning message display: - - End of file (EOF) warning messages not displaying in correct format - - Some messages containing a file path were displaying a double backslash - instead of a single backslash - -08/23/2004: wsfulton - Applied patch #1011604 submitted by Charles Schwieters. Fix for 64 bit tcl - interpreters. - -08/23/2004: wsfulton - Fix for bug #875583 - enum forward declarations previously gave a syntax error. - -08/23/2004: mkoeppe - [Allegro CL] Use typemaps "ffitype" and "lisptype" to determine the FFI type - specifiers from the C type. This makes it possible, for instance, to control - whether a C "char" argument takes a Lisp character or a Lisp integer value. - The default (taking Lisp characters) is done by these built-in typemaps: - %typemap(ffitype) char ":char" - %typemap(lisptype) char "character" - If char means an integer instead, use these typemaps: - %typemap(ffitype) char ":char" - %typemap(lisptype) char "integer" - -08/22/2004: wsfulton - As discussed in bug #772453, the SWIG library directory is now installed - into a different default directory. The library used to be installed to - /usr/local/lib/swig1.3. It is now in the more usual architecture independent - directory and I have additionally used a version specific subdirectory as - the library will rarely work with older versions of SWIG. This release - will thus use /usr/local/share/swig/1.3.22 by default, which can be - tailored as before using './configure --swiglibdir'. - -08/17/2004: mkoeppe - [MzScheme] Add support to create native MzScheme structures from C structures. - To convert a C structure to an MzScheme structure, use the new runtime macro - SWIG_NewStructFromPtr in a typemap. Patch from Dmitriy Zavin. - -08/12/2004: wsfulton - Patch #837715 from Ben Reser to correctly detect Python lib directory - on 64 bit systems. - -08/12/2004: wsfulton - [C# and Java] Prevent memory leaks in the case of early return - from wrapper methods using const std::string & parameters. Modified - Mark Traudt patch #951565. - -08/12/2004: wsfulton - Bug #943783 with patch fixes php char * out typemap NULL values. - -08/03/2004: Ahmon Dancy <dancy@dancy> - - [allegrocl] Additional case mode fixes. Also, make sure - foreign types are exported. - -07/24/2004: mkoeppe - [Guile] In -scm mode, SWIG modules now exchange their pointer type - information via the Guile interpreter. It is no longer necessary to build a - runtime library or to use -noruntime and -runtime etc. - - The module (Swig swigrun) which was introduced in the change of 05/17/2004 is - no longer automatically built. If you need it, run SWIG on the interface file - swigrun.i. - -07/23/2004: wsfulton - [C#] Bug #917601 Mapping C++ bool fix from Mark Traudt - -07/23/2004: wsfulton - RPM fixes for latest CVS version including removal of runtime - library. - -07/23/2004: wsfulton - Patch #908955 from Robert H De Vries. - RPM file generation fix for Fedore Core 1 and Redhat AS2.1. - -07/12/2004: wsfulton - Patch #864689 from Robin Dunn: - - This patch corrects two problems in the XML output of SWIG: - - 1. There were often extra '/>\n' in the output. - - 2. value attributes were output with '\n' in them but - since that is not technically legal most (all?) XML - parsers will strip them out. Replacing the '\n' with - the ' ' entity reference solves this as that is - legal and XML parsers will convert it to a '\n' when - reading the values back in. - - This patch also adds a new global command line option - that will allow the parse tree to be written out in XML - *after* some other language module has been run, in - order to be able to get extra info that the language - module puts in the tree. In this way the XML is a - post-processed version of the tree rather than a - pre-processed version. - - Command line option is -dump_xml or -xmlout <file> - -07/12/2004: wsfulton - [Java] Patch from Scott Michel to fix typesafe enums and proper enums - with directors. - -07/12/2004: wsfulton - HTML documentation (makechap.py) file generator missing end of line - patch #908951 from Robert de Vries. - -07/08/2004: wsfulton - The deprecated runtime library build has been removed. This also removes - the dependency on Libtool. Libtool is no longer required to build SWIG. - The associated -ldflags SWIG commandline option has also been removed. - - The examples and test-suite testcases that used the runtime library have - been updated to use the replacement approach to using SWIG across - multiple modules, that is they use the -noruntime and -runtime commandline - options, see Modules.html. Effectively they build their own runtime - libraries using -runtime. The examples are import and import_template. - The test cases are in the imports and template_typedef_import directories. - - Anyone who wants the original runtime libraries can either run the test-suite - or build the examples and use the appropriate shared object/DLL that is - generated with the -runtime commandline option. For example libimports_runtime.so - (Python calls it lib_imports_runtime.so) is generated after running the - 'make imports.multicpptest' testcase in the Examples/test-suite/<lang> - directory. Or use libruntime.so / runtime.dll after building the import - examples in Examples/<lang>/import. - -07/07/2004: mkoeppe - [Allegro CL] Convert character and string literals in constants to - CL syntax. Fix FF:DEF-FOREIGN-CALL for mixed-case C functions. - -06/27/2004: wsfulton - [Java] New feature for Java exceptions with format %javaexception(exceptionclasses). - This feature is a slight enhancement to %exception and the only difference is the - addition of the exception classes which are generated into a throws clause. - The 'exceptionclasses' is a comma separated list of classes which will be - added to the associated proxy method's throws clause. The 'exceptionclasses' - are specified like the exception classes in the 'throws' attribute in the - typemaps. This feature should be used for correctly handling checked exceptions - thrown from JNI code. For example: - - %javaexception("java.lang.Exception") throwException %{ - ... convert a std::logic_error into a java.lang.Exception using JNI code ... - %} - - #include <stdexcept> - void throwException() { - throw std::logic_error("Logic error!"); - } - - will generate a method with a throws clause in the module class: - - public static void throwException() throws java.lang.Exception { ... } - -06/27/2004: wsfulton - [C#] New %csconstvalue(value) feature directive for use with constants and - enums. This works the same way as %javaconstvalue. For C#, this directive - is the only way that one can fix wrapping of C/C++ enums with proper C# - enums if the enum item's initialiser cannot compile as C# code. This is - because Java enums can use a call into C code to initialise the enum item, - whereas in C#, the enum value must be a compile time constant. That is, - using %csconst(0) cannot be used in C# to initialise the C# enum item via - a PINVOKE call. - -06/27/2004: wsfulton - [Java] New %javaconstvalue(value) feature directive for use with constants and - enums. Sometimes the use of %javaconst(1) will produce code that won't compile - under Java. If a compile time constant is required, %javaconst(0) is not an - option. The %javaconstvalue directive achieves this goal and the value specified - is generated as Java code to initialise the constant. For example: - - %javaconst(1); - %javaconstvalue(1000) BIG; - %javaconstvalue("new java.math.BigInteger(\"2000\")") LARGE; - %javaconstvalue(10) bar; - %{ - const int bar = 10; - %} - %inline %{ - #define BIG 1000LL - #define LARGE 2000ULL - enum Foo { BAR = ::bar }; - %} - - Generates: - - public interface exampleConstants { - public final static long BIG = 1000; - public final static java.math.BigInteger LARGE = new java.math.BigInteger("2000"); - } - public final class Foo { - public final static Foo BAR = new Foo("BAR", 10); - ... - } - - Previously, none of BIG, LARGE or BAR would have produced compilable code - when using %javaconst(1). - -06/27/2004: wsfulton - %feature enhancements. Features can now take an unlimited number of attributes - in addition to the feature name and feature value. The attributes are optional - and are much the same as the typemap attributes. For example, the following - specifies two optional attributes, attrib1 and attrib2: - - %feature(featurename, attrib1="attribval1", attrib2="attribval2") name "val"; - %feature(featurename, val, attrib1="attribval1", attrib2="attribval2") name; - -06/27/2004: wsfulton - %feature improvements for the syntax that takes the feature value within the - %feature() brackets. The value specified is no longer restricted to being just - a string. It can be a string or a number. For example, this is now acceptable - syntax: - %feature("featurename",20.0); - whereas previously it would have to have been: - %feature("featurename","20.0"); - Useful for features that are implemented as a macro, for example: - #define %somefeature(value) %feature("somefeature",value) - These will now work accepting either a string or a number: - %somefeature("Fred"); - %somefeature(4); - -06/06/2004: wuzzeb (John Lenz) - [Chicken, Guile] - - Created the Examples/test-suite/schemerunme directory, which holds all the - runme scripts for guile and chicken (and possibly mzscheme...). The guile - and chicken _runme files then (load "../schemerunme/foo.scm"). - - In chicken module, fix a few bugs invlolving dynamic casts. - -06/03/2004: wsfulton - Patch to fix wrapping of templated methods. ISO compliant compilers, like - Comeau and GCC-3.4.0, don't like the template specifier that SWIG was generating - when calling the method. This fix may break some non standard compliant compilers, - for example, Sun workshop compilers prior to version 6.2.p2. Patch submitted - by Bill Clarke. - -06/03/2004: wsfulton - [Java, C#] Undocumented special variable $imclassname removed. - New special variable $module is replaced by the module name, as specified - by %module or -module commandline option. $imclassname can be created from $module. - -06/03/2004: wsfulton - [C#] Same as for Java below. The new typemaps are named differently, namely, - csbody and csbody_derived. The deprecated typemaps are csgetcptr and - csptrconstructormodifiers. - - *** POTENTIAL INCOMPATIBILITY FOR C# MODULE *** - -06/03/2004: wsfulton - [Java] Typemap changes for the Java proxy / typewrapper and enum classes. A new - typemap called javabody contains the essential support code for generation into the body - of these classes. There is also a new javabody_derived typemap which is used instead for - wrapped classes that have a wrapped base class. The code is basically, the getCPtr() - method and swigCPtr and swigCMemOwn member variables. These used to be hard coded - with no way to modify the code. The introduction of this typemap makes it possible for - the user to tailor nearly every aspect of the code generation. - The exception now is the code for director classes. - - The javagetcptr and javaptrconstructormodifiers typemaps are deprecated and are - no longer used as the code that these generated can be put in the more flexible - javabody and javabody_derived typemaps. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - - The following macros contributed by Scott Michel may help you upgrade if you have used - the javagetcptr typemap: - - /* Utility macro for manipulating the Java body code method attributes */ - %define SWIGJAVA_ATTRIBS(TYPENAME, CTOR_ATTRIB, GETCPTR_ATTRIB) - %typemap(javabody) TYPENAME %{ - private long swigCPtr; - protected boolean swigCMemOwn; - - CTOR_ATTRIB $javaclassname(long cPtr, boolean cMemoryOwn) { - swigCMemOwn = cMemoryOwn; - swigCPtr = cPtr; - } - - GETCPTR_ATTRIB static long getCPtr($javaclassname obj) { - return (obj == null) ? 0 : obj.swigCPtr; - } - %} - - %typemap(javabody_derived) TYPENAME %{ - private long swigCPtr; - - CTOR_ATTRIB $javaclassname(long cPtr, boolean cMemoryOwn) { - super($moduleJNI.SWIG$javaclassnameUpcast(cPtr), cMemoryOwn); - swigCPtr = cPtr; - } - - GETCPTR_ATTRIB static long getCPtr($javaclassname obj) { - return (obj == null) ? 0 : obj.swigCPtr; - } - %} - %enddef - - /* The default is protected getCPtr, protected constructor */ - SWIGJAVA_ATTRIBS(SWIGTYPE, protected, protected) - - /* Public getCPtr method, protected constructor */ - %define PUBLIC_GETCPTR(TYPENAME) - SWIGJAVA_ATTRIBS(TYPENAME, protected, public) - %enddef - - /* Public getCPtr method, public constructor */ - %define PUBLIC_BODYMETHODS(TYPENAME) - SWIGJAVA_ATTRIBS(TYPENAME, public, public) - %enddef - -06/03/2004: wsfulton - [Java, C#] The contents of the class modifier typemaps and pragmas have changed. - They must now include the class type. Previously 'class' was hard coded. - This change enables flexibility into what type of class is generated, - for example the proxy class could be an interface instead of a class. - - For Java this affects the javaclassmodifiers typemap and the jniclassclassmodifiers - and moduleclassmodifiers pragmas. - - For C# this affects the csclassmodifiers typemap and the imclassclassmodifiers - and moduleclassmodifiers pragmas. - - Unless you have overridden the default versions of these typemaps or pragmas, you - shouldn't be affected. However, if you have, upgrading is easy, for example - - class Foo {}; - %typemap(javaclassmodifiers) Foo "public final" - - must now be: - - class Foo {}; - %typemap(javaclassmodifiers) Foo "public final class" - - - *** POTENTIAL INCOMPATIBILITY FOR C# MODULE *** - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -05/31/2004: wsfulton - Fix for C++ exception specifications that are references. Problem reported by - Oren Miller. Also improves the generated exception declarations in the - catch handler for pointers - a pointer is used instead of a reference to - a pointer. Added default throws typemaps for SWIGTYPE &, SWIGTYPE * and - SWIGTYPE[ANY] (Java and C#). - -05/31/2004: wsfulton - [Java, C#] Some minor typesafe enum improvements, including storing the name of - the enum item. The toSring() / ToString() methods are overridden to return this name. - -05/30/2004: wuzzeb (John Lenz) - [Chicken] - - Update how examples and the test suite are built. - - Symbol names are no longer converted to lower case - - Added union_runme.ss, which was copied and modified from the guile module - -05/26/2004: lballabio (Luigi Ballabio) - Committed on behalf of Marcelo (who still has problems with - the SourceForge CVS.) - - Added Python typemaps for FILE* with (Python-only) test. - -5/24/2004: dancy - - * Allegro CL module: Now using some macros (defined in - Lib/allegrocl/allegrocl.swg), swig-defconstant and swig-defun, for - defining constants and foreign functions. This makes the - generated file a bit neater. - - Now strips a layer of parenthesis from constants. - - Uses (* :void) instead of :foreign-address now. - -05/20/2004: wsfulton - Unnamed enum global variables are now supported in addition - to the recently added support for unnamed enum member variables. - For example: - - struct Foo { - enum { enum1, enum2 } MemberInstance; - }; - enum { enum3, enum4 } GlobalInstance; - - The int typemaps are used for wrapping the get/set accessor methods. - If the sizeof an enum is not the same size as an int then setting the - variable will silently do nothing as the casts cannot be easily and portably - generated. If you need to solve this highly obscure situation, write - the assignment using the %exception feature. - -05/20/2004: wsfulton - [C#] C# enum wrapping mods. Similar to the Java module, enums can be wrapped using - one of 3 approaches: - - 1) Proper C# enums - use %include "enums.swg" - 2) Typesafe enums - use %include "enumtypesafe.swg" - 3) Simple constant integers (original approach) - use %include "enumsimple.swg" - - See each of these files for further details. Each of these files use typemaps - and a new feature to control the generated code. The feature is: - - %csenum(wrapapproach); - - where wrapapproach should be one of: "proper", "typesafe", "typeunsafe" or "simple". - [No implementation deemed necessary for type unsafe enums]. - - The default approach is proper C# enums. Anonymous enums are always wrapped by - constant integers. - - *** POTENTIAL INCOMPATIBILITY FOR C# MODULE *** - -05/20/2004: wsfulton - [Java] Java enum support added. There are now 4 ways in which enums can be wrapped: - - 1) Proper Java enums - use %include "enums.swg" - 2) Typesafe enums - use %include "enumtypesafe.swg" - 3) Type unsafe enums (constant integers) - use %include "enumtypeunsafe.swg" - 4) Simple constant integers (original approach) - use %include "enumsimple.swg" - - See each of these files for further details. Each of these files use typemaps - and a new feature to control the generated code. The feature is: - - %javaenum(wrapapproach); - - where wrapapproach should be one of: "proper", "typesafe", "typeunsafe" or "simple". - The default typemaps will handle enums that may or may not have specified initial - values, for example ten is specified: - - enum Numbers { zero, ten(10) }; - - However, the amount of generated Java code can be cut down, by modifying these typemaps - if none of the enums have initial values (proper Java enums and typesafe enums approach). - - The default approach is typesafe enums. Anonymous enums are always wrapped by - constant integers. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -05/11/2004: wsfulton - [Java, C#] Fix bug using %rename on enum items and when using - %javaconst(1) / %csconst(1) - For example, the following used to generate code that wouldn't compile: - - %rename(Obj) Object; - enum Grammar { Subject, Object }; - -04/28/2004: wsfulton - [Java, C#] Minor fixes when using combinations of the - javainterfaces, javabase, csinterfaces and csbase typemaps. - -05/18/2004: wsfulton - [Java] JVM link failure on some systems fixed when using std_vector.i. - Also adds default vector constructor for use from Java. - -05/17/2004: mkoeppe (Matthias Koeppe) - - [Guile] New runtime functions SWIG_PointerAddress, - SWIG_PointerType, SWIG_IsPointerOfType, SWIG_IsPointer. - - [Guile] In -scm mode, wrap several SWIG runtime functions - and export them into the module (Swig swigrun). The - runtime module is now built with "module" linkage. - - [Guile] GOOPS proxy objects now also print the pointer - address of the C object. - -05/14/2004: lyle - Added Kou's patch for the Ruby %import directive so that modules - with "nested" names are handled properly. Consider an interface - file foo.i that has this %module declaration at its top: - - %module "misc::text::foo" - - Now consider another interface file spam.i that imports foo.i: - - %import foo.i - - Before this patch, this would result in the following code being - generated for spam_wrap.c: - - rb_require("misc::text::foo"); - - With this patch, however, you'll get the correct path name - for the call to rb_require(), e.g. - - rb_require("misc/text/foo"); - - See SourceForge Bug #928299. - -05/12/2004: wsfulton - Patch for emitting directors when %feature("director") specified - for a class with no virtual methods, but does have a virtual destructor. - Submitted by Kevin Smith. - -05/06/2004: mkoeppe (Matthias Koeppe) - New SWIG runtime function SWIG_TypePrettyName, which - returns an unmangled type name for a swig_type_info - object. - - [Guile]: Use it for printing pointer objects. - -05/03/2004: dancy (Ahmon Dancy) - - * Lib/allegrocl/allegrocl.swg: Updated comments about identifer - conversion. - - * Sources/Modules/allegrocl.cxx: Register /dev/null for "header" - target. Also, disregard "const" qualifiers during type - conversion. - - -05/02/2004: wuzzeb (John Lenz) - [Chicken] Fix bug 782468. - To fix this bug, the runtime code has been rewritten, and - pointers are now represented as a C_SWIG_POINTER_TYPE. - - Chicken version > 1.40 is now required! - - * Typemap incompatibility: typemaps no longer use chicken_words. - If a typemap needs some space, it should just call C_alloc - - * argout typemaps no longer use the /* if ONE */ construct to - build an output list. A SWIG_APPEND_VALUE macro, exactly like - guile and mzscheme is now used. - -04/25/2004: mkoeppe (Matthias Koeppe) - [Guile] In the generated GOOPS code, don't create methods - that would not specialize any arguments; simply re-export - the primitive functions. (This is a performance - optimization which reduces load time and execution time.) - - [Guile] In -gh mode, fix the "too many initializers" error - which was caused by an incompatible swig_type_info layout. - - [Guile] The typemap for FILE * in ports.i now also accepts - a regular FILE * pointer object. Also a bug with Scheme - file ports that are open for input and output has been - fixed. - -04/25/2004: wsfulton - Change entry 03/21/2004 revoked. The change introduced another - inconsistency (reference typemaps beings used instead of - pointer typemaps for member variables as well as static - member variables and global variables for some languages, - but only for C++ and not C). This would break user's current - typemaps and introduce further inconsistencies. Alternative - solution required and being discussed. - -04/10/2004: mmatus (Marcelo Matus) - - Added the -directors flag. This enables the director - mode for the interface and all the classes that - don't set the "feature:nodirector" explicitly. - - You can use this in your module if you want to use the - director feature in all your classes, but it is most - intended for testing purposes, like: - - make check-python-test-suite SWIG="../../../swig -directors" - make check-ruby-test-suite SWIG="../../../swig -directors" - make check-java-test-suite SWIG="../../../../swig -directors" - - These commands will run the entire test-suite using - directors, and not only the specific 'directors_*' - cases. This should be done from time to time. - -04/10/2004: mmatus (Marcelo Matus) - - [python] Added support for std::wstring and wchar_t, - for compiler and python versions that support them. - - When needed, use - - %inlcude std_string.i // 'char' strings - %inlcude std_wstring.i // 'wchar_t' strings - - -04/10/2004: mmatus (Marcelo Matus) - - [python] Fix the default behaviour (seg. fault) when an - inplace operator (+=,-=,...) was wrapped, as reported by - Lucriz (lucriz@sitilandia.it), when the most common - form was used: - - A& A::operator+=(int i) { ...; return *this; } - ^^^^ ^^^^^^ - - - ie, an object is returned and its contains the same 'this' - value than the input object, which is deleted after the - operation "a += b", leaving the result with no real - object, but a seg. fault. - - To fix it, we needed to introduce a new feature and use an - old one: - - %feature("self:disown") A::operator+=; - %feature("new") A::operator+=; - - here, "self:disown" disable the ownership of the 'self' - or input object, and the "new" feature transfers the - ownership to the result object. - - The feature/solution could also be used in other languages - that use gc and implement the inplace operators, or other - operators, in a similar way. - - *** POTENTIAL INCOMPATIBILITY FOR Python MODULE *** - - If you already are using the inplace operators in python, - and you implemented some kind of workaround to the problem - fixed here, it is possible you could end with 'free' - objects that never get deleted. If that is the case, and - you want to disable the current fix, use: - - %feature("self:disown","") A::operator+=; - %feature("new","") A::operator+=; - - -04/07/2004: cheetah (William Fulton) - [C#] C++ enums are no longer wrapped by integers, they are now wrapped by - C# enums. For Example, given C++: - - enum AnEnum { foo, bar }; - typedef AnEnum AnEnumeration; - void something(AnEnum e, AnEnumeration f); - - The following is generated: - - public enum AnEnum { - foo, - bar - } - public static void something(AnEnum e, AnEnum f) {...} - - Note that a global enum like AnEnum above is generated into its own - file called AnEnum.cs. Enums defined within a C++ class are defined - within the C# proxy class. Some of the typemaps for modifying C# proxy - classes also work for enums. For example global enums can use - - %typemap(csimports) to add in extra using statements. - - Global enums and class enums can use - - %typemap(csclassmodifiers) to make the enum private, public etc. - %typemap(csbase) to change the underlying enum type (enum base) - - If we add this for the above example: - - %typemap(csclassmodifiers) AnEnum "protected" - %typemap(csbase) AnEnum "long" - - the following is generated: - - protected enum AnEnum : long { - foo, - bar - } - - *** POTENTIAL INCOMPATIBILITY FOR C# MODULE *** - -04/07/2004: cheetah (William Fulton) - Seg fault fix for empty enums, like - enum Foo {}; - -03/21/2004: mmatus - [Note: this change revoked on 04/25/2004] - [Python] Makes the following 'var' cases more uniform: - - std::string ga; - - struct A { - static std::string sa; - std::string ma; - }; - - - now the three variables (ga, sa, ma) can be assigned as: - - - cvar.ga = "hello"; - A.sa = "hello"; - a.ma = "hello"; - - ie, now 'ma' will also use a std::string typemap 'in' if - defined, before it was only accepting a 'p_std_string' - pointer. Note, however, that 'ma' will not use the - 'varin/varout' typemaps (that probably could be more - natural), but it will pick up the 'in' typemap for const - std::string& (which is easier). - - The changes in cwrap.c and lang.cxx will probably fix the - behaviour in other languages that do not overload the - membervarHandler method "too much". - - -03/21/2004: mmatus - [Python] Disabling the default instantiations like: - - %template() std::pair<int,int>; - - for all the primitive types and STL containers/classes. - They are expensive, specially for pair and map, and the - previous behaviour also requires the user to perform - manual instantiations. Still, if the speed difference is - not important, it can be re-enabled by defining the macro - SWIG_STD_DEFAULT_INSTANTIATION (see std_common.i). - - Also, normalizing the INPUT/OUTPUT/INOUT typemaps. Now - they use the same conversors than the rest of the - typemaps, and you can use them for std::pair, std::string - and all the other STL types, like in: - - void p_inoutd(std::pair<double, double> *INOUT); - - Added the attribute.i and implicit.i files with macros to - transform functions pairs like 'set_x'/'get_x' - (or 'T& x()'/'const T& x() const') into an attribute, - and allowing the use of implicit constructors in typemaps - (see the files for more details). - -03/21/2004: mkoeppe - [Guile] Fix the documentation strings of functions with - anonymous arguments. - -03/18/2004: mmatus - [Python] More general std_string.i interface. - Now you can wrap it using - - %template(string) std::basic_string<char>; - - and use the std::string as a base class: - - struct A : std::string { - }; - - But more important, swig will recognize - both std::basic_string<char> and std::string as - the same type. - -03/16/2004: mmatus - Previously added, but not mentioned before: - - - friend declaration support, swig now emits a global - function in the same class scope. - - - ref/unref features: to mix ref counting C++ classes - and native script ref counting mechanisms (like in python). - - Use it like: - - %feature("ref") RCObj "$this->ref();" - %feature("unref") RCObj "$this->unref();" - - And the class RCObj, and all the derived ones, will - perform the right ref/unref calls when a new pointer - is returned to the target language, or when the target - language attempts to delete the object. - - See the refcount.i file in the test-suite for more - details. - - -03/16/2004: mmatus - [Python] Using the new %fragment support, major rewrote - of the python swig library, including: - - - Almost automatic template/typemap instantiation for - the STL components. For example, now you can write: - - %template(vector_i) std::vector<int>; - - and a specialized vector_i class is emitted with all - the needed typemaps. No need to use the old - 'specialize_vector' macros. - - Note you can also define - - %template(matrix_i) std::vector<std::vector<int> >; - %template(vector_pii) std::vector<std::pair<int,int> >; - - - The empty template instantiation - - %template() std::vector<int>; - - defines the vector typemaps, but no proxy class. For all the - fundamental types, the empty template instantiation are - defined, so, you can say - - %include std_vector - - int func(const std::vector<int>& a); - - where the proper typemap is applied to 'a', but no - std::vector<int> proxy is generated. - - - - All the STL containers present a more uniform behavior and - more complete interface declaration. The following are - now supported: - - std::vector<T> - std::list<T> - std::deque<T> - std::set<T> - std::multiset<T> - std::map<T> - std::multimap<T> - - not a container, but also supported: - - std::pair<T,U> - - also, more typemaps are defined for all of them, - including varin, varout, typecheck, etc. - - - Initial attempt to implement the STL containers - considering allocators, ie: - - std::vector<T,A> - - it is partially working, but it is just a workaround - while swig improves its template type support. - - - Please test with your particular setup. It seems to be - working with g++ 3.2.2, g++ 2.96, Intel icc and SGI CC - compilers, plus python 1.5.2, 2.0 and 2.3, but since - we are using templates, there is a chance you can find - some problems when using with an old C++ compiler. - -03/16/2004: mmatus - - - Allowing the empty %template directive, such as - - %template() std::vector<int>; - - to process the class "typedef"s and "typemap"s. Before - only the internal "typedef"s were processed. - - This makes possible to emit the default in/out - typemaps without the need of wrapping an specialized - vector instance. - - - Adding the preprocessor extension #@ which mangles the - following macro argument, like in: - - #define macro(X) #@X - macro(int) -> int - macro(std::string) -> std_s_s_string - - - Fragments can now be "type specialized", as the typemaps. The - syntax is as follows - - %fragment("name","header") - { /* a type independent fragment (old syntax) */ } - %fragment("name" {Type}, "header") - { /* the fragment is type dependent */} - - Now fragments can also be used inside templates: - - template <class T> - struct A { - %fragment("incode"{A<T>},"header") { - /* 'incode' specialized fragment */ - } - - %typemap(in,fragment="incode"{A<T>}) { - /* - here we use the 'type specialized' - fragment "incode"{A<T>} - */ - } - }; - - -03/11/2004: cheetah (William Fulton) - [Java] Director bug which meant that some virtual functions overridden in - Java were not being called on some operating systems. Bug reported and fixed - by Robert de Vries and Scott Michel. - -03/02/2004: mkoeppe (Matthias Koeppe) - [Guile] In -scm mode, don't forget to check the type of string arguments. - -02/24/2004: cheetah (William Fulton) - [C#] New commandline option -namespace <name>. This allows one to specify - a C# namespace into which all C# classes are generated. - -02/23/2004: mkoeppe (Matthias Koeppe) - [MzScheme] Use FUNC_NAME rather than a bogus typemap variable for signalling - errors. Call scheme_wrong_type with a zero-based argument number. - Reported by Ondrej Pacovsky, SF #902621. - - [Guile] Define FUNC_NAME also in the dispatch wrapper for overloaded - functions. Patch by John Lenz, SF #896255. - -02/22/2004: mkoeppe (Matthias Koeppe) - [Guile] In -scm mode, don't try to invoke a null destructor function. - -02/20/2004: cheetah (William Fulton) - Fixes so that the SWIG source will compile using the Digital Mars Compiler - (formerly Symantic compiler) on Windows. Submitted by Scott Michel. - -02/13/2004: mkoeppe (Matthias Koeppe) - [MzScheme] New command-line argument -noinit. Use it for building - the runtime library, where we don't want to define the functions - scheme_initialize etc. Reported by Tim Brown, SF #891754. - - [MzScheme] Don't produce invalid C code when invoked with the - -declaremodule option. Reported by Tim Brown, SF #891108. - - [Guile] Build the runtime library with passive linkage, to rename - the SWIG_init function uniquely. - -02/12/2004: cheetah (William Fulton) - [Java, C#] Patch submitted by Bill Hoffman which prevents SWIG from crashing - when a file for the typewrapper class cannot be opened. - -02/11/2004: cheetah (William Fulton) - [Java, C#] Overloading changes: - - Methods which are overloaded in const only no longer generate Java - code that won't compile - the first method parsed is used and a - warning is displayed. Note that this behaviour is slightly different - to the scripting languages which always uses the non-const method. - - Warning messages 509 and 512 replaced by new warning number 516, which - is more relevant to these statically typed languages as the overloaded - methods aren't 'shadowed', they are ignored. - -01/23/2004: mkoeppe (Matthias Koeppe) - [Guile] Replace the "known_classes" hash table by a node - attribute. Methods of classes in C++ namespaces now get - the proper specializer in the GOOPS declaration. - Reported by rm@mh-freiburg.de. - -01/23/2004: mkoeppe (Matthias Koeppe) - [Guile] Uniquify the argument names in GOOPS shadow method - declarations. Reported by rm@mh-freiburg.de. - -01/21/2004: sunshine (Eric Sunshine) - Revived the NextStep port of SWIG. - - Fixed fatal problem in DohStrstr() caused by difference in strstr() - implementation which made %apply become entirely dysfunctional. On - NextStep, strstr("foo","") evaluates to NULL; whereas, on modern - platforms, it evaluates to "foo". %apply relies extensively upon - strstr("foo","") evaluating to non-NULL, therefore it failed - catastrophically when faced with NextStep's strstr(). - - Added `bool' check to configure.in since NextStep's C++ compiler - does not supply this type. swig.h now fakes up `bool' if needed. - - Worked around NextStep C++ compiler bug in which C++ code is - disallowed inside extern "C" functions. This problem affected all - language modules, since they publish hook functions of the form: - extern "C" Language *swig_foo(void) { return new FOO(); } - Fixed by creating a C++ wrapper: - static Language *new_swig_foo() { return new FOO(); } - extern "C" Language *swig_foo(void) { return new_swig_foo(); } - - Ensured that Swig_copy_string() is used in place of strdup() since - NextStep does not supply strdup(). - - Fixed detection of Ruby library name and location in configure.in. - Problem 1: Assumed that library always resided in Ruby's "archdir", - which was correct for Ruby 1.6.x, but which is incorrect for Ruby - 1.8.x, in which case the library normally resides in Ruby's - "libdir". Problem 2: Assumed that the library could always be - linked via "-l"+RUBY_INSTALL_NAME (where RUBY_INSTALL_NAME - typically is "ruby"), however this failed for platforms, such as - NextStep, which do not support shared libraries. In this case, the - static library name in 1.8.x is libruby-static.a, thus - -lruby-static is required. The new logic works correctly for - static and shared libraries for 1.6.x and 1.8.x. - - Fixed detection of Perl CFLAGS in configure.in for NextStep. - Detection code extracted CFLAGS from Perl's %Config hash but - neglected to add a newline to the value before passing it through - `sed'. NextStep's ancient `sed' discards input which is not - terminated with a newline, thus Perl CFLAGS always evaluated to the - empty string. - -01/16/2004: cheetah (William Fulton) - Tidy up in the exception handling code that is generated when - C++ exception specifications are wrapped with the throws typemap. - This redundant code is no longer generated: - - catch(...) { - throw; - } - -01/12/2004: wsfulton on behalf of mmatus (marcelo matus) - if a method uses %exception and the method requires the use - of the throws typemap, the code in a throws typemap will be - generated inside the try body. For example: - - %exception method { - try { - // method action - $action - } catch (int i) { - // method int catch handler - } catch (...) { - // method generic catch handler - } - } - %typemap(throws) Except %{ - // throws typemap Except catch handler - %} - - %inline %{ - class Except {}; - void method(int i) throw (Except); - - Will generate: - - { - try { - // method action - try { - method(arg1); - } - catch(Except &_e) { - // throws typemap Except catch handler - - } - - } catch (int i) { - // method int catch handler - } catch (...) { - // method generic catch handler - } - } - - - As can be seen, the inner try catch block is for the throws typemaps. - Previously, this was reversed so that the inner try catch block - was the %exception code. In the example above, it would have been - impossible to catch Except as the catch all (...) would catch the - exception instead. - -Version 1.3.21 (January 11, 2004) -================================= - -01/10/2004: cheetah (William Fulton) - The output format for both warnings and errors can be selected for - integration with your favourite IDE/editor. Editors and IDEs can usually - parse error messages and if in the appropriate format will easily take you - directly to the source of the error. The standard format is used by - default except on Windows where the Microsoft format is used by default. - These can be overridden using command line options, for example: - - $ swig -python -Fstandard example.i - example.i:4: Syntax error in input. - $ swig -python -Fmicrosoft example.i - example.i(4): Syntax error in input. - -01/09/2004: beazley - Fixed [ 871909 ] simple namespace problem. - This was a problem using anonymous structures in a namespace. - For example: - - namespace ns { - typedef struct { - int n; - } S; - }; - - Reported by Josh Cherry. - -01/09/2004: beazley - Fixed some broken Perl examples. - -12/28/2003: cheetah (William Fulton) - [Java and C#] Fixes for wrapping covariant (polymorphic) return types. - For example: - - struct Base { - virtual ~Base(); - virtual Base* copy() const = 0; - }; - struct Derived : Base { - virtual Derived* copy() const; - }; - - The Derived::copy proxy method returns Base not Derived. A warning is issued - about this. Previously the pointer used by the proxy class was incorrectly - treated as a Base* instead of a Derived*. - -12/18/2003: cheetah (William Fulton) - Fix so that Windows paths are displayed correctly when reporting errors. - An error previously would have been shown something like: - - .?xample.i:14: Syntax error in input. - - instead of: - - .\example.i:14: Syntax error in input. - - -Version 1.3.20 (December 17, 2003) -================================== - -12/17/2003: beazley - Last minute modifications. Perl5 module now generates shadow classes - by default like all of the other modules. PHP4 wrappers no longer - include "config.h". - -12/14/2003: beazley - Weakened warning message related to constructor names so that an - unusual nested-class wrapping technique would work again (apparently - it worked in some older SWIG releases). For example: - - class Scope { - class ClassA; - class ClassB; - }; - class Scope::ClassA { - ... - }; - class Scope::ClassB { - ... - } - - Note: There is still some odd interaction with the SWIG symbol - table/type system that will need to be looked at in a future release. - Reported by Gustavo Niemeyer. - - -12/11/2003: cheetah (William Fulton) - [Java] Protected class methods are wrapped as protected Java methods - when using the dirprot director feature. This can be changed using - %javamethodmodifiers to something else should the need arise, for - example, private or package access. - -12/11/2003: cheetah (William Fulton) - [Java, C#] - %javamethodmodifiers (Java) and %csmethodmodifiers (C#) operate slightly - differently. Previously this feature had to be present to set the method - modifiers. Now it is only used if it exists for the method being wrapped. - The default is "public" as previous however, when wrapping protected - director methods it is "protected". This change will not affect existing - use of the %javamethodmodifiers or %csmethodmodifiers. - -12/11/2003: mmatus (Marcelo Matus) - - This fix some recurring reports about keywords not been - properly identified and warned, and it solves the problem - of how to add a test file to the test-suite such that it - doesn't use any keyword of all the supported languages - (and doing it without compiling the test for all the - supported languages, thing that is not always possible, - and without requiring you to know all the supported - language keywords, thing that is always impossible). - - So these are the changes globally speaking: - - - Uniform the definition of the keyword warnings through - the supported languages: all the languages has now a - separate file that defines the keywords or bad names: - - python/pythonkw.swg - chicken/chickenkw.swg - .... - - - Added keyword list for most of the languages that didn't - have one (using the new separated file). - - - Added the "All keywords" warning support: -Wallkw option. - - This option allows you to include all the known keywords - for all the supported languages, and can be used as: - - swig -Wallkw .... - - This will help to the process of adding a test-suite - file that can be compiled in all the swig supported - languages, and it will be also helpful for users who - want to create multi-language libraries. - - And these are the detailed changes (mostly file addition): - - - For the languages that already have some sort of keyword - warning list, move it to an external languagekw.swg - file, ie: - - move keywords from python.swg -> pythonkw.swg - move keywords from chicken.swg -> chickenkw.swg - move keywords from tcl8.swg -> tclkw.swg - - and re-include languagekw.swg from language.swg. - - - For the language that didn't have a keyword list, and - for the ones that I could find a list, add the - languagekw.swg file, ie: - - csharp/csharpkw.swg - java/javakw.swg - php4/phpkw.swg - pike/pikekw.swg - ruby/rubykw.swg - - - also add a line in language.swg to include - languagekw.swg, but now it is commented!!!, like in - java.swg: - - /* java keywords */ - /* please test and activate */ - //%include "javakw.swg" - - ie, there will be no change in how swig runs normally - until the language maintainer test and uncomment that - line. - - So, please check each languagekw.swg file (I left the - link to the keyword list source for checking), and after - testing, uncomment the %include line. - - - Added the file allkw.swg, which includes all the - languagekw.swg files. - - For the languages that has no languagekw.swg file right - now, and if they need one, add the file into the - language directory, and add the corresponding include - line into the allkw.swg file. - - - Added the -Wallkw that includes the allkw.swg file. - Note that the old -lallkw.swg option couldn't be used - since it include the file after it would be needed. - - - Hopefully, the -Wallkw option will be added to the default - rules in the related test-suite Makefiles, so, when - creating a new test, or adding a new swig library file - (like _std_deque.i), swig will warn you if you are using a - bad name, considering all the language where it needs to - run. - - Right now you can test it by using: - - make check-python-test-suite SWIG="swig -Wallkw" - - or using your favorite target language, it doesn't matter. - - And yes, there are several examples that are using - reserved keywords, specially from csharp. - - *** Remember ****: the new keyword warning lists are not - included by default in any of language that before didn't - have one. To enable the keyword warnings as the default - behavior, the inclusion of the languagekw.swg file has to - be uncommented at each language.swg file. - - So, all the language maintainers, please check the - keywords list. - - Also, you can add buit-in names, and not only keywords, like - 'True/False' in python. Remember that you can be more - specific and refer only to member names, like *::configure - or *::cget (see an example in the tcl8/tcl8kw.swg file), - or only global names, like ::range (see an example in the - python/pythonkw.swg file. - - Just to be consistent, use the following codes: - - - Use code 314 for keyword and/or fatal bad names. - - Use code 321 for buit-in and/or not fatal bad names. - - so, they can't be disabled/enabled independently (see - python/pyhtonkw.swg for examples). - - **** And don't add any new test file without checking it - with the -Wallkw option!! (that includes me) *****. - - -12/11/2003: cheetah (William Fulton) - SF bug #854634 - Added support for accepting the Unix directory separator '/' on - Windows and the Mac in addition to the native one ( '\' on - Windows). This can be used in %import, %include and commandline - options taking a path, for example -I. On Cygwin, both the Windows - and Unix directory separator can now be used (was '/' only). - -12/10/2003: mmatus (Marcelo Matus) - - [python] Implementing the runtime "reprotected" director - members, if you have: - - %feature("director") B; - - class Bar { - public: - virtual ~Bar(); - virtual int hello() { return do_hello();) - - protected: - virtual int do_hi() {return 0;} - virtual int do_hello() {return 0;} - }; - - then, at the python side - - import my_module - - class Foo(my_module.Bar): - def do_hello(self): - return 1 - pass - - b = Bar() # Pure C++ Director class - f = Foo() # C++ Director + python methods - - b.hello() # Ok, and it calls C++ Bar::do_hello() - f.hello() # Ok, and it calls Python Foo::do_hello() - - b.do_hi() # RuntimeError, do_hi() is protected!! - f.do_hi() # RuntimeError, do_hi() is protected!! - - b.do_hello() # RuntimeError, do_hello() is protected!! - f.do_hello() # Ok, since it its redefined in python. - - Here Bar.do_hello is always protected, but Foo.do_hello - is "public", because it is redefined in python. Before, - all the 'do_hello' methods were public. - - This seems to be a good compromise between C++ and python - philosophies, ie, all the director protected methods keep - protected at the user side (C++ way) until they are - redefined (python way, were all defined methods are always - public). And this is not only a good compromise, it also - seems to be the only way to do it :). - - Now ruby has native director protected members, and python - pure runtime support. I guess these are the two possible - extreme cases. And hopefully, they could be used as - templates to modify the other languages that support - directors, so they can "reprotect" the protected director - members at the target language side. - - This finished the director protected support for the - python language. Ocalm will need to add the - "reprotection" later. - -12/10/2003: mmatus (Marcelo Matus) - - The following case (reported by Lyle Johnson) was fixed: - - %rename(x) Foo::y(); - - class Foo { - public: - void y(); - - protected: - int x; - }; - - swig warned that the symbol 'x' was already defined, and - the renaming fails. 'x' was not emitted, since it is - protected, but it was kept in the symbol table with too - much information. - - Now swig works for all the cases (plain, director and - dirprot) again. This was fixed by allowing the parser.y to - decide much closer what to do with 'x'. Before all the - discarding or generation was resolved at the lang.cxx - stage. Also the changes in parser.y to implement the - director protected mode are now much more encapsulated, and - they get disabled if the mode is not enabled. Before the - deactivation was done at the generation stage (lang.cxx). - - By the other hand, if the director mode is enabled, and - %rename is done, reusing a protected member name, there is - a pathological case: - - %rename(x) Foo::y(); - - class Foo : public A { - public: - void y(); - - protected: - int x; /* works */ - static int x; /* works */ - static void x(); /* works */ - typedef void x(); /* works */ - - virtual void x(); /* always fails, as it should, since - Foo::x() will be emitted in the - director */ - - void x(); /* always fails, but sometimes it shouldn't, - since the Foo::x() will not be emitted if - it is not virtual */ - - }; - - The last case is not always right because at the parser.py - stage it is not possible to decide if the protected member - Foo::x() could or not conflict with the renamed Foo::y(), - since Foo::x() could be virtual by inheritance. - - I guess this just an intrinsic limitation, and no much can - be done about it without resorting into larger changes to - postpone, under certain conditions, the multiply symbol - detection (lang.cxx stage). - - So, by now, it is just considered a well known "feature" in - the director protected mode. The good news is that it seems - to be a rare case, and it can be avoided by the user by - hiding 'x' before renaming 'y': - - %rename(_x) Foo::x(); - %rename(x) Foo::y(); - - -12/08/2003: mmatus (Marcelo Matus) - The virtual method detections now properly - treats the following cases: - - namespace foo { typedef int Int; } - struct A {}; - typedef A B; - - struct Foo { - virtual ~Foo() {} - - virtual Foo* cloner() = 0; - virtual int get_value() = 0; - virtual A* get_class() = 0; - virtual void just_do_it() = 0; - }; - - struct Bar : Foo - { - Bar* cloner(); - foo::Int get_value(); - B* get_class(); - void just_do_it(); - }; - - All the Foo and Bar methods are virtual. A new attribute - "virtual:type" record the base polymorphic type. In the - previous cases we have: - - type : Bar virtual:type : Foo - type : foo::Int virtual:type : int - type : B virtual:type : A - type : void virtual:type : void - - This attribute is useful in languages (java+directors) - that could have problems redefining Bar* Bar::cloner(). - - If you never had code like the above, you will see no - effects. But if you have some code like that, you - will see some effects since some methods that - before were not properly treated as virtual, - will start to act like that. This could enlarge - your director classes. - - -12/08/2003: mmatus (Marcelo Matus) - The director protected member support (dirprot) - is disabled by default. - - It can be enable by using '-dirprot' or by adding - the option to the module declaration, like: - - %module(directors="1",dirprot="1") my_module - - This module option was added to properly compile the - director_protected.i and director_nested.i examples. - - The feature has been tested with python[2.2,2.3] - and ruby[1.6.7], both at compilation and runtime, and - java[j2sdk1.4.1_01], but only at compilation (my java - installation doesn't run any of the director examples, - olds nor news). - - Please test for ocaml and java. - - The errors reported by William and Scott were fixed, - except for a warning about SWIG_JavaThrowExecption() - multiply defined. I can't reproduce this error with my - examples. We will wait for Scott to send us a minimal - case. - - -12/07/2003: mmatus (Marcelo Matus) - The director protected member support has been - completly moved out from python.cxx, and now - resides in the common lang.cxx, emit.cxx and - allocate.cxx files. - - This means it should work for all the other languages - that currently support directors, ie, python, java, ocalm - and ruby. - - The change has been tested with python (compilation+runtime) - and java (just compilation). - - Please add runtime tests for the missing languages - and test it. - - The '-nodirprot' option was moved to the principal main, - and can be used from all the languages. - -12/07/2003: cheetah (William Fulton) - [Java] Fixed and improved error checking of STRING_OUT typemaps in - various.i. - -12/04/2003: mmatus (Marcelo Matus) - - - Now the virtual members with no explicit declarator - are properly identified: - - struct A { - virtual int f() = 0; - }; - - struct B : A { - int f(); - }; - - Here, B::f() is virtual, and the director and the - virtual elimination mechanism now recognize that. - - - [C#] This fix also fixes the problem where 'override' was not being - used on any overridden virtual method, so for struct B above, - this C# code is generated: - - public class B : A { - ... - public override int f() { - ... - } - ... - } - - - Initial support for protected virtual methods. They are now - properly emitted when using with director (python only by - now). - - %feature("director") A; - struct A { - protected: - virtual int f1() = 0; - }; - - %feature("director") B; - struct B : A{ - protected: - int f1(); - virtual f2(); - }; - - This can be dissabled by using the '-nodirprot' option. - - - The feature 'nodirector' is working now at the top level, - so, it must work for all the languages: - - %feature("director") A; - %feature("nodirector") A::f2; - - struct A { - virtual int f1(); - virtual int f2(); - }; - - in this case, only 'f1' is exported to the director class. - - - Added director support for const TYPE& arguments (python). - -12/02/2003: cheetah (William Fulton) - [Java] Fix for INOUT and OUTPUT typemaps in typemaps.i for when the JNI type - is bigger than the C type. For example, unsigned long (32bits on most systems) - is mapped to jlong (64bits). Returned value was incorrect. Bug reported by - Brian Hawley. - -12/02/2003: cheetah (William Fulton) - [C# and Java] Better fix for entry dated 05/11/2003. Fixes the following - typemaps: - - Java: javabase, javainterfaces, javaimports, javaclassmodifiers, - javaptrconstructormodifiers, javafinalize, javagetcptr & javacode. - C#: csbase, csinterfaces, csimports, csclassmodifiers, - csptrconstructormodifiers, csfinalize, csgetcptr & cscode. - - It also fixes bug in using arrays of C structs with arrays_java.i - as reported Scott Michel. - -12/02/2003: beazley - [Perl] Fixed [ 852119 ] recursive inheritance in output .pm, perl5. - Reported by William Dowling. - -12/02/2003: beazley - [Tcl] Fixed [ 755382 ] calling func(const vector<T>& p) evaluates p[0] in interp. - The Tcl type checker was improperly handling the interpreter result when - type violations were supposed to be ignored. - Reported by Flaviu Popp-Nowak. - -11/30/2003: cheetah (William Fulton) - Fixed [ 545058 ] configure's --with-tclincl has no effect - -11/30/2003: cheetah (William Fulton) - [Java] Fixed [ 766409 ] missing symbol SWIG_JavaThrowException during module load - SWIG's internal functions are all static as there is no need for different SWIG - generated modules to share any code at runtime. - -11/30/2003: beazley - [Tcl] Added support for C++ pointers to members. - -11/28/2003: cheetah (William Fulton) - Fixed [ 848335 ] Directors: #include wrapper .h file - was incorrectly - adding a directory to the generated #include "foo_wrap.h" statement - in some situations. - -11/28/2003: cheetah (William Fulton) - [Java] Fixed [ 849064 ] JAVA : Access modifier for derived class wrong. - The delete() method is always public now. It used to be protected whenever a - destructor was non public. An UnsupportedOperationException runtime - exception is thrown instead of making delete() protected now. - -11/28/2003: beazley - [Perl5] Added support for C++ pointers to members. - -11/28/2003: beazley - Fixed [ 850151 ] PYVERSION with python2.3 in configure of SWIG 1.3.19 (Maybe). - -11/28/2003: beazley - Fixed [ 850666 ] #include extra line added. - This should fix some problems with getting correct line numbers on - error messages. - -11/26/2003: beazley - Fixed another one of Marcelo's evil template bugs (infinite - recursion). [ 849504 ] template and typedef -> inf. recursion. - -11/26/2003: beazley - Fixed parsing problem with declarations like this: - - int *x = &somearray[0]; - -11/25/2003: beazley - Fixed [ 756552 ] missing default argument class scope with "|". - This is really only a band-aid fix for use of class-enums in - expressions. For example: - - class A { - public: - enum Flag { flag1 = 0x1, flag2 = 0x2 }; - void foo(int x = flag1 | flag2); - }; - - Note: there are still some (more subtle) cases that are broken, - but hard to fix due to an issue with template expansion. Will - address later. - Reported by Dmitry Mironov. - -11/25/2003: beazley - Incorporated [ 840878 ] support for %inline { ... } (PATCH). - This adds support for the following: - - %inline { - ... some code ... - } - - The difference between this and %inline %{ ... %} is that the - enclosed text is processed by the SWIG preprocessor. This - allows special macros and other processing to be used in - conjunction with %inline. - Contributed by Salvador Fandino Garcia. - -11/25/2003: beazley - Fixed [ 836903 ] C++ inconsistency (with void arguments). - SWIG was having difficulty with f() vs f(void) in C++ programs. - For instance: - - class A { - public: - virtual void f(void) = 0; - }; - - class B { - public: - virtual void f(); // Not matched to f(void) correctly - }; - - The parser now normalizes all declarations of the form f(void) - in C++ classes to f(). This should fix a variety of subtle - problems with inheritance, optimizations, overloading, etc. - Problem reported by Partho Bhowmick. - -11/25/2003: beazley - [Perl5] Incorporated [ 841074 ] better croaking (PATCH). This fixes some problems - with strings and provides some new error functions. - Contributed by Salvador Fandino Garcia. - -11/25/2003: beazley - Fixed [ 791835 ] Default argument with cast: txt = (char *)"txt" syntax Error. - The parser should now accept things like this: - - void foo(char *s = (char *) "Hello"); - - Problem reported by Claudius Schnorr. - -11/24/2003: beazley - [Tcl] Fixed problem with cross module linking. Previously modules referred - to base classes through a global variable. Now, the module looks up base - classes through the type system itself---avoiding the need to link to a global - like before. Caveat: modules with base classes must be loaded before - modules with derived classes. - -11/24/2003: mkoeppe (Matthias Koeppe) - [Guile] In -scm mode, use () to represent null pointers, - as it is done in -gh mode. - -11/23/2003: mkoeppe (Matthias Koeppe) - Add a generated script "preinst-swig", which can be used - to invoke SWIG before it has been installed. It arranges - that the runtime libraries from the source directory are - used. - -11/23/2003: mkoeppe (Matthias Koeppe) - [Guile] In -gh mode, don't forget to call SWIG_Guile_Init. - Add a SWIG_contract_assert macro. - -11/23/2003: mkoeppe (Matthias Koeppe) - [MzScheme] Update the configure check for the dynext object to work - with MzScheme 205. - -11/20/2003: mmatus - Fixed the include/import error reported by Kerim Borchaev, - where two files with names like - - 'dir1/hello.i' - 'dir2/hello.i' - - can not be include at the same time. Swig was including - just the first one, assuming the second one was not a - different one, since it was checking/keeping just the - basename 'hello.i'. - -11/19/2003: beazley - Changes to the SWIG runtime library support. - - The -c command line option has been renamed to -noruntime - - New command line option: -runtime. When supplied, this - inserts the symbol SWIG_GLOBAL into the wrapper code. This, - in turn, makes all of the runtime support functions globally - visible. - - New library file: swigrun.i. Used to create modules - for runtime library (if needed). - -11/18/2003: cheetah (William Fulton) - 'make srcrpm' rpmbuild fix - patch from Joe Cooper - -11/18/2003: mkoeppe (Matthias Koeppe) - [Guile] Change meaning of configure option --with-guile to - the name of the Guile executable. The new option --with-guile-prefix - can be used to specify the tree where Guile is - installed. (However, usually it suffices to use the - single option --with-guile-config.) - When running the run tests test-suite, make sure to use the - version of Guile that SWIG was configured for. - -11/17/2003: mkoeppe (Matthias Koeppe) - [Guile] Improvements to object-ownership management in - "-scm" mode. (They do not apply to the default "-gh" mode.) - * Renamed the smob type that indicates that the object can - be garbage collected from "collected swig" to "collectable - swig", which is more precise. - * Export the destructor functions again. It is now - allowed to explicitly call destructors, even for - garbage-collected pointer objects. A pointer object - that has been passed to a destructor is marked in a - special way using a new smob type, "destroyed swig". - (This helps avoid nasty memory bugs, where references to - dead C objects are still held in Scheme. Moreover, the - garbage collector will not try to free a destroyed - object once more.) - * Destructor-like functions can also mark their arguments - as destroyed by applying the typemap SWIGTYPE *DESTROYED. - (It calls the function SWIG_Guile_MarkPointerDestroyed.) - * Functions that "consume" their objects (or that "own" - them after the call) can mark their arguments as - not garbage collectable. This can be done by applying - the typemap SWIGTYPE *CONSUMED. (It calls the function - SWIG_Guile_MarkPointerNoncollectable.) - * The macro TYPEMAP_POINTER_INPUT_OUTPUT from library - pointer-in-out.i creates additional typemaps - PTRTYPE *INPUT_CONSUMED, PTRTYPE *INPUT_DESTROYED. - They mark the passed pointer object likewise. - The typemap PTRTYPE *OUTPUT creates a garbage-collectable - pointer object, like %newobject does for a returned - pointer. Use the new typemap PTRTYPE *OUTPUT_NONCOLLECTABLE - to create a pointer object that will not be garbage collected. - -11/17/2003: mkoeppe (Matthias Koeppe) - [Guile] Handle $input in "freearg" typemaps. - Never qualify GOOPS slot names with the class name. - Handle optional arguments properly in the GOOPS methods. - -11/16/2003: cheetah (William Fulton) - Fixes for installation to work with the upcoming Automake-1.8. - mkinstalldirs was being used by a non-Automake makefile. - mkinstalldirs is being phased out and so was not being - created by Automake. install-sh used instead. - -11/16/2003: cheetah (William Fulton) - [Java] Numerous director improvements, tweaks and bug fixes since - the initial implementation have been contributed by Scott Michel. - -11/12/2003: beazley - [Python] When %feature("shadow") is used to add code to shadow - classes, the special variable $action expands to the name of the - underlying wrapper function that would have been called normally. - -11/12/2003: beazley - [Python] When generating proxy class code, SWIG emits a few - default methods for __repr__() and other Python special - methods. Some of these methods are emitted after all of the - contents of a class. However, this makes it hard to override - the methods using %pythoncode and some other directives that - allow code to be inserted into a class. These special methods - are now emitted into the code *before* all of the other methods. - Suggested by Eric Jones. - -11/11/2003: beazley - Preprocessor enhancement. For include statements like this: - - %include "foo/bar.i" - - the directory "foo" is now added to the search path while - processing the contents of bar.i. Thus, if bar.i includes other - files in the same directory, they will be found. Previously, - you would have to add additional directories using -I to make this - work correctly. Note: the C preprocessor seems to behave in - an identical manner on many (most? all?) systems. - Suggested by Kerim Borchaev. - -11/11/2003: beazley - Configuration changes to make SWIG work on Mac OS X 10.3.x (Panther). - Tested with Python, Tcl, Perl, and Ruby---all of which seem to work. - -11/08/2003: cheetah (William Fulton) - [Java] Fixed the typemaps in various.i which were mostly broken. - char **STRING_IN and char **STRING_RET typemaps replaced with - STRING_ARRAY. float *FLOAT_ARRAY_RETURN typemap removed. - -11/08/2003: beazley - [Tcl] Tcl module now emits a safe module initialization function by - default. It can be removed by running 'swig -nosafe'. - -11/04/2003: mkoeppe (Matthias Koeppe) - [Guile] Only use the SCM_ API when the function - `scm_slot_exists_p' exists (needed for GOOPS support). - This function was renamed during the Guile 1.5 series - from `scm_slots_exists_p'. - Report the right runtime library when invoked with - -scm -ldflags. - -11/03/2003: mkoeppe (Matthias Koeppe) - [Chicken] Fix #782052. The --with-chickencfg configure - option (and others) were not accepted. - -11/02/2003: mkoeppe (Matthias Koeppe) - [Guile] Merge new set of GOOPS changes by John Lenz. - GOOPS objects are now manipulated directly by the C code. - Some fixes to typemap-GOOPS interaction. - -11/02/2003: mkoeppe (Matthias Koeppe) - [Guile] Remove the file argument to -scmstub and -goops. - The Scheme files are now always called MODULE.scm or - MODULE-primitive.scm, where MODULE is the module name and - "primitive" can be changed by the -primsuffix option. - The Scheme files are now placed in the directory given by - the -outdir option, or the current directory. - (Patch by John Lenz, slightly modified.) - - *** INCOMPATIBILITY [Guile] *** - -11/02/2003: mkoeppe (Matthias Koeppe) - Unify the pointer-conversion runtime API. The standard - functions are: - * SWIG_NewPointerObj (POINTER, TYPE, FLAGS) - -- Create an scripting object that represents a typed - pointer. FLAGS are language specific. - * SWIG_ConvertPtr (INPUT, RESULT, TYPE, FLAGS) - -- Get a pointer from the scripting object INPUT and - store it in the place RESULT. When a type mismatch - occurs, return nonzero. - * SWIG_MustGetPtr (INPUT, TYPE, ARGNUM, FLAGS) - -- Get a pointer from the scripting object INPUT and - return it. When a type mismatch occurs, throw an - exception. If ARGNUM > 0, report it as the - argument number that has the type mismatch. - [Guile]: No changes. - [MzScheme]: No changes. - [Perl]: Add the function SWIG_NewPointerObj. - The function SWIG_MakePtr is kept. - The function SWIG_MustGetPtr is currently not - supported. - [Python]: Add the function SWIG_MustGetPtr. - [Ruby]: Add the function SWIG_MustGetPtr. - [Tcl]: Remove the "interp" argument of - SWIG_NewInstanceObj, SWIG_ConvertPtr, - SWIG_ConvertPacked, and SWIG_ConvertPtrFromString. - The function SWIG_MustGetPtr is currently - not supported. - No changes to Pike because its pointer conversion code did - not look complete. No changes to PHP4, because I did not - understand its runtime code. No changes to Chicken - because major changes are expected soon anyway. No - changes to Java, OCaml, C# because they do not seem to - have a pointer-conversion runtime API. - - *** INCOMPATIBILITY [Tcl] *** - -11/02/2003: mkoeppe (Matthias Koeppe) - [Perl5, PHP4, Pike, Python, Ruby, Tcl]: Use the - preprocessor to rename external functions of the SWIG - runtime API to follow the naming convention - SWIG_<language>_<function>. This should allow linking - more than one interpreter into a program. - -10/31/2003: cheetah (William Fulton) - [C#] Fix since introducing the exception and std::string delegates. - The fix overcomes linker errors when using more than one SWIG module. - Problem reported by Andreas Schörk. - -10/31/2003: beazley - Incorporated patch: [ 823302 ] Incr Tcl support. - Contributed by Alexey Dyachenko. - Note: needs documentation. - -10/31/2003: beazley - Incorporated patch: [ 829325 ] new Python Module options and features. - Robin Dunn writes: - - This patch makes a number of changes to the SWIG python module. - - 1. Add -apply option, and change the default code - output to use the foo(*args, **kw) calling syntax - instead of using apply(). If the -apply option is - given then code is generated as before. This is very - similar to Patch #737281 but the new -modern option - makes the second half of that patch unnecessary so it - is not included here. - - 2. Add -new_repr option. This is the same as my Patch - #797002 which I will mark as closed since it is no - longer needed. When this new option is used then the - __repr__ methods that are generated for proxy classes - will be more informative and give details about the - python class and the C++ class. - - 3. Add %feature("addtofunc"). It allows you to insert - one or more lines of code inside the shadow method or - function that is already generated, instead of - replacing the whole thing like %feature("shadow") does. - For __init__ it goes at the end, for __del__ it goes - at the begining and for all others the code generated - is expanded out to be like - - def Bar(*args, **kwargs): - val = _module.Foo_Bar(*args, **kwargs) - return val - - and the "addtofunc" code is inserted just before the - return statement. If the feature is not used for a - particular method or function then the shorter code is - generated just like before. - - 4. A little bit of refactoring to make implementing - addtofunc a little easier. - - 5. Added a -modern command-line flag that will cause - SWIG to omit the cruft in the proxy modules that allows - it to work with versions of Python prior to 2.2. The - result is a simpler, cleaner and faster python proxy - module, but one that requires Python 2.2 or greater. - -10/31/2003: beazley - Incorporated patch: [ 829319 ] XML module tweaks. - This adds a new command line option -xmllite that - greatly reduces the amount of emitted XML code by - eliminating some fields mostly used in SWIG's - internal processing. Contributed by Robin Dunn. - -10/31/2003: beazley - Incorporated patch: [ 829317 ] Adds DohSplitLines function. - Contributed by Robin Dunn. - -10/29/2003: beazley - Fixed [ 827907 ] argout objects not being wrapped properly (PATH). - Patch contributed by Salvador Fandiño García. - -10/29/2003: beazley - Fixed [ 826996 ] perl type checking ignores perl subclasses. - This enhancement makes it so wrapped classes and structs can - be subclassed in Perl and used normally. - Patch contributed by Salvador Fandiño García. - -10/16/2003: cheetah (William Fulton) - [C#] IntPtr marshalled with a void* instead of int in C function - declarations. The casts thus look more conventional, for example: - - // old - DllExport double SWIGSTDCALL CSharp_get_Shape_x(int jarg1) { - ... - Shape *arg1 = (Shape *) 0 ; - arg1 = *(Shape **)&jarg1; - ... - } - // new - DllExport double SWIGSTDCALL CSharp_get_Shape_x(void * jarg1) { - ... - Shape *arg1 = (Shape *) 0 ; - arg1 = (Shape *)jarg1; - ... - } - - -10/14/2003: beazley - Fixed a subtle problem with overloaded methods and smart pointers. - If a class has overloaded methods like this: - - class Foo { - public: - int bar(int x); - static int bar(int x, int y); - }; - - and the class is used as a smart pointer: - - class FooPtr { - public: - Foo *operator->(); - }; - - The SWIG would try to expose the static member Foo::bar - through FooPtr---resulting bogus wrapper code and a compiler - error. - - Due to the way in which overloading is handled, it is - extremely difficult to eliminate the static method in - this case. Therefore, it is still exposed. However, - the generated code now compiles and works. - -10/05/2003: mkoeppe (Matthias Koeppe) - [Guile, MzScheme, Chicken]: Remove symbol clashes between - the runtime libraries by renaming all extern common.swg - functions with the preprocessor. - -10/05/2003: mkoeppe (Matthias Koeppe) - [Guile] Added basic GOOPS support, contributed by John Lenz. - See the documentation for details. - - *** NEW FEATURE *** - -10/04/2003: mkoeppe (Matthias Koeppe) - [Guile] New option, -only-setters, which disables - traditional getter and setter procedures for structure slots. - -10/03/2003: mkoeppe (Matthias Koeppe) - [Guile] Added run test for reference_global_vars by John Lenz. - -09/30/2003: beazley - Partial solution to [ 792180 ] C++ smart-pointer/namespace mixup revisited. - The problem is not easy to fix (at least it doesn't seem so), but is - related to the instantiation of qualified templates inside of other - namespaces. SWIG now generates an error message in this case rather - than generating broken wrappers. - -09/30/2003: beazley - Fixed [ 800012 ] ENTER macro from CORE/scope.h clashes with libc search.h. - Reported by Britton Leo Kerin. - -09/30/2003: beazley - Fixed [ 811518 ] Casting ints to doubles (w/ solution?) - Addresses a problem with overloading in the Perl module. - Reported by Gerald Dalley. - -09/28/2003: mkoeppe - [Guile with -scm option] Fix typo in generated code for - procedures-with-setters. Reported by John Lenz. - -09/26/2003: beazley - Fixed [ 812528 ] externs not correct when throw is in signature. - Reported by Joseph Winston. - -09/23/2003: cheetah (William Fulton) - SWIG was generating a number of symbols that didn't comply with - the ISO C/C++ standard, in particular ISO/IEC 14882:1998(E) 17.4.3.1.2 - where double underscores are forbidden as well as symbols starting with - an underscore followed by an upper case letter. Most of these have - been rooted out. See new section added to internals.html development - manual 'Symbol Naming Guidelines for Generated C/C++ Code'. - -09/23/2003: cheetah (William Fulton) - Director typemap name changes: - inv => directorin - outv => directorout - argoutv => directorargout - - *** POTENTIAL INCOMPATIBILITY *** - -09/19/2003: mrose (Mark Rose) - [Python] Director constructors now default to __disown = 0, - which is the intended behavior and fixes the director_finalizer - test case under python. - -09/12/2003: cheetah (William Fulton) - [C#] - Typemaps added for std::string and const std::string &. - - New delegate for creating a C# string given a char *. It - can be used by calling SWIG_csharp_string_callback as shown - in the std::string 'out' typemap. Useful if the return type is - mapped to a C# string and the calling function is responsible - for cleaning up memory as the C# garbage collector doesn't - free the memory created in C/C++ and then returned as a C# string. - - The exception delegates have moved into an inner class in the - intermediate class, thereby freeing up the static constructor. - -09/11/2003: beazley - (Internals) - Major refactoring of iteration over lists and hashes. The - DOH library now uses iterators. They work like this: - - List *l = (some list); - - Iterator i; - for (i = First(l); i.item; i = Next(i)) { - // i.item contains the actual list item. - // i.item is NULL at end of list - ... - } - - Hash *h = (some hash); - Iterator j; - for (j = First(h); j.item; j = Next(j)) { - // j.item contains hash table item - // j.key contains hash table key - // Both j.item and j.key are NULL at end - ... - } - - The old iteration functions Firstitem(), Nextitem(), Firstkey(), - and Nextkey() are gone. - - The new iterators are simpler, result in better memory use, - and may be faster. Also, there are no longer any problems - iterating over the same list/hash in multiple places at - the same time. For example, this is fine: - - Iterator i,j; - for (i = First(l); i.item; i = Next(i)) { - for (j = First(l); j.item; j = Next(j)) { - ... - } - } - - (This never worked in previous versions). - *** POTENTIAL INCOMPATIBILITY ***. This will probably break - third party extensions to SWIG (or give them further encouragement - to join the SWIG CVS-tree :-). - -09/10/2003: mkoeppe (Matthias Koeppe) - [Guile] Fix memory leaks in the "list-vector.i" typemaps. - -09/09/2003: mkoeppe (Matthias Koeppe) - [Chicken] Use C_mk_bool rather than C_mkbool. This fixes - the wrapping of boolean values for Chicken 1.10 and newer. - Reported by Dave <hundo@yahoo.com> / Felix Winkelmann - <felix@proxima-mt.de>. - -09/05/2003: cheetah (William Fulton) - [Java] Directors implemented for Java. In summary this is a big new feature - which supports upcalls from C++ to Java. Code is generated to support C++ - callbacks to call into Java and true polymorphic behaviour for Java classes - derived from C++ classes. See java.html for details. Contributed by - Scott Michel. - -09/05/2003: Tiger - Created contract example directory at /SWIG/Examples/contract - Added simple contract examples (simple_c & simple_cxx) - Modified contract module's output format - - *** NEW FEATURE *** - -09/01/2003: cheetah (William Fulton) - Test-suite build improvements: - - Multiple build directories working for the test suite, so it is now - possible to run configure in multiple subdirectories and run the test - suite in each of these sub directories. - - 'make distclean' fixed so it doesn't bomb out on the Examples directory - when using multiple subdiretory builds. Required the following directories - to be moved: - Examples/GIFPlot/Perl -> Examples/GIFPlot/Perl5 - Examples/GIFPlot/Php -> Examples/GIFPlot/Php4 - These new directories used to be symbolic links to the old directory. - Also the Examples/test-suite/Perl symbolic link has been removed. - - Running the test-suite, other than from the root directory, say - in Examples/test-suite/python will now display all the code being - executed. - - The following 3 C# compilers are detected during configure and work with - the test-suite: Mono, Portable.NET and Microsoft. - -09/01/2003: Tiger - Added inheritance support for design by contract feature. - -09/01/2003: beazley - Fixed [ 794914 ] Wrong types in template specialization. - SWIG was not handling arguments correctly in template - partial specialization. For example, - - template<class T> class Foo<T *> { - public: - T *blah(); - }; - - %template(FooInt) Foo<int *>; - - in this class, the return type of blah was set to - 'int **', but it should really be 'int *'. This has been - fixed, but it will affect all prior uses of partial - specialization. - -09/01/2003: beazley - Fixed [ 786394 ] Patch for generated perl code does not compile under RedHat9. - Reported by Scott Finneran. - -09/01/2003: beazley - Fixed [ 791579 ] (unsigned) long long handled incorrectly (Tcl). - This was an error in the Tcl typemaps.i file. - Reported by Kjell Wooding. - -09/01/2003: beazley - Fixed [ 797573 ] no way to rename classes coming from C structures. - This problem relates to renaming of anonymous structures with a - typedef. For example: - - %rename(Bar) Foo; - typedef struct { - ... - } Foo; - - Reported by Britton Leo Kerin. - -09/01/2003: beazley - Fixed [ 797576 ] -help seems to imply that only tcl-specific options exist. - Added a comment to alert user to other options. - Reported by Britton Leo Kerin. - -09/01/2003: beazley - Fixed [ 798205 ] Segfault in SWIG_ConvertPtr. - Reported by Prabhu Ramachandran. - -08/30/2003: mrose (Mark Rose) - Modified the director typemaps in python/std_complex.i to use the - new-style macro and conversion functions, which eliminated some - redundant code. Fixed a few bugs in these typemaps as well, although - more testing is needed. - -08/29/2003: mrose (Mark Rose) - Completed initial support for wrapping abstract classes with directors. - Constructor wrappers will be generated for abstract classes that have - directors, and instances of the director classes will be created regardless - of whether the proxy class has been subclassed in the target language. - No checks are made during construction to ensure that all pure virtual - methods are implemented in the target language. Instead, calls to - unimplemented methods will throw SWIG_DIRECTOR_PURE_VIRTUAL_EXCEPTION - exceptions in C++. - - Integrated Prabhu Ramachandran's typemap patches, which provide director - typemap support for enums and std::size_t, and fix a couple bugs in the - director std::vector<> typemaps. - -08/29/2003: cheetah (William Fulton) - [C#] Implemented exception handling for throwing C# exceptions from C/C++ code. - A few delegate functions are available for calling which then throw the C# - exception. Use the SWIG_CSharpThrowException function from C/C++ typemaps. - See the generated wrapper code or csharphead.swg for all available exceptions. - Example: - - SWIG_CSharpThrowException(SWIG_CSharpException, "exception description"); - - The 'throws' typemaps are also now implemented, so code is automatically - generated to convert any C++ exception into a C# System.Exception when the C++ - method declares an exception specification such as: - - int foo() throw(Bar); - - Also any parameters that are references to a C++ class or a class passed by value - and are passed as a C# null will now throw a C# NullReferenceException. - -08/29/2003: cheetah (William Fulton) - [C#] Fix to match the calling convention of all pinvoke methods so that they - match the calling convention used by default in the C# 'static extern' declarations - (__stdcall is used on Windows). - -08/19/2003: cheetah (William Fulton) - [Java] Reworked std::string typemaps. Fixes a number of string in std namespace - problems. For example %template vector<string>. The templated class' get method - wasn't returning a Java String, but a SWIGTYPE_p_string. Reported - by Zach Baum. - -08/15/2003: beazley - Fixed [ 763522 ] 1.3.19 segfault in SwigType_add_pointer/DohInsertitem. - Related to problem with unnamed class handling in Perl module. - -08/15/2003: beazley - Fixed [ 763563 ] Missing indication of optional arguments. - Tcl module. Reported by Krzysztof Kozminski. - -08/15/2003: beazley - Fixed [ 787432 ] long param handled as int. Tcl module - now uses Tcl_GetLongFromObj to convert integer values. - -08/11/2003: beazley - Fixed [ 775989 ] numeric template parameters. There were - some errors in template expansion related to the use of - arrays where the array dimension was a template parameter. - It should work now. Reported by Bryan Green. - -08/10/2003: mrose (Mark Rose) - Added a director typemap (outv) for return by value and cleaned up up a few - of the commented director typemaps. - -08/10/2003: mrose (Mark Rose) - Fixed constructor generation for director classes to ignore private - constructors. Protected constructors are also ignored for now, pending - a solution to the problem of wrapping classes that only define protected - constructors. - -08/07/2003: cheetah (William Fulton) - New commandline option -outdir <dir> to specify where the language specific - files are to be generated. This is useful for target languages like Python, - Java etc which generate proxy files in the appropriate language. - This option does not apply to the C/C++ wrapper file. - -08/07/2003: cheetah (William Fulton) - On Windows the generated files (other than the _wrap.c or _wrap.cxx files) - were sometimes incorrectly being generated into the current directory unless - the input file used the Unix path separator. The Windows path separator - should now be used. Bug reported by Robert Davies. - -08/07/2003: beazley - Added array variable set typemap to Perl module. - -08/07/2003: beazley - Fixed [ 775677 ] Array init causes codegen bug.. - -08/07/2003: beazley - Fixed [ 779062 ] Class"\n"::foo not supported. SWIG - should now correctly handle whitespace in between - namespace qualifiers. For example "A :: Foo :: Bar". - -07/31/2003: cheetah (William Fulton) - Fixes for parameters which are classes that are passed by value and have - a default value. A copy constructor for SwigValueWrapper is required - (SF #780056). Also fixed memory leak in these circumstances. These mods - also fix SF #780054. - -07/28/2003: beazley - Improved run-time error message for pointers in Python module. - Contributed by Zooko. - -07/10/2003: ballabio (Luigi Ballabio) - [Almost all languages] Wrappers for std::pair added. - Typemaps for Python, Ruby, Guile and MzScheme. - -07/01/2003: mkoeppe (Matthias Koeppe) - [Chicken] Handle the case of more than one argout typemap - per function. - -06/29/2003: cheetah (William Fulton) - [Java, C#] SF #670949 request. The destructor wrapper function name is now - configurable. A new attribute called methodname in the - javadestruct/javadestruct_derived (Java) or csdestruct/csdestruct_derived (C#) - typemaps specifies the method name. For example in Java the destructor is - wrapped by default with the delete method: - - %typemap(javadestruct, methodname="delete") SWIGTYPE {...} - -06/27/2003: cheetah (William Fulton) - [Java, C#] The throws attribute for adding exception classes to the throws - clause also now works with the following typemaps: - newfree - javain, javaout (Java) - csin, csout (C#) - - For example, the 'AnException' will be added to the throws clause in the - proxy function: - - %typemap(javaout, throws="AnException") int { - int returnValue=$jnicall; - if (returnValue==0) throw new AnException("Value must not be zero"); - return returnValue; - } - -06/25/2003: mrose (Mark Rose) - [Python] Director typemap marshalling checks for null pointers when - walking the parameter list instead of relying soley on the parameter - count. Cures a segfault that occurred for multiple argument inv typemaps. - Someone with more Swig experience should probably review this code. - -06/24/2003: mkoeppe (Matthias Koeppe) - [Chicken] Don't emit calls to "C_check_for_interrupt", - which may result in an endless loop. Patch by felix@proxima-mt.de. - -06/20/2003: cheetah (William Fulton) - [C#] Finalizers now use destructor syntax as the override which was used in - the Finalize method is not in the ECMA standards, spotted by the MS compiler. - -06/10/2003: cheetah (William Fulton) - [C#] A number of changes have been made to remove the Java naming - that was used in the C# module. - - Typemap name changes: - jni -> ctype - jtype -> imtype - jstype -> cstype - javain -> csin - javaout -> csout - javainterfaces -> csinterfaces - javabase -> csbase - javaclassmodifiers -> csclassmodifiers - javacode -> cscode - javaimports -> csimports - javaptrconstructormodifiers -> csptrconstructormodifiers - javagetcptr -> csgetcptr - javafinalize -> csfinalize - - Feature name changes: - javaconst -> csconst - javamethodmodifiers -> csmethodmodifiers - - Pragma changes: - pragma(java) -> pragma(csharp) - jniclassbase -> imclassbase - jniclassclassmodifiers -> imclassclassmodifiers - jniclasscode -> imclasscode - jniclassimports -> imclassimports - jniclassinterfaces -> imclassinterfaces - - Special variable name changes: - $javaclassname -> $csclassname - $javainput -> $csinput - $jnicall -> $imcall - - This will break SWIG interface files that use these typemaps, features - and pragmas. Please update your code or use macros for backwards - compatibility. - - *** POTENTIAL INCOMPATIBILITY FOR C# MODULE *** - -06/10/2003: mkoeppe (Matthias Koeppe) - [MzScheme] Applied MzScheme module updates contributed by - John Lenz <jelenz@students.wisc.edu>. - - - Updated mzscheme to use SWIG's common runtime type - system from common.swg. - - - The Lib/mzscheme directory has been reorganized to - standardize names across the language modules: - mzscheme.i was moved to mzscheme.swg, mzscheme.swg and - mzschemedec.swg have been removed, mzrun.swg (which - contains the runtime code) has been added. - - - The swig_proxy structure was renamed to swig_mz_proxy. - swig_mz_proxy now contains a pointer to a swig_type_info - structure. - - - Added varin and varout typemaps for SWIGTYPE [] and - SWIGTYPE &. - - - Garbage collection by calling scheme_add_finalizer() has - been added. - - *** NEW FEATURE [MzScheme] *** - -06/10/2003: cheetah (William Fulton) - [Java] New typemaps: javadestruct and javadestruct_derived - for the C++ destructor wrapper. The javadestruct version gets used by - classes at the top of an inheritance chain and the javadestruct_derived - version gets used by other classes. - - [C#] cildispose and cildisposeoverride typemaps replaced by - csdestruct and csdestruct_derived typemaps. The delete() - method has been removed and its functionality put into these - typemaps designed for the Dispose() method. - - - New typemaps csinterfaces and csinterfaces_derived replace - the javainterfaces typemap. Also fixes the peculiarity of all classes - in an inheritance chain individually deriving from the IDisposable - interface. - - - New typemap csfinalize for finalizers. C++ destructors are now called - by garbage collector during finalization. Problem reported by - Andreas Schörk. - -06/10/2003: Tiger - Modified contract code for error message output. - Contract code can now print out simple error message. - Modified contract code to prepare for inheritance - -06/03/2003: mkoeppe - [Guile] Applied Guile module updates contributed by - John Lenz <jelenz@students.wisc.edu>. - - - SWIG currently uses Guile's gh_ API, which is marked as - deprecated in Guile 1.6 and will be removed in Guile - 1.9. This change introduces a command-line flag "-scm" - which causes SWIG to generate wrappers that use Guile's - SCM API instead; this requires Guile >= 1.6. - - - The Lib/guile directory has been reorganized to - standardize names across language modules: guiledec.swg - and guile.swg have been moved into guile_gh_run.swg, - guile.i has been moved to guile_gh.swg, guile_scm.swg - and guile_scm_run.swg which contain the SCM API stuff - have been added - - - ghinterface.i, which contains the defines from the gh_ - functions to the scm_functions has been added - - - The API for dealing with pointer objects is now - SWIG_ConvertPtr, SWIG_MustGetPtr, SWIG_NewPointerObj. - - - Added varin and varout typemaps for SWIGTYPE [] and SWIGTYPE & - - - Garbage collection has been added. - - *** NEW FEATURE [Guile] *** - -06/01/2003: cheetah (William Fulton) - Dimensionless arrays such as - - int foo[] = {1, 2}; - extern int bar[]; - - produce a warning that the variable is read-only. Depending on the target - language, this used to cause compile errors or generate a setter that - generated a runtime error. A setter cannot be automatically generated - because the array size cannot be determined by SWIG. A varin, globalin - or memberin typemap (depending on the target language) must be written - by the user. - -05/29/2003: beazley - Refinement to default typemap matching and arrays. When an - array is declared like this: - - int foo[4]; - - The default typemap now resolves to - - SWIGTYPE [ANY] - - If no match is found for that, it then resolves to - - SWIGTYPE [] - - If no array dimension is specified in the original declaration, - the SWIGTYPE [] is used right away. - - Note: This change has been made to resolve problems related to - arrays with and without dimensions. For example, sometimes SWIG - was generating setter functions for array variables with no dimensions - (an error). Likewise, SWIG sometimes made arrays with dimensions - read-only (also an error). This fixes the arrays_global test - problem. - -05/28/2003: beazley - Fixed subtle type handling bug with references and pointers. - If you had functions like this: - - typedef Foo Bar; - - Foo *func1(); - void func2(Bar &x); - - Then func2() wouldn't accept objects returned by func1() - because of a type error. It should work now. - Reported by Brian Yang. - -05/21/2003: cheetah (William Fulton) - Fixes to some of the Visual C++ example project files which would not - work with spaces in the paths held in the environment variables used to - point to the target language's library / include directory. - SF bug #740769 - -05/21/2003: songyanf (Tiger) - Added -contracts option. - First try of the idea of "Wrap by Contract": - build up realiable cross-language module by wrapping with SWIG. - Implemented basic assertion - (preassertion & postassertion & invariant) - for simple C/C++ functions. - - Current format of contracts are: - %contract class_name :: func_name (paras...) { - require: - boolean exprs; - exprs; - ensure: - boolean expr; - exprs; - invariant: - boolean expr; - exprs; - } - - *** NEW FEATURE *** - -05/19/2003: cheetah (William Fulton) - Build tweaks. There were a few preprocessor definitions which were - specified in the Makefile for passing on the commandline when compiling. - These are now all defined in swigconfig.h. Autoconf doesn't normally - allow installation directories to be defined in this config header file, - but an autoconf archive macro enables this. This macro along with future - autoconf macros are going to be put in the Tools/config directory. - - 'swig -version' now reports the target build platform. - -05/11/2003: cheetah (William Fulton) - [C# and Java] Fix to the following typemaps: - - javabase, javainterfaces, javaimports, javaclassmodifiers, - javaptrconstructormodifiers, javafinalize, javagetcptr & javacode. - - These are the typemaps for modifying/generating proxy classes. - Previously the typemaps would use the proxy class name and not the - C++ type, which was inconsistent with all other typemaps. - - In most circumstances the proxy class name and the C++ class name/type - is the same except for classes in namespace, templated classes etc. so - this shouldn't affect most cases. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA and C# MODULES *** - -05/09/2003: cheetah (William Fulton) - Visual C++ Project files have been added so that the runtime libraries - can be built on Windows (for Tcl, Perl, Python and Ruby). - -05/01/2003: beazley - Fixed problem with return by value, const, and private constructors. - For example: - - class B { - private: - B(); - public: - B(const B&); - }; - - class A { - ... - const B returnB() const; - ... - }; - - Problem and patch suggestion reported by Bill Hoffman. - -04/29/2003: cheetah (William Fulton) - Build changes: - - Single autoconf invocation - autoconf in the Tools directory has gone. - - - Libtool bootstrapped when running autogen.sh. This requires anyone - using the cvs version of SWIG to have libtool installed on their - machine. Suggest version 1.4.2 or higher, preferably the latest - 1.5. - - - Automake is now used to build the runtime libraries in conjunction - with libtool. - - - Runtime libraries are now successfully built as DLLs on Cygwin. - - - Skipping languages is no longer just determined in the top level - makefile but in configure.in. This info is used for building - the runtime libraries and for running the examples and test-suite. - - - These changes have fixed multiple build directory builds, that is - building from directories other than the top level directory. - Installation from multiple build directories also working. An initial - configure in the top level directory is no longer needed as described - in 04/02/2003 entry. A 'make distclean' will be needed before building - in a directory other than the top level directory if the autotools - have been run from this top level directory at some point, but - autoconf will tell you this. Note that 'make check' only works from - the top level directory at the moment. - -04/28/2003: beazley - Fixed [ 723471 ] Wrapper_print() fails with preprocessor directives. - -04/28/2003: beazley - Minor refinement of const static member variable handling - described in CHANGES 08/11/2002. Previously, SWIG merely - checked to see if there was an initializer in the declaration. - Now, SWIG additionally checks to make sure the static member - is const. - -04/25/2003: ljohnson (Lyle Johnson) - [Ruby] Added a kind of limited support for multiple inheritance, - activated using the -minherit command-line option. I've also updated - the "C++ Inheritance" section of the Ruby documentation to discuss - how this works, and its limitations. Also also modified the minherit.i - test case to run against this. - -04/25/2003: ljohnson (Lyle Johnson) - [Ruby] Added the -globalmodule command-line option for the Ruby - module, for wrapping stuff into the global module (Kernel) instead - of a nested module. Updated documentation accordingly. - -04/23/2003: mrose (Mark Rose) - Fixed symname error in director calls to Python methods - that extend C++ operators. - - Stopped director destructor wrappers from calling __set_up, - which was leaving the director flag in an inconsistent state. - -04/23/2003: beazley - Fixed problem with namespace resolution and nested namespaces. - Reported by Alfred Lorber (and Marcelo Matus). - -04/16/2003: cheetah (William Fulton) - Patch for Java examples and test-suite to run on Mac OS X. - -04/15/2003: ljohnson (Lyle Johnson) - [Ruby] Incorporated Nobu Nakada's patches for supporting the Ruby - 1.8 allocation framework. - -04/15/2003: ljohnson (Lyle Johnson) - [Ruby] Replaced all uses of the deprecated STR2CSTR() macro with the - safer StringValuePtr() macro. For more information, see ruby-talk:67059 - and follow-ups to that post. - -04/11/2003: beazley - Fixed problem with preprocessor macro expansion. For example: - - #define min(x,y) ((x) < (y)) ? (x) : (y) - int f(int min); - - Reported by Sebastien Recio. - -04/10/2003: cheetah (William Fulton) - [Java] Added a runtime check to typemaps in arrays_java.i library to check - that the Java array passed in is the same size as the C array and throw an - exception if not. - - Also fix to use delete instead of free for arrays created using new. - -04/07/2003: cheetah (William Fulton) - Remove GCC3 warning when compiling the examples and test-suite: - - cc1plus: warning: changing search order for system directory "/usr/include" - cc1plus: warning: as it has already been specified as a non-system directory - - See SF patch #715531 submitted by Gerald Williams - -04/03/2003: cheetah (William Fulton) - [C#] Improved wrapping of enums and constants. These were previously - wrapped as C# variables rather than constants. Either these are wrapped - as readonly (runtime) constants or compile time constants, depending on - the %javaconst directive (The directive is likely to change name soon). - For example wrapping: - %javaconst(0); - #define ABC 22 - %javaconst(1) XYZ; - #define XYZ 33 - is now: - public static readonly int ABC = examplePINVOKE.get_ABC(); - public const int XYZ = 33; - -04/03/2003: cheetah (William Fulton) - [Java] Global constants and enums are put in their own interface called - xxxConstants, where xxx is the module name. This is an improvement as - it is possible to derive (implement) a Java class from the xxxConstants - interface to improve the syntax; namely when wrapping: - enum {ONE=1, TWO, THREE}; - accessing these from a Java class implementing xxxConstants is neater: - int number = ONE; - than the previous: - int number = xxx.ONE; - - Patch submitted by Dave Dribin. - -04/02/2003: cheetah (William Fulton) - Build improvements for multiple builds. This allows one to build - the SWIG executable and runtime libraries for different platforms/compilers - etc by running configure in different directories. This isn't 100% just - yet and won't be until libtool is better configured... a 'configure' and - 'make distclean' needs to be run in the root directory before it all works. - For example: - $ ./configure - $ make distclean - $ mkdir config1; cd config1; ../configure CC=gcc CXX=g++; make; cd .. - $ mkdir config2; cd config2; ../configure CC=cc CXX=c++; make; cd .. - - To be improved. A 'make check' does not work yet either. - -04/01/2003: beazley - Fixed template partial specialization argument expansion bug. - This showed up when trying to use std_vector.i with vectors - of pointers. - -03/31/2003: cheetah (William Fulton) - Fix for parallel make builds of SWIG, for example - make -j 4 - Build failure reported by Bill Clarke. - -03/28/2003: beazley - Released 1.3.19. - - - -Version 1.3.19 (March 28, 2003) -=============================== - -03/28/2003: beazley - Variety of minor bug fixes to the 1.3.18 release including: - - - Segmentation fault with %extend directive. - - Typemap variable substitution bug. - - Expression evaluation bug. - - Large memory leak with template expansion. - -Version 1.3.18 (March 23, 2003) -=============================== - -03/21/2003: beazley - Fixed two problems with the %extend directive, overloading, and - template expansion. See the 'template_extend_overload' and - 'template_extend_overload_2' tests in Examples/test-suite for - details. - -03/20/2003: cheetah (William Fulton) - [C#] Added some typemaps as suggested by Andreas Schoerk for handling - parameters that are passed as pointers or by reference. These have - been put in typemaps.i. - -03/20/2003: beazley - Fixed a C++ scoping bug related to code like this: - - class Foo { - public: - int Foo::bar(); - }; - - Previously, SWIG just tossed out the Foo::bar() declaration. Now, - the declaration is wrapped provided that the prefix is exactly the - same as the current scope (including any enclosing namespaces). - Reported by Bruce Lowery. - -03/20/2003: beazley - Incorporated [ 696516 ] Enabling exception processing for data member access. - In some compilers, attribute access can generate exceptions. However, - SWIG ordinarily assumes that no exceptions will be raised. To disable this, - use the %feature("allowexcept"). For example: - - %feature("allowexcept") Foo::x; - ... - class Foo { - public: - int x; /* Exception handling enabled */ - ... - }; - - Patch contributed by Yakov Markovitch. - -03/20/2003: beazley - Incorporated Patch. [ 701860 ] Improve Performance (python proxies). - Gives a performance boost to proxy class code and the management of the - .this and .thisown attributes. Contributed by Mike Romberg. - -03/19/2003: cheetah (William Fulton) - [C# and Java] Added missing vararg support. - -03/18/2003: mrose (Mark Rose) - Removed code related to tagging individual methods for directors. - The concept of having directors for some but not all virtual methods - of a class is deeply flawed. The %feature("nodirector") tag is also - gone. - - Directors are off by default. To enable them for a class, issue - %feature("director") classname; which will create director methods - for every virtual method in the hierarchy of the class. - -03/17/2003: beazley - Fixed a subtle problem with passing arguments of type function. For - example: - - int foo(int x(int, int)); - - or - - typedef int binop_t(int, int); - int foo(binop_t x); - - In old versions, this would produce code that wouldn't compile. Now, - SWIG merely adds an extra pointer, making these declarations the same - as: - - int foo(int (*x)(int, int)); - - typedef int binop_t(int, int); - int foo(binop_t *x); - - Reported by Garth Bushell. - -03/17/2003: mrose (Mark Rose) - Fixed the return statement for director base class calls that have no - return value. - -03/15/2003: beazley - Fixed a problem with const smart-pointer wrapping. For example: - - class Foo { - public: - int x; - void bar() const; - void spam(); - }; - - class Blah { - ... - const Foo *operator->(); - ... - }; - - In this case, only "x" and "bar" are visible from Blah (since application - of spam violates constness). Moreover, access to "x" is read-only. - -03/15/2003: mrose (Mark Rose) - Cleaned up two signed versus unsigned comparisons in python/std_vector.i. - -03/15/2003: cheetah (William Fulton) - [C#] Global variables are wrapped using properties instead of get and set methods. - Member variable wrapping bug fixes, for example wrapping pointers work now. - Typemaps are used for all variable wrapping to generate the property code. - -03/13/2003: mrose (Mark Rose) - Fixed a bug in the virtual method unrolling for directors. - The order of unrolling is now from base to derived, to ensure - that the most derived implementation of a director method is - found. - - Director methods for pure virtual methods now throw - DIRECTOR_PURE_VIRTUAL_EXCEPTION if _up is set. - -03/12/2003: cheetah (William Fulton) - [C#] Polymorphism fix: virtual functions now use the appropriate - keyword in the C# proxy class, virtual or override. - Some 'using System;' statement fixes needed by the Mono compiler. - -03/11/2003: beazley - Fixed subtle bug in the application of SwigValueWrapper<> to - template classes with default constructors. Reported by - Bruce Lowery. - -03/11/2003: beazley - The $descriptor(type) variable is now expanded in code supplied to - %extend. This is useful for certain kinds of advanced wrapping - (especially container classes). - -03/11/2003: luigi - Support for std::map. - (a) Integration with scripting language (a la std::vector) for - Python, Ruby, MzScheme, and Guile; - (b) Simple wrapper for other languages - -03/10/2003: beazley - Fixed problem with escape sequences in string and character constants. SWIG - wasn't parsing certain octal codes correctly. - -03/07/2003: beazley - Fixed a variety of subtle preprocessor problems reported by - Sebastien Recio. - - (a) Empty preprocessor values no longer generate "bad constant - value" errors. For example: - - #define FOO - #define FOO BAR - - (b) Macro names can now span multiple lines (technically valid, - although questionable practice). For example: - - #define A_LONG_MACRO_\ - NAME 42 - - (c) Whitespace is no longer required before certain macro values. - For example: - - #define FOO"Hello" - #define BAR\ - "Hello" - -03/07/2003: ljohnson (Lyle Johnson) - [Ruby] Added missing long long and unsigned long long typemaps - in the Lib/ruby/typemaps.i library file. - -03/07/2003: mrose (Mark Rose) - Added Examples/python/callback to demostrate how directors can - be used to implement callbacks in Python - Added Examples/python/extend to demonstrate virtual method - calls from C++ to Python (really the same as the callback - example, just a different context). - Added four tests for very basic director functionality. These - have runtime tests under python. - The Python module now emits #define SWIG_DIRECTORS near the - top of the output file if directors are enabled. This is useful - for disabling parts of tests in target languages that don't - support directors. - -03/06/2003: mrose (Mark Rose) - Added a section to Doc/Manual/Python.html on cross language - polymorphism (directors). - -03/06/2003: mrose (Mark Rose) - The short-lived "-fdirectors" command line option has been - removed. To enable directors, instead use the extended %module - directive as follows: - - %module(directors="1") modulename - -03/06/2003: cheetah (William Fulton) - The long long typemaps have been rewritten so that they can be more - easily used with non ISO compilers, like Visual C++. For example - if you are wrapping the Windows 64 bit type __int64 the long long - typemaps can be used with %apply: - - %apply long long { __int64 }; - __int64 value1(__int64 x); - - __int64 will now appear in the generated code instead of long long. - -03/06/2003: beazley - *** DEVELOPER CHANGE *** - Swig module mutation has been changed slightly. When a language - class method wants to save node attributes, it now uses one of the - following functions: - - Swig_require() - Swig_save() - - The first argument to these functions is a namespace in which - saved attributes are placed. For example,this code - - Node *n; - Swig_save("cDeclaration",n,"type","parms","name",NIL); - - saves the attributes as "cDeclaration:type", "cDeclaration:parms", - and so forth. If necessary, a language module can refer to - old values by using this special namespace qualifier. - - In addition to this, a special attribute "view" contains the name - of the last namespace used to save attributes. In the above - example, "view" would have the value "cDeclaration". The value - of "cDeclaration:view" would have the previous view and so forth. - - Swig_restore(n) restores a node to the state before the last - Swig_require() or Swig_save() call. - - Note: This change makes it easier for language modules to refer - to old values of attributes. - - -03/06/2003: mrose (Mark Rose) - Merged the cross-language polymorphism patch. When enabled, C++ - "proxy" classes (called directors) are generated for each specified - C++ class. Directors pass method calls from C++ to Python, similar - to the way the usual proxy (shadow) classes pass method calls from - Python to C++. Together, these two types of proxies allow C++ - classes that are extended in Python to behave just like ordinary - C++ classes and be used in C++ like native objects. - - This feature is still very experimental and is disabled by default. - To enable director support, specify '-fdirectors' on the SWIG command - line or in the SWIG_FEATURES environment variable. In the interface - file, add %feature("director") to generate directors for all classes - that have virtual methods. - - See http://stm.lbl.gov/~tm2/swig/ProxyDoc.html for more details. - - -03/03/2003: beazley - Fixed a small glitch in typemap local variable replacement. If you had - a typemap like this: - - %typemap(in) type ($1_type temp) { - ... - temp = ...; - ... - } - - and no occurrence of "$1_type" appeared in the body, then the local - variable type wouldn't be substituted. - -03/03/2003: cheetah (William Fulton) - [C#] New version of the CSharp module which is typemap based. - It also uses ECMA C# and no longer uses Microsoft Visual C++.NET - glue. This means that it will work on non-Windows platforms. - Contributed by Neil Cawse. - -02/27/2003: beazley - Fixed [ 653548 ] error parsing casting operator definition. - SWIG now ignores casting operators declared outside of a class. - For example: - - inline A::operator char *() { ... } - - Bug reported by Martin Casado. - -02/27/2003: beazley - Added support for anonymous bit-fields. For example: - - struct Foo { - int x : 4; - int : 4; - int y : 8; - }; - - Anonymous bit-fields are ignored by SWIG. Problem - reported by Franz Höpfinger. - -02/26/2003: cheetah (William Fulton) - [Java] Better typemaps in the Examples/java/typemap example and also - fixes subtle bug when using the StringBuffer typemaps more than once. - -02/26/2003: beazley - Fixed [ 642112 ] Constants char bug. - -02/26/2003: beazley - Fixed [ 675337 ] Partial template specialization not entirely working. - There was a subtle problem related to the naming and ordering of - template partial specialization arguments. Matching worked okay, - the resulting templates weren't expanded correctly. - -02/25/2003: beazley - Fixed problem with parsing (and generating code) for - references to arrays. For example: - - int foo(int (&x)[10]); - -02/25/2003: beazley - Fixed [ 635347 ] Compilation warning from libpy.c. - Reported by Daniel L. Rall. - -02/25/2003: beazley - Fixed a subtle problem with virtual method implementation - checking and typedef. - - typedef int *intptr; - - struct A { - virtual int *foo() = 0; - }; - struct B : public A { - virtual intptr foo() { }; - }; - - SWIG was treating these declarations as different even though - they are the same (via typedef). - -02/25/2003: ljohnson (Lyle Johnson) - [Ruby] Added range checking for the NUM2USHRT macro, per [ 675353 ]. - -02/24/2003: beazley - Fixed a subtle problem with the code that determined if a class is abstract - and can be instantiated. If you had classes like this: - - struct A { - virtual int foo(int) = 0; - }; - struct B : virtual A { - virtual int foo(int); - }; - - struct C : virtual A { - }; - - /* Note order of base classes */ - struct D : B, C { }; /* Ok */ - struct E : C, B { }; /* Broken */ - - then SWIG determined that it could instantiate D(), but not E(). - This inconsistency arose from the depth-first search of the - inheritance hierarchy to locate the implementations of virtual - methods. This problem should now be fixed---SWIG will attempt - to locate any valid implementation of a virtual method by - traversing over the entire hierarchy. - -02/22/2003: cheetah (William Fulton) - [Java] Fix for using enum typemaps. The Java final static variable type - can be set using the jstype typemap, enabling enums to be mapped to - something other than int. Bug reported by Heiner Petith. - -02/21/2003: songyanf (Tiger) - Added CSharp (C#) module prototype - i.e. csharp.cxx & csharp.h at Source/Modules/. - They are for test usage only now and need improvement. - The interface also need to be modified. - - *** NEW FEATURE *** - -02/20/2003: songyanf (Tiger) - Fixed problem with typedef with -fvirtual. - Similar as beazley's modification today. - -02/20/2003: beazley - Added support for gcc-style variadic preprocessor macros. - Patch [ 623258 ] GCC-style vararg macro support. - Contributed by Joe Mason. - -02/20/2003: beazley - Fixed [ 605162 ] Typemap local variables. - Reported by Lyle Johnson. - -02/20/2003: beazley - Fixed problem with abstract classes and typedef. For example: - - class Foo { - public: - virtual void foo(int x) = 0; - }; - - typedef int Integer; - class Bar : public Foo { - public: - virtual void foo(Integer x); - }; - - SWIG was getting confused about the latter method---making Bar - abstract. Reported by Marcelo Matus. - -02/19/2003: cheetah (William Fulton) - [Java] %javaconst(flag) can also be used on enums as well as constants. - This feature enables true Java compiler constants so that they can be - used in Java switch statements. Thanks to Heiner Petith for patches. - -02/19/2003: songyanf (Tiger) - Modified -fcompact feature to deal with PP lines - -02/18/2003: beazley - Fixed [ 689040 ] Missing return value in std_vector.i. - Reported by Robert H. de Vries. - -02/18/2003: beazley - Fixed a few evil scoping problems with templates, namespaces, and the - %extend directive. Problem reported by Luigi Ballabio. - - -02/18/2003: cheetah (William Fulton) - [Ruby] Improved support for Visual C++ and other native Windows compilers. - It is no longer necessary to specify "/EXPORT:Init_<module>", where <module> is the - swig module name when linking using these native Windows compilers. - -02/15/2003: songyanf (Tiger) - Added -fvirtual option. - Reduce the lines and size of the wrapper file - by omitting redifined virtual function in children classes. - - Modified -compact option to -fcompact option - - Added -small option. - -small = -fvirtual -fcompact - And it can be extended by future feature options, - which are used to reduce wrapper file szie. - - Added SWIG_FEATURES environment variable check. - To dynamically set the feature options such as -fcompact & -fvirtual - *** NEW FEATURE *** - -02/13/2003: lenz - Updated Doc/Manual/Perl5.html to talk about C++ compile problems - configure.in now checks for PERL5_CCFLAGS - Runtime/Makefile.in and Example/Makefile.in now use PERL5_CCFLAGS - Added Lib/perl5/noembed.h which contains all the known macro conflicts - -02/12/2003: beazley - Fixed [ 685410 ] C++ Explicit template instantiation causes SWIG to exit. - Fixes a syntax error with declarations similar to this: - - template class std::vector<int>; - - SWIG now ignores the instantiation and generates a warning message. - We might do more later. Reported by Thomas Williamson. - -02/11/2003: cheetah (William Fulton) - Rewrote bool typemaps to remove performance warning for compiling generated code - under Visual C++. - -02/11/2003: cheetah (William Fulton) - Fix for wrapping reference variables (const non-primitive and all non-const types) - for example: - int& i; - Class& c; - const Class& c; - -02/11/2003: beazley - Fixed more very subtle preprocessor corner cases related to recursive - macro expansion. For example: - - #define cat(x,y) x ## y - - cat(cat(1,2),3) // Produces: cat(1,2)3 - - #define xcat(x,y) cat(x,y) - - xcat(xcat(1,2),3) // Produces 123 - - See K&R, 2nd Ed. p. 231. - -02/10/2003: cheetah (William Fulton) - Fixed [ 683882 ] - patch submitted by F. Postma for SWIG to compile on HP-UX. - -02/10/2003: beazley - Fixed subtle preprocessor argument expansion bug. Reported by Marcelo Matus. - -02/10/2003: songyanf - Added -compact option. - Reduce the lines and size of the wrapper file - by omitting comments and combining short lines. - *** NEW FEATURE *** - -02/07/2003: beazley - Fixed [ 651355 ] Syntax error with cstring.i - Reported by Omri Barel. - -02/07/2003: beazley - Fixed [ 663632 ] incompatibility with standard cpp. - This is a refinement that fixes this problem: - - // Some macro with an argument - #define FOO(x) x - - int FOO; /* Not a macro---no arguments */ - -02/05/2003: beazley - Fixed [ 675491 ] parse error with global namespace qualification. - Submitted by Jeremy Yallop. - -02/04/2003: beazley - Fixed bug in varargs processing introduced by the numinputs typemap parameter. - -01/08/2003: ttn - [xml] Fix string-replacement ordering buglet. - Thanks to Gary Herron. - -12/23/2002: cheetah (William Fulton) - Further build changes: - - The SWIG executable is now built using a single Makefile. - - This makefile is generated by Automake (Source/Makefile.am). - - Dependency tracking and tags support are in this makefile. - - Automake 1.7.2 and Autoconf 2.54 minimum versions are needed to build SWIG from CVS. - - Running ./autogen.sh now installs Autoconf/Automake support files into - Tools/config and these files are no longer stored in CVS. - - Bug fixes in 'make install' for systems using .exe executable extension and - ./configure --with-release-suffix=whatever - -12/16/2002: cheetah (William Fulton) - More build changes: - - Autoconf's AC_CANONICAL_HOST replaces proprietary approach for detecting build host. - - Autoconf support files moved to Tools/config. - -12/16/2002: cheetah (William Fulton) - Modifications to run on MacOS, submitted by Bernard Desgraupes. - Mainly ensuring generated files are output in the appropriate directory for - some modules. - -12/11/2002: cheetah (William Fulton) - Various build modifications and bug fixes: - - Simplification of version string. Use autoconf's PACKAGE_VERSION instead. - - Build time removed from SWIG version. - - Using standard autoconf config header generation. - - Updated old autoconf macros as reported by autoupdate. - - Removed $prefix in autoconf from search paths as autoconf won't expand them. - - Subtle bug fix where 'make prefix=/somewhere; make clean; make prefix=/somwhere/else' - produced an executable using the incorrect library directories. - - Added -ldflags commandline option for MzScheme, Ocaml, Pike and PHP. - - Fixed reporting of compiler used when using -version commandline option. - - SWIG web address added to -version commandline option. - -12/11/2002: beazley - Minor fix to Tcl dynamic cast typemaps. Reported by - Kristopher Blom. - -12/10/2002: beazley - Fixed subtle template argument replace bug. Reported by - Chris Flatley. - -12/10/2002: beazley - Reverted CHANGES 09/03/2002, preprocessor argument evaluation. Arguments - are not evaluated during collection, K&R, p. 230. - -12/06/2002: beazley - Fixed [ 649022 ] Compilation problems with KAI/KCC - -12/02/2002: beazley - SWIG 'rel-1-3' CVS branch merged back into the main branch. - - -Version 1.3.17 (November 22, 2002) -================================== - -11/19/2002: beazley - Fixed [ 613922 ] preprocessor errors with HAVE_LONG_LONG. - -11/19/2002: beazley - Fixed [ 615480 ] mzscheme SWIG_MustGetPtr_. - -11/19/2002: beazley - Fixed [ 635119 ] SWIG_croak causes compiler warning. - -11/16/2002: cheetah (William Fulton) - [Java] Added typemaps for pointers to class members. - -11/15/2002: cheetah (William Fulton) - [Java] Bug fix: Overloaded C++ functions which cannot be overloaded in Java - once again issue a warning. - -11/14/2002: cheetah (William Fulton) - [Java] Handling of NULL pointers is improved. A java null object will now - be translated to and from a NULL C/C++ pointer by default. Previously when - wrapping: - - class SomeClass {...}; - void foo(SomeClass *s); - - and it was called from Java with null: - - modulename.foo(null) - - a Java NullPointerException was thrown. Extra typemaps had to be written in - order to obtain a NULL pointer to pass to functions like this one. Now the - default wrapping will detect 'null' and translate it into a NULL pointer. - Also if a function returns a NULL pointer, eg: - - SomeClass *bar() { return NULL; } - - Then this used to be wrapped with a SomeClass proxy class holding a NULL - pointer. Now null is returned instead. These changes are subtle but useful. - The original behaviour can be obtained by using the original typemaps: - - %typemap(javaout) SWIGTYPE { - return new $&javaclassname($jnicall, true); - } - %typemap(javaout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { - return new $javaclassname($jnicall, $owner); - } - %typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{ - protected static long getCPtr($javaclassname obj) { - return obj.swigCPtr; - } - %} - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - - -11/12/2002: beazley - Fixed problem with abstract methods and signatures. For example: - - class abstract_foo { - public: - virtual int meth(int meth_param) = 0; - }; - - - class abstract_bar : public abstract_foo { - public: - int meth(int meth_param_1, int meth_param_2) { return 0; } - }; - - In this case, abstract_bar is still abstract. - - Fixes [ 628438 ] Derived abstract class not abstract. - Reported and patched by Scott Michel. - -11/11/2002: beazley - Fixed a matching problem with typemaps and array dimensions. For example, if you - had this: - - typedef char blah[20]; - - and a typemap: - - %typemap() char [ANY] { - ... $1_dim0 ... - } - - then $1_dim* variables weren't be expanded properly. It should work now. - Problem reported by Pankaj Kumar Goel. - -11/07/2002: mkoeppe - Added an experimental new module that dumps SWIG's parse - tree as (Common) Lisp s-expressions. The module is - invoked with SWIG's -sexp command-line switch. The output - can be read into Common Lisp. There is (prototype) - example Lisp code that generates Foreign Function Interface - definitions for use with Kevin Rosenberg's UFFI. - - *** EXPERIMENTAL NEW FEATURE *** - -11/07/2002: mkoeppe - Removed duplicate declaration of "cpp_template_decl" in - parser.y; bison 1.75 complained. - -11/06/2002: cheetah (William Fulton) - [Java] Default primitive array handling has changed like arrays of classes. - C primitive arrays are no longer wrapped by a Java array but with a pointer - (type wrapper class). Again the changes have been made for efficiency reasons. - The original typemaps have been moved into arrays_java.i, so the original - behaviour can be obtained merely including this file: - - %include "arrays_java.i" - - The array support functions are no longer generated by default. They are only - generated when including this file, thus this often unused code is only - generated when specifically requiring this type of array support. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -11/05/2002: ljohnson (Lyle Johnson) - [Ruby] Added support for nested module declarations (as was - previously added for the Perl module). So a %module directive - of the form: - - %module "Outer::Inner::Foo" - - will nest everything as (in Ruby code): - - module Outer - module Inner - module Foo - # stuff goes here - end - end - end - -11/05/2002: mkoeppe - [MzScheme] Add an argument (-declaremodule) that generates - code to correctly declare a primitive module extension. - Patch submitted by Bruce Butterfield. - -11/02/2002: cheetah (William Fulton) - [Java] Added patch submitted by Michael Cahill to remove unused parameter - warnings for the jenv and cls parameters. This patch also also allows one - to use "void" in the jni typemap for any type without code being generated - attempting to return a value. - -10/29/2002: cheetah (William Fulton) - [Java] Array handling is different. Arrays of classes are no longer wrapped - with proxy arrays, eg wrapping - - class X {...}; - X foo[10]; - - used to be wrapped with these Java getters and setters: - - public static void setFoo(X[] value) {...} - public static X[] getFoo() {...} - - This approach is very inefficient as the entire array is copied numerous - times on each invocation of the getter or setter. These arrays are now - wrapped with a pointer so it is only possible to access the first array element - using a proxy class: - - public static void setFoo(X value) {...} - public static X getFoo() {...} - - Arrays of enums have also been similarly changed. This behaviour is now like the - other SWIG language's implementation and the array library should be used to - access the other elements. The original behaviour can be achieved using the - macros and typemaps in arrays_java.i, for example: - - %include "arrays_java.i" - JAVA_ARRAYSOFCLASSES(X) - class X {...}; - X foo[10]; - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -10/29/2002: cheetah (William Fulton) - [Java] Two new typemaps javain and javaout for generating the proxy class - and type wrapper class method calls to the JNI class. The new typemaps are - really used for transforming the jstype (used in proxy class and type wrapper - classes) to the jtype (used in the JNI class) and visa versa. A javain typemap - is required whenever an in typemap is written and similarly javaout for an out - typemap. An example is probably best to show them working: - - %typemap(javain) Class "Class.getCPtr($javainput)" - %typemap(javain) unsigned short "$javainput" - %typemap(javaout) Class * { - return new Class($jnicall, $owner); - } - - %inline %{ - class Class {}; - Class * bar(Class cls, unsigned short ush) { return new Class(); }; - %} - - The generated proxy code is then: - - public static Class bar(Class cls, int ush) { - return new Class(exampleJNI.bar(Class.getCPtr(cls), ush), false); - } - - - Some new special variables have been introduced in order to use these typemaps. - Here $javainput has been replaced by 'cls' and 'ush'. $jnicall has been replaced by - the native method call, 'exampleJNI.bar(...)' and $owner has been replaced by 'false'. - $javainput is analogous to the $input special variable. It is replaced by the parameter name. - $jnicall is analogous to $action in %exception. It is replaced by the call to the native - method in the JNI class. - $owner is replaced by either true if %newobject has been used otherwise false. - - The java.swg file contains default javain and javout typemaps which will produce the same code - as previously. This change is only of concern to those who have written their own typemaps as - you will then most likely have to write your own javain and javaout typemaps. - - The javaout typemap also makes it possible to use a Java downcast to be used on abstract - proxy base classes. See the Java documentation on dynamic_cast. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -10/24/2002: ttn - [Methodology] Upgaded to libtool 1.4.3, presumably w/ better - support for newish platforms (like MacOS X). - -10/21/2002: ttn - Fixed Runtime/Makefile.in bug -- thanks to Richard Calmbach. - -10/18/2002: ttn - Fixed typo in doh.h -- thanks to Max Horn. - -Version 1.3.16 (October 14, 2002) -================================= - -10/13/2002: beazley - Fixed bug with %extend directive and %feature reported - by William Fulton. - -10/13/2002: beazley - Added OpenVMS build directory (vms). Contributed by - Jean-François Pieronne. - -10/09/2002: cheetah (William Fulton) - [Java] Added throws clause to the native functions in the JNI class. - The throws clause is the same as the one generated for proxy functions - and module class functions. - -09/27/2002: beazley - Fixed some problems with the %import directive and classes that - were defined but not wrapped. Problem reported by Leslie Brooks, - Gerry Woods, and others. - -09/23/2002: cheetah (William Fulton) - [Java] Some error checking added: - 1) OutOfMemoryException check in the char * typemaps. - 2) As SWIG treats pointers, references and passing by value all the - same, it is possible to pass a NULL pointer to a function that expects - an object passed by value or by reference. A NullPointerException is - now thrown under this scenario. - -09/20/2002: ttn - [Methodology] Reworked "make clean" and "make install" - to be more table driven. - [Docs] Explain how to extend "make install" w/ extra-install.list. - -09/15/2002: beazley - Deprecation of the "ignore" typemap. The "ignore" typemap has - been deprecated in favor of a generalization of the "in" typemap. - To ignore an argument, use something like this instead: - - %typemap(in,numinputs=0) int *output (int temp) { - $1 = &temp; - } - - This change fixes a number of subtle bugs related to the interaction - of the "in" and "ignore" typemaps (which were supposed to be - mutually exclusive). - - The use of the numinputs argument is reserved for future expansion. - Currently, values >1 will generate an error. However, future - releases of SWIG may utilize that to support multi-input typemaps. - - %typemap(ignore) still works, but generates a warning message and is - translated to %typemap(in,numinputs=0). - - *** POTENTIAL INCOMPATIBILITY *** - *** NEW FEATURE *** - -09/15/2002: beazley - Fixed segmentation fault for unnamed structures. For example: - - typedef struct { - } *blah; - - - Reported by Roger Gibson. - Note: we might be able to generate wrappers in special cases. - -09/13/2002: beazley - Minor modification to generated wrapper functions. Pointer arguments are now - always set to an initial value of 0. Simplifies typemap writing and cleanup - code (since you can rely on zero-value initialization). This also greatly - reduces the need to ever write an "arginit" typemap. - -09/12/2002: beazley - Minor enhancement to smart-pointer support. If operator->() - is part of an ignored base class like this, - - %ignore Bar; - - class Foo { - public: - int blah(); - }; - - class Bar { /* Ignored */ - public: - ... - Foo *operator->(); - ... - }; - - class Spam : public Bar { }; - - then methods from Foo are still available. For example, - - >>> s = Spam() - >>> s.blah() - 0 - >>> - - The only catch is that the operator->() itself is not available - (since it wasn't wrapped). Therefore, there won't be any - __deref__() operation unless it is explicitly added to Spam - (either using %extend or just placing operator->() in the - definition of Spam). - -09/11/2002: ttn - [Methodology] Reworked "make check" to be more table driven. - [Docs] Docuemented methodology in Manual/Extending.html. - -09/11/2002: ttn - [Docs] Prefixed Manual/*.html with "<!DOCTYPE html ...>" to - pander dotingly to (over-)sensitive editors. - -09/10/2002: ttn - [Guile] Converted Examples/guile/simple "make check" - behavior to actually check execution results. Reduced - iteration counts so that the test doesn't take too long. - -09/10/2002: beazley - SWIG-1.3.15 released. - - -Version 1.3.15 (September 9, 2002) -================================== - -09/09/2002: beazley - Fixed nasty runtime type checking bug with subtypes and inheritance - and templates. - -09/09/2002: cheetah (William Fulton) - [Java] Java exception classes for a method's throws clause can be generated by - specifying them in a comma separated list in the throws attribute in any one - of the following typemaps: in, out, check, freearg, argout and throws. A classic - example would be to convert C++ exceptions into a standard Java exception: - - %typemap(throws, throws="java.io.IOException") file_exception { - jclass excep = jenv->FindClass("java/io/IOException"); - if (excep) - jenv->ThrowNew(excep, $1.what()); - return $null; // or use SWIG_fail - } - - class file_exception {...}; - void open(const char *filename) throw(file_exception); - - The Java method will then be declared with a throws clause: - - public static void open(String filename) throws java.io.IOException {...} - -09/08/2002: mkoeppe - * [Guile] Improved the documentation system. The arglist no - longer gets cluttered with type specification, making it - more readable. (Also the ILISP function C-u M-x - `arglist-lisp' RET works better this way.) The types of - arguments are explained in an extra sentence after the - arglist. - - There are now two documentation-related typemap arguments: - - %typemap(in, doc="$NAME is a vector of integers", - arglist="$name") int *VECTOR { ... } - - The "arglist" texts of all arguments of a function make up - its arglist in the documentation. The "doc" texts of all - arguments are collected to make a sentence that describes - the types of the arguments. Reasonable defaults are - provided. - - As usual, $name is substituted by the name of the - argument. The new typemap variable $NAME is like $name, - but marked-up as a variable. This means that it is - upper-cased; in TeXinfo mode ("-procdocformat texinfo") it - comes out as @var{name}. - - The directives %values_as_list, %values_as_vector, - %multiple_values now also have an effect on the - documentation. (This is achieved via the new pragmas - return_nothing_doc, return_one_doc, return_multi_doc.) - - Documentation has also improved for variables that are - wrapped as procedures-with-setters (command-line switch - "-emit-setters"). - - * [Guile] Emit constants as _immutable_ variables. (This - was broken recently.) - -09/07/2002: mkoeppe - [Guile] Updated the typemaps in list-vector.i. - -09/07/2002: mkoeppe - Short-circuit the typechecks for overloaded functions. - (The changes in code generation are visible in the new - testcase "overload_complicated".) - -09/06/2002: cheetah (William Fulton) - [Java] Solution for [ 596413 ] - New typemap so that the Java proxy classes and type wrapper classes - wrapper constructor modifier can be tailored by users. The default value is - protected. Normally SWIG generates a constructor like this which can only - be accessed within one package: - - protected Bar(long cPtr, boolean cMemoryOwn) { - ... - } - - If you are using SWIG across multiple packages or want to use this constructor - anyway, it can now be accessed outside the package. To modify use for example: - - %typemap(javaptrconstructormodifiers) SWIGTYPE "public" - - to change to public for all proxy classes and similarly for all type wrapper classes: - - %typemap(javaptrconstructormodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "public" - -09/06/2002: cheetah (William Fulton) - [Java] Added throws typemaps for the Java module. C++ exceptions get converted into - java.lang.RuntimeException Java exceptions. - - Warning: This may change from java.lang.Runtime exception in the future. - -09/05/2002: cheetah (William Fulton) - [Java] Fix for variables declared as references. - -09/05/2002: beazley - Fixed [ 605162 ] Typemap local variables. Reported by Lyle Johnson. - -09/05/2002: ljohnson (Lyle Johnson) - [Ruby] More updates to the Ruby module documentation, including - a new typemap example that demonstrates how to collect key-value - pairs from an argument list into a Hash. - -09/05/2002: beazley - Fixed bug with template expansion and constructors. - - template<class T> class Foo { - public: - Foo<T>() { } - }; - - The extra <T> in the constructor was carried through in the - name--causing runtime problems in generated modules. - Reported by Jordi Arnabat Benedicto. - -09/05/2002: mkoeppe - [Guile] Support overloading. - -09/04/2002: ljohnson (Lyle Johnson) - [Ruby] Updated typemaps for long long and unsigned long long types - to use Ruby 1.7 support for these types when available. - -09/04/2002: ljohnson (Lyle Johnson) - [Ruby] Added output typemaps for const reference to primitive - types. - -09/04/2002: mkoeppe - [Guile] Fix pass-by-value typemaps. Reported by Arno - Peters via Debian bugtracking (#156902), patch by Torsten - Landschoff <torsten@debian.org>. - -09/03/2002: samjam (Sam Liddicott) - Better reference support. - Functions that want a void** can take a NULL by reference and - the void* will be made for you and then passed-by-reference - - Also all integer-class native types can be passed by reference - where an int* or int& etc is needed - -09/03/2002: beazley - Changed the evaluation order of preprocessor macro arguments. - Arguments are now expanded by the preprocessor *before* they - are passed to macro expansion. This fixes a subtle expansion - bug reported by Anthony Heading. - -09/03/2002: beazley - Fixed the file include order (again, apparently). See 2/27/99. - -09/02/2002: beazley - [Perl] Better exception handling support. Since Perl error handling - relies on setjmp/longjmp, wrapper functions have been modified slightly - to provide an extra block scope: - - XS(foo) { - char _swigmsg[SWIG_MAX_ERRMSG] = ""; - const char *_swigerr = _swigmsg; - { - /* Normal wrapper function here */ - ... - SWIG_croak("An error occurred\n"); - ... - XSRETURN(argvi); /* Successful return */ - fail: - /* cleanup code */ - } - croak(_swig_err); - } - - The macro SWIG_croak(x) sets the value of _swigerr to x and - executes a "goto fail". The whole wrapper function is enclosed - block scope to provide proper cleanup of C++ objects. Since - croak executes a longjmp(), there is no way to properly reclaim - resources if this executes in the same scope as the wrapper - function. - - The _swigmsg[] variable is normally unused, but can be used - to store small error messages using sprintf or snprintf. It - has a capacity of at least 256 bytes (SWIG_MAX_ERRMSG). - -09/02/2002: beazley - [Tcl] Added better support for exceptions. Instead of returning TCL_ERROR, - use the macro SWIG_fail to return with an error. This ensures that - arguments are properly cleaned up. Exception specifiers are now - handled by default. - -09/02/2002: ljohnson (Lyle Johnson) - [Ruby] The type-checking system for the Ruby module has had a flaw - in that some types which should be considered equivalent - weren't. This bug was best demonstrated by the inherit_missing.i - test suite case, which defines a base class "Foo" that is - subclassed by "Bar". The "Foo" class isn't actually wrapped (i.e. - it's not directly accessible from Ruby) but we'd still like to be - able to pass "Bar" instances to functions expecting Foos and have - that work; it wasn't. The revised implementation (similar to that - used for some other language modules) adds a new instance variable - (__swigtype__) to each object that indicates its SWIG type; - that is, each "Bar" instance will now have a string instance - variable called "__swigtype__" whose value is "_p_Bar". - - Unless developers were taking advantage of this low-level - implementation detail, they shouldn't notice any compatibility - problems; nevertheless, I'm marking it as a "potential - incompatibility". - - *** POTENTIAL INCOMPATIBILITY *** - -09/01/2002: ljohnson (Lyle Johnson) - [Ruby] Fixed SF Bug #603199. - -08/08/2002: cheetah (William Fulton) - [Java] Added OUTPUT, INPUT and INOUT typemaps in typemaps.i for C++ - references. - -08/27/2002: mkoeppe - [Guile] Fixed error in "lib_std_vector" testcase and - compiler warning in "lib_cdata" testcase. - -08/27/2002: ljohnson (Lyle Johnson) - [Ruby] Added the "%mixin" directive, which allows the user to - specify a comma-separated list of module names to mix-in to a - class. So, for example, if you'd like to specify that Ruby's - Enumerable module should be mixed-in to your class Foo, you'd - write: - - %mixin Foo "Enumerable"; - - or to specify that the modules Fee, Fie and Fo should be mixed - in to Foo: - - %mixin Foo "Fee,Fie,Fo"; - - *** NEW FEATURE *** - -08/27/2002: ljohnson (Lyle Johnson) - [Ruby] Modified the %alias directive so that multiple aliases - can be specified for an instance method by using a comma-separated - list of aliases. - -08/27/2002: ljohnson (Lyle Johnson) - [Ruby] Added "throw" typemaps for the Ruby module. - -08/26/2002: beazley - Two new command line options for printing dependencies. - 'swig -M' lists all file dependencies. 'swig -MM' lists - dependencies, but excludes files in the SWIG library. - Example: - - % swig -M -python example.i - example_wrap.cxx: \ - /u0/beazley/Projects/lib/swig1.3/swig.swg \ - /u0/beazley/Projects/lib/swig1.3/python/python.swg \ - example.i \ - example.h - - % swig -MM -python example.i - example_wrap.cxx: \ - example.i \ - example.h - - *** NEW FEATURE *** - -08/26/2002: beazley - Fixed [ 597599 ] union in class: incorrect scope. - Reported by Art Yerkes. - -08/26/2002: beazley - Fixed [ 600132 ] Default argument with namespace. - Reported by Shibukawa Yoshiki. - -08/24/2002: beazley - Automatic C++ exception handling enabled for all language modules. This is - pretty simple. If you have a class like this: - - class Foo { - }; - class Bar { - public: - void blah() throw(Foo); - } - - then the generated wrapper code looks like this: - - wrap_Bar_blah() { - ... - try { - arg1->blah(); - } - catch (Foo &_e) { - /* "throw" typemap code inserted. $1 = _e */ - } - catch (...) { - throw; - } - } - The "throw" typemap can be used to raise an error in the target - language. It can do anything. Here is a very simple example: - - %typemap("throw") Foo { - PyErr_SetString(PyExc_RuntimeError, "Foo exception"); - return NULL; - } - - To make this work in each language module, simply define a few default - "throw" typemaps for SWIGTYPE, SWIGTYPE *, int, const char *, and a - few common exception types. That's all there is to it. - - Automatic exception handling can be disabled using -noexcept or - setting the NoExcept global variable to 1. - *** NEW FEATURE *** - -08/23/2002: beazley - [ Python ] - Automatic translation of C++ exception specifications into error handling code. - For example: - - class Foo { - }; - class Bar { - public: - void blah() throw(Foo); - } - - In this case, Foo is wrapped as a classic-style class (compatible - with exception handling). Furthermore, you can write Python code - like this: - - b = Bar() - try: - b.blah(); - except Foo,e: # Note use of exception class here! - # Handle Foo error - ... - - The object "e" in the exception handler is just a wrapped Foo - object. Access it like a normal object. - - If an exception is not wrapped as a class, a RuntimeError - exception is raised. The argument to this exception is - the exception object. For example: - - class Bar { - public: - void blah() throw(int); - } - - b = Bar() - try: - b.blah(); - except RuntimeError,e: - print e.args[0] # Integer exception value - - Comments: - - - If a class is used as an exception, it *must* be wrapped - as a Python classic-style class (new classes don't work). - - - Automatic exception handling is compatible with %exception. - - - Use -noexcept to turn off this feature. - - - The newly introduced "throw" typemap is used to raise - Python errors (naturally). - - *** EXPERIMENTAL NEW FEATURE *** - -08/23/2002: beazley - Information from throw() specifiers is now stored in the parse - tree. For example: - - class Foo { - public: - int blah() throw(spam,bar); - } - - The stored information is fully corrected for namespaces and works - with templates. Uses will follow. - -08/22/2002: beazley - Exception handling code is no longer applied to member access - function. For example, in this code - - %exception { - try { - $action - } catch(whatever) { - ... - } - } - - class Foo { - public: - int x; - ... - } - - The exception handling code is not applied to accessor functions - for Foo::x. This should reduce the amount of extra code - generated. - - Caveat: Exception handling code *is* used when attributes are - accessed through a smart-pointer or a synthesized attributed - added with %extend is used. - -08/22/2002: beazley - Made more patches to hopefully eliminate problems when compiling SWIG - as a 64-bit executable. - -08/22/2002: beazley - Fixed a bug with const reference members, variables, and static members. - For example: - - class Foo { - public: - static const int &ref; - }; - - SWIG was trying to generate "set" functions which wouldn't compile. - -08/21/2002: beazley - Made the warning message for "Class X might abstract" off by default. - Enable with -Wall. - -08/21/2002: beazley - Refined handling of const and non-const overloaded methods. If - a class defines a method like this: - - class Foo { - public: - int bar(int); - int bar(int) const; - } - - Then the non-const method is *always* selected in overloading and - the const method silently discarded. If running with -Wall, a warning - message will be generated. - -08/19/2002: beazley - Better support for using declarations and inheritance. Consider this: - - class Foo { - public: - int blah(int x); - }; - - class Bar { - public: - double blah(double x); - }; - - class FooBar : public Foo, public Bar { - public: - char *blah(char *x); - using Foo::blah; - using Bar::blah; - }; - - Now SWIG wraps FooBar::blah as an overloaded method that uses all - accessible versions of blah(). See section 15.2.2 in Stroustrup, 3rd Ed. - - SWIG also supports access change through using declarations. For example: - - class Foo { - protected: - int x; - int blah(int x); - }; - - class Bar : public Foo { - public: - using Foo::x; - using Foo::blah; - }; - - - Caveat: SWIG does not actually check to see if declarations imported - via 'using' are in the inheritance hierarchy. If this occurs, the - wrapper code won't compile anyways---not sure it's worth worrying about. - -08/18/2002: beazley - Modified overloading dispatch to not include nodes with an "error" attribute. - A language module can set this if a node couldn't be wrapped and you don't want - it included in the dispatch function. - -08/18/2002: beazley - Enhancement to overloaded function dispatch. The dispatcher is now aware of - inheritance relationships. For example: - - class Foo { }; - class Bar : public Foo { }; - - void spam(Foo *f); - void spam(Bar *b); - - In this case, the dispatcher re-orders the functions so that spam(Bar *b) is - checked first---it is more specific than spam(Foo *f). - -08/17/2002: beazley - Added -Werror command line option. If supplied, warning messages are treated - as errors and SWIG will return a non-zero exit code. - -08/17/2002: beazley - Fixed [ 596135 ] Typedef of reference can't compile. For example: - - typedef int &IntRef; - void foo(IntRef i); - - SWIG-1.3.14 generated code that wouldn't compile. - -Version 1.3.14 (August 12, 2002) -================================ - -08/11/2002: mmatus - Static const members initialized during declaration, and - only them, ie: - - struct A - { - static const int a = 1 ; // this one - static const int b; // not this one - }; - - are emitted like constants (equivalent to enums or - explicit %constant). - - This is because they cannot be added directly to 'cvar' - since they lack the needed reference (well, you can force - them to have a real reference, but in an ugly way which - goes completely again the original purpose of initialize - them during declaration, you also have to deal with extra - linking matters, and it take a while to figure out what is - the problem and how to solve it). - - Please test it with your preferred target language, and - not only the code generation, but really run the example - in the test-suite (static-const-member-2.i) because the - problem and the solution cannot be "fully" appreciated - until you try to load the module and run it. - - In some target languages (python specially), this can - produces a difference in the way that the static constant - members 'a' and 'b' are internally wrapped. Hopefully, - they still can be accessed in the same way. - - -08/11/2002: mmatus - [python] Now static const members can be accessed in a more - natural way, ie, if you have - - struct A - { - typedef unsigned int viewflags; - static const viewflags forward_field = 0; - static const viewflags backward_field; - }; - - now you can do: - - print A.backward_field - - and also - - a = A() - print a.forward_field - - Note that if the static const members don't have an - initializer (like backward_field), still you can access - them in the same way in the python side, but the - implementation is a quite different: backward_field will - still appear in the cvar entity, and also, you are - responsible to initialize it in some code unit, and link it - properly. forward_field, by the other hand, will not - appear in the cvar entity but only as a A member, similar - to what happen with enum or %constant members. - -08/11/2002: mmatus - [python] Common code in the __setattr__/__getattr__ now - goes to two "free" methods at the beginning of the proxy - file, from where each class use it. This change reduces - the size of the proxy file, specially if you wrap a lot of - small classes in one module (up to 33% in some cases), - making it faster to load too. - -08/09/2002: beazley - [Perl5] If a function that returns char * returns NULL, - undef is returned to the Perl interpreter. - -08/09/2002: beazley - Fix to conversion operators and namespaces. For example: - - namespace ns { - struct Foo { }; - struct Bar { - operator Foo*(); - }; - } - - In the wrapper code, SWIG was using ->operator Foo*() - when it should have been using ->operator ns::Foo*(). - - Note: if using %rename with a conversion operator, you - might have to do this: - - %rename(toFooPtr) ns::operator ns::Foo*(); - // ^^^^ note extra qualifier - namespace ns { - ... - - -08/09/2002: beazley - [Python] Minor enhancement to 'const' variable declarations. - Normally const declarations are wrapped as read-only variables - accessible only through the cvar attribute (see SWIG.html for - a discussion of why). However, in many programs, "const" - declarations may just be constants---making the cvar. access - awkward. To fix this, "const" declarations are now available - both through cvar. and as a simple name. For example: - - const int FOO = 42; - - In Python: - - >>> print example.cvar.FOO - 42 - >>> print example.FOO - 42 - - Note: There are cases where the value of a "const" variable - might change. For example: - - char *const BAR = "Hello World"; - - In this case, the pointer itself can not change, but the - data being pointed to could be modified. In these situations, - cvar.BAR should be accessed to obtained the current value. - -08/08/2002: beazley - [Python] Fixed generation of the proxy code (.py files) to more - closely follow the order of declarations as they appear in - the .i file. In the past, all of the class wrappers appeared - first, followed by function stubs, inserted Python code, and - other details. - -08/08/2002: cheetah (William Fulton) - [Java] Proxy method _delete() changed to delete(). There shouldn't ever - be a wrapped function called delete() as it is a C++ keyword and there - is no such thing as a member function in C. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - - Backwards compatibility can be achieved by adding the function back in - for all proxy classes: - %typemap(javacode) SWIGTYPE %{ - public void _delete() { - delete(); - } - %} - - Java backwards compatibility summary - ------------------------------------ - - There are a number of changes that have been made in improving the Java module - for ver 1.3.14. If at all possible change your code to take advantages of the - improvements. If you were using proxy classes you may not notice any backwards - compatibility issues. Here is an example which will help with most backwards - compatibility problems where it is not possible to modify the code that uses - the generated output: - - Replace: - %module modulename - - With: - %module (jniclassname="modulename") modulename; - %typemap(javacode) SWIGTYPE %{ - public long getCPtr$javaclassname() { - return swigCPtr; - } - public void _delete() { - delete(); - } - %} - %pragma(java) jniclassclassmodifiers="public"; - - The proxy constructors that took parameters (long cPtr, boolean cMemoryOwn) - were public and are now protected. If you were making use of these then you'll - have to modify your code and the best solution would be to use the new type - wrapper classes. - - The other main areas are the pragmas and global variable wrapping. Replace - the pragmas with one of the new directives or typemaps mentioned below and use - %rename on the variables. - - If you were not using proxy classes, you will have to define a jstype typemap - as well as a jtype typemap. - -08/08/2002: cheetah (William Fulton) - [Java] Fix for wrapping two dimension array variables. - -08/07/2002: beazley - [Python,Tcl] - Object management now has a much better sense of ownership. - Ownership bits is changed whenever an object is stored in a - global variable or structure member. For example: - - struct Foo { - int val; - Foo *next; - }; - - Now in Python - - >>> f = Foo() - >>> f.thisown - 1 - >>> g = Foo() - >>> g.next = f # Assign a pointer - >>> f.thisown # Notice ownership change - 0 - >>> - - This scheme is mostly a conservative heuristic designed to - provide segmentation faults. It could cause a memory leak - if ownership is changed unnecessarily. In this case, you can - either write a typemap (that doesn't change ownership), or - manually set the thisown attribute back to 1. - -08/07/2002: beazley - [Tcl] Major usability improvements to the object interface. - Suppose you had code like this: - - struct Foo { - int x; - int spam(); - }; - - void blah(Foo *f); - - In past versions of SWIG, you could create objects and use - them like this: - - % Foo f - % f configure -x 3 - % f spam - 37 - - The only problem is that if you tried to call blah(), it didn't - work: - - % blah f - Type Error. Expected _p_Foo - % - - Instead, you had to do this: - - % blah [f cget -this] - - SWIG now automatically extracts the -this pointer, avoiding this - problem. This means that saying "blah f" is perfectly legal and - everything will still work normally. - - Caveat: Since pointer strings start with a leading underscore (_), - don't use this in object names. For example: - - % Foo _f - % blah _f # Potential crash - - Objects now have a -thisown attribute that shows the ownership. - This builds upon the CHANGES 11/24/2001 entry. - -08/07/2002: samjam, Sam Liddicott - Properly implemented pointer system using php resources. - Still need to work out whether or not to let script-users call - destructors directly - -08/06/2002: beazley - Upgraded mzscheme module to support version 201 and added - overloading support. - -08/05/2002: beazley - Added parsing support for extra grouping (in very limited cases). - For example: - - typedef int (FuncPtr)(int, double); - - *** EXPERIMENTAL *** - -08/03/2002: ljohnson (Lyle Johnson) - [Ruby] Updates to typemaps.i as those done previously for Perl, - Python and Tcl modules. Now supports reference types with INPUT, - OUTPUT and INOUT typemaps. - -08/02/2002: beazley - New library file cstring.i added. Provides macros for - manipulating char * data. - -08/02/2002: beazley - Deprecated the %new directive. Use %newobject instead. For - example: - - %newobject foo; - ... - char *foo(); - - %newobject follows the same rules as %rename, %ignore, %feature, - etc. - - *** POTENTIAL INCOMPATIBILITY *** - -08/01/2002: cheetah (William Fulton) - [Java] New attribute 'jniclassname' for the module directive allows a way of - changing the JNI class name from the default which uses the modulename with JNI - appended after it. - - %module (jniclassname="name") modulename - - If 'name' is the same as 'modulename' then the module class name gets changed - from 'modulename' to modulenameModule. - -08/01/2002: beazley - Fixed problem with file include order. Language specific - directories should take precedence over generic directories. - For example: "swig_lib/python/foo.i" should be loaded before - "swig_lib/foo.i". I thought this was the case already, but - apparently it has been broken for quite some time. - -08/01/2002: beazley - Added std_deque.i library file. Work in progress. - -08/01/2002: beazley - [Python,Tcl,Perl] - Improvements to typemaps.i. INPUT/INOUT typemaps perform better - error checking. Typemaps are now supplied for references like - int &OUTPUT, double &INOUT, etc. - -08/01/2002: beazley - [Python] Deprecated the T_* and L_* typemaps in typemaps.i. - Multiple return values are always placed in a tuple. Deprecated - the BOTH typemaps. This is now INOUT (e.g., int *INOUT). - - *** POTENTIAL INCOMPATIBILITY FOR PYTHON MODULE *** - -08/01/2002: beazley - Deprecated the array.i, carray.i, and timer.i library files. - -08/01/2002: beazley - Deprecated the pointer.i library file. Use cpointer.i instead. - *** POTENTIAL INCOMPATIBILITY *** - -08/01/2002: cheetah (William Fulton) - [Java] For consistency the global variable getters and setters use the JavaBean - property design pattern like member variables always have. This means if you are - wrapping a variable called foo, the getter is called getFoo() and the setter is - called setFoo(). Before the recent changes to the Java module the getters and - setters were called get_foo() and set_foo(). If you really want the original - function names use the %rename directive like this: %rename(_foo) Foo; - -07/31/2002: beazley - Fixed casting problem with multiple inheritance. If you had this, - - class foo {}; - class bar : public foo {}; - class baz : public foo {}; - class spam : public bar, public baz {}; - - then the wrappers wouldn't compile due to an ambiguous cast. - Reported by Art Yerkes. - -07/30/2002: cheetah (William Fulton) - [Java] Due to new static typechecking all pointers held in a Java long are part of - the internal workings and this pointer value in the Java long has become abstracted - data. The type wrapper constructor and getCPtr() methods are as such protected. - If you need to mess around with pointers from Java or for example create a proxy - class or type wrapper class around a null pointer, add a function/constructor - to do so with the %javacode typemap. You can also make getCPtr() public again with - the %javagetcptr typemap. - -07/30/2002: cheetah (William Fulton) - [Java] Fixes for %typemap(ignore). In particular when ignoring the last parameter - in a function. Also for all parameters in constructors. These mods have also fixed - multi-argument typemaps for proxy classes - SF 581791. - -07/30/2002: cheetah (William Fulton) - [Java] %newobject (replacement for %new) now implemented for Java. - -07/29/2002: beazley - Fixed problem with typemap copies, %apply, and %clear inside - C++ namespaces. - -07/28/2002: cheetah (William Fulton) - [Java] The JNI class now has package access as the class modifier - has been changed from "public" to nothing. This has been done - as this class is now more for the internal workings of SWIG since the module - class has static type checking for all types. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - - Backwards compatibility can be achieved by using the %jniclassclassmodifier - pragma to change it back to "public". - -07/28/2002: cheetah (William Fulton) - [Java] Proxy/Shadow classes are generated by default. The -proxy and - -shadow command line options are deprecated. If you want to use the - low-level functional interface then use the new -noproxy commandline option. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -07/28/2002: cheetah (William Fulton) - [Java] Remaining pragmas shakeup. These were the remaining pragmas and their - new names where changed: - - modulebase - modulecode - moduleclassmodifiers - moduleimport => moduleimports - moduleinterface => moduleinterfaces - - The moduleimports works slightly differently to how the moduleimport pragma worked. - Now it actually takes code which gets placed before the class definition so the - whole import statement has to be given, for example: - - %pragma(java) moduleimports=%{ - import java.io.*; - import java.math.*; - %} - - The moduleinterfaces is slightly different to the old moduleinterface in that if - more than one interface is required they must be comma separated in one use of - the pragma, for example: - - %pragma(java) moduleinterfaces="Serializable, MyInterface" - - These last two pragmas are consistent with the javainterfaces and javaimports - typemap. - - A similar set of pragmas has been introduced, namely: - - jniclassbase - jniclasscode - jniclassclassmodifiers - jniclassimport - jniclassinterface - - These work in the same way as their module counterparts. Note that previously - the moduleXXX pragmas worked on the old module class which is now called the - JNI class (the class with the native functions). The jniclassXXX pragmas now - work on the new module class (the class that has all the global functions and - global variable getters and setters when using proxy classes, plus all other - remaining functions when using the low-level procedural interface). - - In summary the contents of the pragmas make up a class like this: - - <jniclassimports> - <jniclassmodifiers> class modulename extends <jniclassbase> implements <jniclassinterfaces> { - <jniclasscode> - ... SWIG generated functions ... - } -} - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -07/28/2002: cheetah (William Fulton) - [Java] Deprecated modulemethodmodifiers pragma and replaced with - a better %feature based directive called %javamethodmodifiers. - A useful example would be for synchronisation in multi-threaded apps: - - %javamethodmodifiers foo(int a) "public synchronized"; - - Changes this function from the default ("public") to "public synchronized". - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -07/26/2002: beazley - Several directives now allow optional configuration parameters. - These include: - - %module(name="value", name="value", ...) modulename - %import(name="value", ...) "filename.i" - %extend(name="value", ...) classname { - ... - } - - These currently have no effect and are reserved for - future expansion. - -07/26/2002: beazley - Enhancements to smart-pointer handling. SWIG only provides - extra support for a smart-pointer if operator->() returns - a proper pointer. For example: - - Foo *operator->(); - - If operator->() returns an object by value or reference, - then SWIG examines the returned object to see if it also - implements operator->(). If so, SWIG chases operator->() - until it can find one that returns a pointer. This allows - cases like this to work: - - class Foo { - public: - void blah(); - }; - - class Bar { - ... - Foo *operator->(); - ... - }; - - class Spam { - ... - Bar operator->(); - ... - }; - - For example: - - >>> s = Spam() - >>> s.blah() # Invokes Foo::blah() - - The s.blah() call actually invokes: - - ((s.operator->()).operator->())->blah(); - -07/26/2002: beazley - Fixed a bug with typedef and references. For example: - - typedef Foo & FooRef; - FooRef blah(); - - Previous versions of SWIG generated code that wouldn't - compile. - -07/25/2002: beazley - Wrapping of static methods has been improved in proxy classes. In older - versions of SWIG, if you had this: - - class Foo { - public: - static void bar(); - }; - - The static method was only available as a function Foo_bar(). For example: - - >>> Foo_bar() - - Now, the static method can also be invoked through an instance like this: - - >>> f = Foo() - >>> f.bar() # Invokes static method - - This works with all versions of Python. Additionally, for Python-2.2, - the static method can be invoked as: - - >>> Foo.bar() - - The old-style function is still support for backwards compatibility. If - you care about making your code across different versions of Python, - either use Foo_bar() or access the method through an instance. - -07/25/2002: beazley - Changes to the Python module. Proxy classes now utilize new Python-2.2 - features including properties and static methods. However, these features - are supported in a way that provides backwards compatibility with older - Python versions. In other words, proxy classes work with all versions - of Python and only use new features when running on Python-2.2. - - -07/25/2002: beazley - Modified %extend so that overloaded methods can be added. For example: - - %extend Foo { - void bar(int x) { }; - void bar(char *s) { }; - ... - } - - This works with both C++ *and* C. - -07/24/2002: cheetah (William Fulton) - [Java] More new typemaps so that the Java proxy classes and type wrapper classes - can be further tailored by users. These are the default code for generating the - finalize() methods (proxy classes only) and the getCPtr() methods for proxy - classes and type wrapper classes: - - %typemap(javafinalize) SWIGTYPE %{ - protected void finalize() { - _delete(); - } - %} - - %typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{ - public static long getCPtr($javaclassname obj) { - return obj.swigCPtr; - } - %} - - The javagetcptr typemap will enable users to handle Java null by overriding - this typemap - a requested feature. - - The -nofinalize commandline option has been deprecated. The javafinalize - typemap is more powerful as it will allow the removal of the finalize methods - for all or any one or more particular proxy class. - -07/23/2002: cheetah (William Fulton) - [Java] The getCPtrXXX() function has been changed to a static function and - is now of the form: - - protected static long getCPtr(XXX obj) {...} - - This is a requested change which will allow Java null pointers to be used as null - can be passed in for obj. However, to achieve this the appropriate code must be - written using the new javagetcptr typemap directive. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - - Backwards compatibility can be achieved by adding this function back in using the - new javacode typemap: - - %typemap(javacode) SWIGTYPE %{ - - // SWIG-1.3.12 and SWIG-1.3.13 - public long getCPtr$javaclassname() { - return swigCPtr; - } - // SWIG-1.3.11 and earlier - public long getCPtr() { - return swigCPtr; - } - - %} - - -07/23/2002: cheetah (William Fulton) - [Java] New directive to control constant code generation - %javaconst. - The default handling for handling constants is to get the value through - a JNI call, eg - - #define YELLOW 5 - #define BIG 1234LL - - results in: - - public final static int YELLOW = modulename.get_YELLOW(); - public final static long BIG = modulename.get_BIG(); - - Earlier versions of the Java module initialised the value using the C value: - - public final static int YELLOW = 5; - public final static long BIG = 1234LL; - - This works in most cases, but the value for BIG won't compile as 1234LL is not - valid Java code and this is one of the reasons why the default is now to get the - values through a JNI call. The side effect is that these 'constants' cannot be used - in switch statements. The %javaconst directive allows one to specify the - way the constant value is initialised and works like other %feature - directives, eg - - %javaconst(0); // all constants from this point on are initialised using the C value - %javaconst(1) BIG; // just BIG initialised using JNI call (must be parsed before BIG is defined) - -07/23/2002: beazley - *** IMPORTANT CHANGES TO THE PYTHON MODULE *** - - (1) The Python module now enables shadow/proxy classes by default. - This means that two files are always created by SWIG. For - instance, if you have this: - - // file: foo.i - %module foo - ... - - Then swig generates two files "foo_wrap.c" and "foo.py". - - (2) The name of the low-level C extension module has been changed - to start with a leading underscore. This means that you have - to compile the module as follows: - - $ cc -c -I/usr/local/include/python2.2 foo_wrap.c - $ cc -shared foo_wrap.o $(OBJS) -o _foo.so - ^^^^ - note extra underscore - - This naming scheme is consistent with other Python modules that - utilize extension code. For instance, the socket module consists - of "_socket.so" and "socket.py". In previous versions of SWIG, - the shared object file was named "foocmodule.so". - - (3) A new directive can be used to insert Python code into - the corresponding .py file. For example: - - %pythoncode %{ - def foo(): - print "Hello World" - %} - - This directive allows you to create modules as a mix of C and Python. - Python code is seamlessly added to the module. - - (4) The -shadow command line option is deprecated. This is turned on - by default. - - (5) To disable the generation of the extra python file, use the "-noproxy" - command line option. - - *** POTENTIAL INCOMPATIBILITY *** - This change will likely break the build environment of projects that - utilize shadow classes. To fix this, you probably only need to - change the name of the target .so file. For example, if you have - Makefile information like this: - - TARGET = examplecmodule.so - - Just change it to: - - TARGET = _example.so - - *** DOCUMENTATION UPDATE *** - The file Doc/Manual/Python.html has been updated to describe these changes. - - -07/23/2002: beazley - Added -noextern option. If supplied, SWIG will not generate - extra extern declarations. This is sometimes an issue on - non-unix platforms. - -07/23/2002: beazley - Added a warning for ignored friend functions. - -07/23/2002: beazley - Fixed [ 574498 ] -proxy and %include "pointer.i" clash. - Reported by David Creasy. - -07/23/2002: beazley - Fixed [ 576103 ] global destruction warning with shadow. - Perl extensions should no longer report the warning - - "Use of uninitialized value during global destruction." - - when running with "perl -w". Reported by - Brett Williams. - -07/23/2002: beazley - In C++ mode, SWIG now always defines namespace std. By default, - it's empty. However, this will silence errors from programs - that include statements such as "using namespace std;". - This fixes Bug [ 584017 ] using namespace std generates error. - Reported by Joseph Winston. - -07/22/2002: beazley - Added a new warning message for %apply. If you use %apply but no typemaps - are defined, you will get a warning message. This should help with - problems like this: - - %apply char *OUTPUT { ... }; - - In old versions of SWIG, this silently did nothing. Now you get an error like this: - - file:line. Warning. Can't apply (char *OUTPUT). No typemaps are defined. - -07/22/2002: cheetah (William Fulton) - [Java] Started Java pragma deprecation. Replacements use %typemap based - directives and enable proxy classes and the new type wrapper classes to be - tailored in various ways. These are the new typemaps: - - %typemap(javabase) - base (extends) for Java class - %typemap(javaclassmodifiers) - class modifiers for the Java class: default is "public" - %typemap(javacode) - java code is copied verbatim to the Java class - %typemap(javaimports) - import statements for Java class - %typemap(javainterfaces) - interfaces (extends) for Java class - - And these are the %pragma directives being deprecated: - allshadowbase - allshadowclassmodifiers - allshadowcode - allshadowimport - allshadowinterface - shadowbase - shadowclassmodifiers - shadowcode - shadowimport - shadowinterface - - Note that it is possible to target a particular proxy class: - %typemap(javaimports) Foo "import java.util.*" - or a particular type wrapper class: - %typemap(javaimports) double* "import java.math.*" - Note that $javaclassname in these typemaps are substituted with either the proxy - classname when using proxy classes or the SWIGTYPE class name. - -07/18/2002: cheetah (William Fulton) - [Java] Java module overhaul to implement static type checking of all - types. - - 1) Changes when using Java Proxy classes - ---------------------------------------- - - Previously when wrapping global functions: - - class SomeClass{}; - void foo(SomeClass* s); - SomeClass* bar(); - - The native method prototypes used a long for pointers and looked like this: - - public class modulename { - ... - public final static native void foo(long jarg1); - public final static native long bar(); - } - - and unlike member functions of a C++ class there was no wrapper around the native calls - to make the use of them more user friendly. They would be used from Java like this: - - SomeClass s = new SomeClass(modulename.bar(), false); - modulename.foo(s.getCPtrSomeClass()); - - Note that the following will have the same effect, but then it would not have - been possible to call any proxy member functions in SomeClass: - - long s = modulename.bar(); - modulename.foo(s); - - Now wrapper functions are generated: - - public class modulename { - public static void foo(SomeClass s) { - // calls the native function - } - - public static SomeClass bar() { - // calls the native function - } - } - - Which means these functions can now be used more naturally with proxy classes: - - SomeClass s = modulename.bar(); - modulename.foo(s); - - 2) Changes when not using Java Proxy classes - -------------------------------------------- - - The so called low-level interface was rather low-level indeed. The - new static type checking implementation makes it less so but it remains a - functional interface to the C/C++ world. Proxy classes are the obvious way to use - SWIG generated code, but for those who want a functional interface all non-primitive - types now have a simple Java class wrapper around the C/C++ type. Pointers and - references to primitive types are also wrapped by type wrapper classes. The type - wrapper classnames are based on the SWIG descriptors used by the other language - modules. For example: - - C/C++ type Java type wrapper class name - ---------- ---------------------------- - int* SWIGTYPE_p_int - double** SWIGTYPE_p_p_double - SomeClass* SWIGTYPE_p_SomeClass - SomeClass& SWIGTYPE_p_SomeClass - SomeClass SWIGTYPE_p_SomeClass - - Note that everything wrapped by SWIG is accessed via a pointer even when wrapping - functions that pass by value or reference. So the previous example would now be - used like this: - - SWIGTYPE_p_SomeClass s = example.bar(); - example.foo(s); - - Note that typedefs that SWIG knows about are resolved, so that if one has - - class Foo{}; - typedef Foo Bar; - - then any use of Bar will require one to use SWIGTYPE_p_Foo; - - Some considerations: - Make sure you make a firm decision to use either proxy classes or the functional - interface early on as the classnames are different. - - 3) Pointers and non-parsed types - -------------------------------- - Sometimes SWIG cannot generate a proxy class. This occurs when the definition of - a type is not parsed by SWIG, but is then used as a variable or a parameter. - For example, - - void foo(Snazzy sds); - - If SWIG has not parsed Snazzy it handles it simply as a pointer to a Snazzy. - The Java module gives it a type wrapper class around the pointer and calls it - SWIGTYPE_p_Snazzy. In other words it handles it in the same manner as types are - handled in the low-level functional interface. This approach is used for all - non-proxy classes, eg all pointer to pointers and pointers to primitive types. - - 4) Backwards compatibility - ----------------------- - Backwards compatibility is not an issue if you have been using proxy classes and - no global variables/functions. Otherwise some changes will have to be made. - The native methods still exist but they are now in a JNI class, which is called - modulenameJNI. As this class is really part of the internal workings, - it should not be required so the class has become protected. Some pragmas/directives - will hopefully be added to help with backwards compatibility. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -07/18/2002: beazley - Modified wrapping of uninstantiated templates returned by - value. Just to be safe, they are now wrapped by SwigValueWrapper<> - just in case they don't define a default constructor. This - would be used if you had code like this - - Foo<int> blah(); - void moreblah(Foo<int> x); - - but you didn't instantiate Foo<int> using %template. - We should probably add a warning for this. - -07/17/2002: beazley - Added an error check to detect shadowed template paramaters. - For example: - - template<class T> class Foo { - public: - int T; - }; - - This results in an error, not a warning. This warning is - also needed to fix some rather insidious problems like - this: - - struct T { - int blah; - }; - - template<class T> class Foo { - public: - typedef T Traits; // Which T is this???? - }; - - In this case, the template parameter T shadows the outer - structure (which is what you want). - -07/16/2002: beazley - Improved support for templates with integer arguments. SWIG is - much more aware of situations such as this: - - const int Size = 100; - - %template(Foo100) Foo<100>; - void bar(Foo<Size> *x); // Knows that Foo<Size> is the same as Foo<100>; - -07/15/2002: beazley - Fixed bug with %feature/%ignore/%rename and namespaces. - For example: - - %ignore Foo::Bar - namespace Foo { - class Bar { - ... - }; - } - - Reported by Marcelo Matus. - -07/09/2002: beazley - Added parsing support for constructors that try to catch - exceptions in initializers. For example: - - class Foo { - Bar b; - public: - Foo(int x) try - : b(x) { ... } - catch(int) { - ... - } - } - - This has no effect on the generated wrappers. However, the try and catch - parts of the declaration are ignored. See Stroustrup, 3rd Ed, section - 14.4.6.1 for details. - -07/06/2002: beazley - Fixed bug in template symbol table management. This fixes - two bugs. First, mixing abstract methods, templates, and - inheritance no longer generates a failed assertion. - - template <class T> - class A { - public: - virtual void foo() = 0; - }; - - template <class T> - class B : public A<T> - { - }; - %template(A_int) A<int>; - %template(B_int) B<int>; - - This fix also fixes a subtle problem with default values and - templates. For example: - - template <class C> - struct B { - typedef unsigned int size_type; - static const size_type nindex = static_cast<size_type>(-1); - void foo(size_type index = nindex); - }; - - Bugs reported by Marcelo Matus. - - -07/05/2002: ljohnson (Lyle Johnson) - [Ruby] Changed the definition of the SWIG_ConvertPtr() function - for the SWIG/Ruby runtime support so that it looks like the - Python version. If the last argument (flags) is non-zero, - SWIG_ConvertPtr() will raise an exception for type mismatches - as before. If flags is zero, this function will return -1 for - type mismatches without raising an exception. - - *** POTENTIAL INCOMPATIBILITY FOR RUBY MODULE *** - -07/04/2002: beazley - Overloaded functions/methods/constructors now work in many language - modules. The support is completely transparent--just call the - function normally and SWIG will dispatch to the correct implementation. - There are a variety of issues associated with this. Please refer - to the overloading section of Doc/Manual/SWIGPlus.html for details. - *** NEW FEATURE *** - -07/04/2002: beazley - Fixed a bug with namespaces, enums, and templates. For example: - - namespace hello { - enum Hello { Hi, Hola }; - - template <Hello H> - struct traits - { - typedef double value_type; - }; - - traits<Hi>::value_type say_hi() - { - return traits<Hi>::value_type(1); - } - } - SWIG wasn't generating wrappers that properly qualified - traits<Hi>. Reported by Marcelo Matus. - -06/30/2002: beazley - Supplied array variable typemaps for Tcl module. If you have a - variable like this: - - int foo[10]; - - then a set function like this is generated: - - void foo_set(int *x) { - memmove(foo,x,10*sizeof(int)); - } - -06/30/2002: beazley - New %fragment directive. When writing typemaps, it can be easy to - get carried away and write a lot of code. However, doing so causes - tremendous code bloat. A common way to solve this is to write - helper functions. For example: - - %{ - void some_helper_function() { - ... - } - %} - - %typemap(in) type { - some_helper_function(...); - } - - The only problem with this is that the wrapper file gets polluted - with helper functions even if they aren't used. To fix this, - a new fragment directive is available. For example: - - (corrected typo in line below - 06/26/2008) - %fragment("type_header","header") %{ - void some_helper_function() { - ... - } - %} - - %typemap(in, fragment="type_header") type { - some_helper_function(...); - } - - In this case, the code fragment is only emitted if the typemap is - actually used. A similar capability is provided for declaration - annotation and the %feature directive. For example: - - %feature("fragment","type_header") SomeDeclaration; - - The first argument to %fragment is the fragment name. The second argument - is the file section where the fragment should be emitted. - - The primary use of this directive is for writers of language modules - and advanced users wanting to streamline typemap code. - - *** EXPERIMENTAL NEW FEATURE *** - -06/30/2002: beazley - Supplied memberin typemaps for all arrays in an attempt to eliminate - confusion about their use. - -06/29/2002: beazley - Experimental support for smart-pointers. When a class defines - operator->() like this - - class Foo { - ... - Bar *operator->(); - ... - }; - - SWIG locates class Bar and tries to wrap its member variables and - methods as part of Foo. For example, if Bar was defined like this: - - class Bar { - public: - int x; - int spam(); - }; - - You could do this (in the target language): - - f = Foo() - f.x = 4 # Accesses Bar::x - f.spam() # Accesses Bar::spam - - The primary use of this feature is to emulate the behavior of C++ - smart-pointers---which allow attributes to accessed transparently - through operator->. - - This feature is supported automatically in SWIG---no special directives - are needed. To disable this behavior. Use %ignore to ignore - operator->. - *** NEW FEATURE *** - -06/26/2002: beazley - Deprecated the %except directive. %exception should be used instead. - -06/25/2002: beazley - Major cleanup of the modules directory. Eliminated most - header files, consolidated module code into single files. - -06/24/2002: beazley - Reworked the instantiation of language modules. All language - modules must now define a factory function similar to this: - - extern "C" Language * - swig_python(void) { - return new PYTHON(); - } - - This function is then placed in a table and associated with - a command line option in swigmain.cxx. - - This approach has a number of benefits. It decouples the - SWIG main program from having to know about the class - definitions for each module. Also, by using a factory - function, it will be easier to implement dynamic loading - of modules (simply load the file and invoke the factory - function). - -06/24/2002: beazley - Fixed syntax error for reference conversions. For example: - - operator Foo &(); - -06/24/2002: beazley - Fixed syntax error for operator new[] and operator delete[]. - -06/24/2002: beazley - Fixed code generation problem for constants and default arguments - involving templates. - -06/19/2002: ljohnson (Lyle Johnson) - [Ruby] Fixed a bug for the '-feature' command line argument; - that setting was effectively being ignored and so the feature - name was always set equal to the module name. - -06/17/2002: beazley - Fixed problems with static members and enums in templates. - -Version 1.3.13 (June 17, 2002) -============================== - -06/16/2002: beazley - Fixed a bug with __FILE__ expansion in the preprocessor. On Windows, - the backslash (\) is now converted to (\\) in the string literal - used for __FILE__. Reported by Steve Glaser. - -06/14/2002: beazley - Fixed warning message about 'name private in this context'. The - warning is only generated for public methods. Reported by - Scott Michel. - -06/14/2002: beazley - Fixed some problems related to template instantiation - and namespaces. When SWIG expands a template, it does - so with fully resolved types. For example, if you have this: - - template<class T> class foo { }; - typedef double Double; - %template(foo_d) foo<Double>; - - then, it is handled as foo<double> in the typesystem. - This fixes a number of subtle problems with inheritance - and templates. - -06/14/2002: ljohnson (Lyle Johnson) - [Ruby] Added missing bool typemaps for INPUT, OUTPUT and - INOUT in Lib/ruby/typemaps.i. - -05/29/2002: cheetah (William Fulton) - [Java] Fix for a couple of broken pragmas. - -05/29/2002: cheetah (William Fulton) - Fix for unnecessary cast when wrapping global variable where - the type is not parsed by SWIG - Java variables example - failure as reported by Larry Virden. - -06/10/2002: beazley - Modified %template to allow for empty instantiations. - - %template() foo<int,int>; - - This registers foo<int,int> with the type system, but - doesn't wrap it (same as %ignore). This may only be a - temporary measure. SWIG might be able to automatically - instantiate templates in certain cases. - -06/10/2002: beazley - Fixed function prototype problems with Tcl 8.4 - -06/09/2002: beazley - Fixed problem with templates and location of base classes. - This one is a little mind-bending, but here is an example - that illustrates: - - template <class ArgType, class ResType> - struct traits - { - typedef ArgType arg_type; - typedef ResType res_type; - }; - - template <class ArgType, class ResType> - struct Function - { - }; - - template <class AF, class AG> - struct Class : Function<typename traits<AF, AG>::arg_type, - typename traits<AF, AG>::res_type> - { - }; - - %template(traits_dd) traits <double, double>; - %template(Function_dd) Function <double, double>; - %template(Class_dd) Class <double, double>; - - - In this example, the base class of 'Class' is determined from - the Function template, but the types are obtained through typedefs. - Because of this, SWIG could not locate the wrapped base class - (Function<double,double>). Should be fixed in 1.3.13 even - though I can think of a million other things that might - also be broken. - -06/07/2002: beazley - Fixed a problem with conversion operators. If you had an - operator like this, - - operator double() const; - - SWIG was ommitting the "const" qualifier. This affected - %rename and other directives. Reported by Zhong Ren. - -06/07/2002: beazley - Lessened the strictness of abstract class checking. If - you have code like this: - - class Foo { - public: - virtual int method() = 0; - }; - - class Bar : public Foo { - public: - Bar(); - ~Bar(); - }; - - SWIG will go ahead and generate constructor/destructors - for Bar. However, it will also generate a warning message - that "Bar" might be abstract (since method() isn't defined). - In SWIG-1.3.12, SWIG refused to generate a constructor at all. - -06/07/2002: beazley - Change to %template directive. If you specify something like this: - - %template(vi) std::vector<int>; - - It is *exactly* the same as this: - - namespace std { - %template(vi) vector<int>; - } - - SWIG-1.3.12 tried to instantiate the template outside of the namespace - using some trick. However, this was extremely problematic and full - holes. This version is safer. - -06/07/2002: beazley - Fixed bug with scope qualification and templates. For example: - - A<B::C>::DD - - Before, this was separated as scopes A<B, C>, and DD. Fixed now. - -06/06/2002: beazley - Allow the following syntax: - - class A { }; - struct B : A { ... }; - - A base class without a specifier is assumed to be public for a struct. - -06/06/2002: beazley - Fixed syntax error with template constructor initializers. - Reported by Marcelo Matus. - -06/06/2002: beazley - Fixed bug with default template arguments. - Reported by Marcelo Matus. - -06/05/2002: beazley - Fixed subtle problems with %rename directive and template - expansion. - - Code like this should now work: - - %rename(blah) foo<double>::method; - ... - template<class T> class foo { - public: - void method(); - }; - - %template(whatever) foo<double>; - -06/05/2002: beazley - Resolved some tricky issues of multi-pass compilation and - and inheritance. The following situation now generates - an error: - - class Foo : public Bar { - ... - }; - - class Bar { - ... - }; - - The following code generates a warning about incomplete classes. - - class Bar; - class Foo : public Bar { }; - - The following code generates a warning about an undefined class. - - class Foo : public Bar { }; // Bar undefined - - This fixes a failed assertion bug reported by Jason Stewart. - -06/05/2002: ljohnson - [Ruby] Added a warning message for the Ruby module about the lack - of support for multiple inheritance. Only the first base class - listed is used and the others are ignored. (Reported by Craig - Files). - -06/03/2002: beazley - Fixed a bug with struct declarations and typedef. For example: - - typedef struct Foo Foo; - struct Foo { - ... - }; - - A few other subtle struct related typing problems were - also resolved. - -Version 1.3.12 (June 2, 2002) -============================= - -05/30/2002: beazley - Fixed problem related to forward template class declarations and - namespaces. Bug reported by Marcelo Matus. - -05/30/2002: beazley - Added 'make uninstall' target. Contributed by Joel Reed. - -05/29/2002: beazley - Fixed rather insidious bug with %rename, %feature and template specialization. - For example: - - %exception vector::__getitem__ { - ... some exception ... - } - - template<class T> class vector { - ... - T __getitem__(int index); // Fine - ... - }; - - template<> class vector<int> { - ... - T __getitem__(int index); // Oops. - ... - }; - - Now, the %exception directive (and other features) should correctly apply to - both vector and specializations. - -05/29/2002: beazley - Subtle changes to %template() directive. Template arguments are now - reduced to primitive types in template matching. For example: - - template<class T> class vector<T *> { - ... partial specialization ... - } - - typedef int *IntPtr; // Gross typedef - - // Gets the above partial specialization - %template(vectorIntPtr) vector<IntPtr>; - - This change is extremely subtle, but it fixes a number of potential - holes in Luigi's STL library modules. For example: - - typedef int Integer; - %template(vectori) vector<int>; - -05/29/2002: beazley - Fixed rather insidious typemap bug related to const. const - was being discarded through typedefs. - -05/29/2002: ljohnson (Lyle Johnson) - [Ruby] Added input typemaps for const references to primitive - types (in Lib/ruby/ruby.swg). - -05/29/2002: cheetah (William Fulton) - [Java] The java arrray support functions are enclosed by - a SWIG_NOARRAYS #define. Useful if not using arrays and - it is desirable to minimise the amount of compiled code. - -05/29/2002: cheetah (William Fulton) - [Java] Enums were not renamed when using %name or %rename - fix. - -05/28/2002: ljohnson - [Ruby] Modified the name of the wrapper functions for the - "new" singleton method and "initialize" instance method for - consistency with the other language modules. The wrapper name - for the function that implements "new" is alloc_classname and - the wrapper name for the function that implements "initialize" - is new_classname. - - -05/27/2002: beazley - Changes to runtime. Pointer conversion/creation functions - now almost always have an extra "flags" argument. For - example: - - SWIG_ConvertPtr(obj, void **, swig_type_info *ty, int flags); - ^^^^^^^^^^ - This extra parameter is reserved for future expansion and will - be used for more control over pointers in future versions. - -05/27/2002: beazley - Fix for C++ classes with private assignment operators. It - is now possible to safely return objects like this by value. - Caveat: the class must provide a copy constructor. - -05/26/2002: beazley - -proxy option added to many language modules. This is the - same as -shadow. We are merely changing terminology. - -05/26/2002: beazley - [perl] Fixed some inconsistencies in the -package option. - -package merely sets the package name to be used on the - wrappers. It does not change the name of the shared library - file or the name of the generated .pm file. This was - broken at some point, but works again now. - -05/25/2002: beazley - [perl] Fixed [ 475452 ] memory leak in return-by-value. - Problem related to static member variables returning newly - allocated objects. Reported by Roy Lecates. - -05/25/2002: beazley - [perl] Fixed [ 513134 ] %BLESSEDMEMBERS isn't always right. - Reported by Fleur Diana Dragan. - -05/25/2002: beazley - Fixed [ 540735 ] -importall and the -I option. - -05/25/2002: beazley - [guile] Fixed [ 532723 ] Default arg for char* can SegV. - Error in guile module. Reported by Brett Williams. - -05/25/2002: beazley - Subtle change to typemap application code. The "freearg" - typemap must exactly match up with the "in" or "ignore" - typemap. For example: - - %typemap(in) (char *data, int len) { ... } - %typemap(freearg) char *data { ... } - - void foo(char *data, int len); - - In this case, the "in" typemap is applied, but the - freearg typemap is not. This is because the freearg - typemap doesn't match up with the input argument sequence. - -05/25/2002: beazley - Fixed [ 548272 ] Default argument code missing braces. - Reported by Brett Williams. - -05/25/2002: beazley - Fixed [ 547730 ] SwigValueWrapper needed for constructors. - Reported by William Fulton. - -05/25/2002: beazley - Undefined identifiers now evaluate to 0 when evaluating - preprocessor expressions. For example: - - #if !FOO - ... - #endif - - where FOO is undefined or set to some non-numeric value. - - Fixes [ 540868 ] #if defined whatever - not parsed. - Reported by Adam Hupp. - - -05/24/2002: beazley - SWIG now ignores the C++ 'export' keyword. - -05/23/2002: beazley - Some refinement of type-name mangling to account for pointers, arrays, - references, and other embedded type constructs. - -05/23/2002: beazley - Initial attempt at supporting template partial specialization. At - the very least, it is parsed and the classes are stored. Matching - of instantiations to specialized version is more limited and based on - the SWIG default typemap rules: - - SWIGTYPE * - SWIGTYPE [] - SWIGTYPE & - - Now, why in the world would you want to use this feature? Other - than allowing for slightly modified class APIs, this capability is - primarily used to provide advanced wrapping support for STL-like - objects. It can also be mixed with typemaps. Here is an example: - - - /* Generic version */ - template<class T> class vector { - %typemap(in) vector<T> * { - // A container of objects - } - }; - /* Partial specialization (pointers) */ - template<class T> class vector<T *> { - %typemap(in) vector<T> * { - // A container of pointers to objects. - } - }; - /* Specialization (integers). */ - template<> class vector<int> { - %typemap(in) vector<int> * { - // A container of integers. - } - }; - - *** EXPERIMENTAL FEATURE *** - -05/23/2002: beazley - Enhancement to typemaps. Normally, typemap variables are - renamed to avoid conflicts. For example: - - %typemap(in) int * (int temp) { - $1 = &temp; - } - - This results in code that creates and uses variables "temp1","temp2", - "temp3" and so forth depending on how many times the typemap is used. - Sometimes you want a single variable instead. To do that, using - the following naming scheme: - - %typemap(in) int *(int _global_temp) { - } - - Is this case, a single variable _global_temp is emitted in the - wrapper functions. It is shared across all typemaps. Repeated - typemaps do not replicate the variable---they use the first one - emitted. - *** NEW FEATURE *** - -05/23/2002: beazley - Minor enhancement to typemaps. If you have this code, - - %typemap(in) Foo (int somevar = 3) { - ... - } - - the default value for somevar is now emitted into the wrapper code. - -05/22/2002: beazley - Fixed %extend to be better behaved in namespaces. If you have code - like this: - - namespace foo { - struct bar { - %extend { - void blah(); - }; - }; - } - - SWIG matches the blah() method to a C function named - void foo_bar_blah(foo::bar *self). - - This is consistent with the non-namespace version. - Bug reported by Marcelo Matus. - -05/22/2002: beazley - New library files: cpointer.i, carrays.i, cmalloc.i. These - provide access to C pointers and memory allocation functions. - See Doc/Manual/Library.html for details. - -05/22/2002: cheetah (William Fulton) - [Java] C type char no longer maps to Java type byte, but to Java type char. - It is now treated as a character rather than a signed number. This fits in - with the other language modules and is a more natural mapping as char* is - mapped as a string of characters. Note that the C signed char type is still - mapped to a Java byte. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -05/22/2002: cheetah (William Fulton) - [Java] Improved constants wrapping. Constants (#define and %constant) values - are now obtained through a JNI call. Previously the value was compiled as - Java code, but this didn't work for all cases, eg #define 123ULL. - -05/22/2002: beazley - Fixed bogus error message with %extend directive and C++ - access specifiers. Reported by Marcelo Matus. - -05/22/2002: beazley - Namespaces and enums now work correctly. For example: - - namespace Foo { - enum Bar { A, B }; - } - - Bug reported by Marcelo Matus. - -05/21/2002: beazley - The %types directive can now be used to specify inheritance relationships - in the runtime type system. For example, - - %types(Foo = Bar); - - specifies that Foo isa Bar. Using this is potentially quite dangerous. - However, this is useful in certain cases (and in the SWIG library). - -05/20/2002: beazley - %nodefault and %makedefault directives now require a trailing semicolon. - For example: - - %nodefault; - ... - %makedefault; - - In addition both directives can take a class name. For example: - - %nodefault Foo; - - class Foo { /* No default constructor/destructor */ - }; - - class Bar { /* Default constructor/destructor generated */ - }; - - *** POTENTIAL INCOMPATIBILITY *** - If you don't use the trailing semicolon, things will mysteriously break. - -05/20/2002: beazley - More improvements to type system handling. SWIG now correctly handles - template names and parameters in a namespace. For example: - - namespace foo { - template<class T> class bar { }; - typedef int Integer; - - void blah(bar<Integer> *x); - }; - - In the generated code, all of the typenames are properly qualified. - -05/17/2002: cheetah (William Fulton) - [Java] deprecated broken -jnic and -jnicpp commandline options. The C or C++ - JNI calling convention is now determined from the -c++ commandline option. - -05/16/2002: cheetah (William Fulton) - [Java] The JCALL macros which exist so that the same typemaps can be used - for generating both the C and C++ JNI calling conventions no longer appear - in the generated code. This is because the output is now passed through the - SWIG preprocessor which does the macro expansion for either C or C++ (depending - on whether -c++ is passed on the SWIG commandline). - - The generation of the functions used in the array typemaps have been adjusted - to take account of this. The side effect is that any typemaps which contained - JCALL macros within %{ %} brackets will have to be moved within {} brackets - so that the SWIG preprocessor can expand the macros. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -05/13/2002: beazley - Class templates may now be used as template parameters. For example: - - template<class T, template<class> class C> class Foo { - ... - }; - template<class T> class Bar { - ... - }; - - %template(Fooi) Foo<int, Bar>; - - SWIG doesn't really do anything special with this---it's just - another way of specifying a template parameter. - -05/13/2002: beazley - Minor refinement of template support. Template parameter names are no longer - required for types. For example: - - template<bool> class Foo { - }; - - Obviously, names are required for template<class T>; - -05/12/2002: beazley - New macro expansion in typemaps. The sequence: - - $descriptor(type) - - Will expand into the SWIG type descriptor structor for - the given type. Type may be any abstract datatype. - For example: - - $descriptor(int *) - $descriptor(int (*)(int,double)) - $descriptor(vector<int> *) - - Caveat: It is *NOT* currently legal to use other typemap - substitution variables in the macro. For example - $descriptor($1_type). - - The primary purpose of this modification is to better - support typemaps for container objects or to allow typemaps - that might be performing type conversions. - *** NEW FEATURE *** - -05/11/2002: beazley - The wrapping of references to primitive types has been - changed as follows: - - Arguments of type 'const primitive &' are now passed - by value as opposed to pointers. Return values of - type 'const primitive &' are returned as values instead of - pointers. - - 'primitive' is any one of int, short, long, long long, - char, float, double, bool (as well as unsigned variants). - - This change is being made to better support C++ wrapping--especially - code that makes use of templates and the STL. - -05/11/2002: beazley - The %template directive can now be used to access templates - in a namespace. For example: - - namespace std { - template<class T> class complex { - T re, im; - public: - complex(T _r = T(), T _i = T()) : re(_r), im(_i) { } - T real() { return re; } - T imag() { return im; } - }; - } - - %template(complex) std::complex<double>; - - Note: There are some very subtle namespace/symbol table - management issues involved in the implementation of this. - It may not work in certain cases. - -05/10/2002: beazley - Member template constructor support added. For example: - - template<typename _T1, typename _T2> - struct pair { - _T1 first; - _T2 second; - pair() : first(_T1()), second(_T2()) { } - template<class _U1, class _U2> pair(const pair<_U1,_U2> &x); - }; - - To instantiate the template, use %template and %extend. - For example, this expands the constructor into a default - copy constructor: - - %extend pair { - %template(pair) pair<_T1,_T2>; - } - - Highly experimental. Other uses may be broken. - -05/10/2002: beazley - The %extend (%addmethods) directive no longer works unless - it appears in the public section of a class. An error - message is now generated (as opposed to a segmentation fault). - -05/09/2002: beazley - New %warnfilter() directive. This directive attaches a warning - filter to specific declarations and has the same semantics as - %rename, %ignore, %feature, and so forth. For example: - - %warnfilter(501) foo; // Suppress overloaded warning - int foo(int); - int foo(double); - - or - - %warnfilter(501) Object::foo(double); - class Object { - public: - int foo(int); - int foo(double); - }; - - This feature only suppresses warnings in later stages of code - generation. It does not suppress warnings related to preprocessing - or parsing. - *** NEW FEATURE *** - -05/09/2002: beazley - SWIG now supports C99 variadic preprocessor macros. For example: - - #define debugf(fmt,...) fprintf(stderr,fmt,__VA_ARGS__) - - The argument "..." is used to indicate variable arguments which - are all placed into the special argument name __VA_ARGS__ in - the macro expansion. - - SWIG also implements the GNU (##) extension for swallowing the - preceding comma when __VA_ARGS__ is empty. For example: - - #define debugf(fmt,...) fprintf(stderr,fmt, ##__VA_ARGS__) - - Here is how this is expanded: - - debugf("%d", 3) --> fprintf(stderr,"%d",3) - debugf("Hello") --> fprintf(stderr,"Hello" ) - - (notice the deleted comma). - *** NEW FEATURE *** - -05/08/2002: samjam (Sam Liddicott) - Many changes to php module. Shadow classes are now implemented - entirely in native C and no need for php-code shadow wrappers - Populated template config.m4 and Makefile.in as needed by - phpize are generated. - -05/08/2002: ljohnson (Lyle Johnson) - [Ruby] A copy constructor is now turned into a "clone" - instance method (see Dave's change for copy constructors - dated 4/7/2002). This seems like the appropriate thing - to do for Ruby code. - -05/08/2002: ljohnson (Lyle Johnson) - [Ruby] Fixed [ 553864 ] Inline destructor code not written. - -05/08/2002: beazley - %ignore behaves better with constructors, destructors, and the - type system in general. For constructors and destructors, - %ignore now suppresses the creation of a default constructor - or destructor. For example: - - %ignore ~Foo; - class Foo { - public: - Foo(); - ~Foo(); - ... - }; - - In SWIG-1.3.11, ~Foo() simply "disappeared" and the code generator - created a wrapper for a default destructor (as if it was never - declared in the interface). In SWIG-1.3.12, %ignore suppresses - the creation of a destructor if one is actually defined. - - Similarly, even though a declaration is ignored, information - may still be needed to properly handle types. For example, here - is a very subtle error that is fixed by this change: - - %ignore std::string; // Prevent class wrapping - namespace std { - class string { - ... - }; - %typemap(in) string * { - ... - } - } - - void foo(std::string *s); // Broken. - - Before this fix, %ignore would cause the class definition to disappear. - This, in turn, would cause the typemap to be misapplied. - -05/08/2002: beazley - Minor changes to %rename, %ignore, %feature, and related directives - for better support of destructors. Destructors can now be precisely - tagged. For example: - - %ignore Foo::~Foo; - %feature("action") ~Bar { - ... - } - - *Developer warning* - Operations such as renaming and feature attachment for classes used to - be applied to destructors as well. For instance, if you did this: - - %rename(Bar) Foo; - - The operation applied to the class itself, the constructor, and - the destructor. This is no longer the case. Now such operations - will only apply to the class and the constructor. Note: if you - were relying on this for class renaming, be aware that renamed - classes should really only be handled at the level of the class itself - and not the level of individual declarations in the class (although - they can be renamed individually if needed). As far as I know, - the Language class is already taking care of this case correctly. - -05/07/2002: beazley - New set of tests. The Examples/test-suite/errors directory contains - tests that try to exercise all of SWIG's error and warning messages. - -05/07/2002: beazley - Start of a warning framework. Warning messages are now assigned numeric values - that are shown in warning messages. These can be suppressed using the - -w option. For example: - - swig -w302 example.i - swig -w302,305 example.i - - Alternatively, the #pragma preprocessor directive can be used to disable this: - - #pragma SWIG nowarn=302 - #pragma SWIG nowarn=302,305 - - Note: Since SWIG is a multi-pass compiler, this pragma should - only be used to change global settings of the warning filter. It should - not be used to selectively enable/disable warnings in an interface file. - The handling of #pragma occurs in the C++ preprocoessor and affects all - subsequent stages of compilation. - - The -Wall option turns on all warnings and overrides any filters that - might have been set. - - Warnings can be issued from an interface using %warn. For example: - - %warn "110:%section is deprecated" - - The first part of a warning message is an optional warning number. - A complete set of warning numbers is found in Source/Include/swigwarn.h. - *** NEW FEATURE *** - -05/07/2002: beazley - Internal parsing change. Directives to include files now use brackets [ ... ] - instead of { ... }. - - %includefile "foo.i" [ - ... - ] - - The use of { ... } was a bad choice because they were included implicitly by - the preprocessor and made it impossible to properly detect legitimate missing '}' - errors. - -04/16/2002- -05/02/2002: beazley - SWIG European Tour: Paris-Amsterdam-Bath. - -04/23/2002: beazley - The %addmethods directive has been renamed to %extend. - For example: - - class Foo { - ... - }; - - %extend Foo { - int blah() { ... }; - int bar() { ... }; - ... - }; - - Motivation: the %addmethods directive can be used for many - other tasks including adding synthesized attributes, constructors, - and typemaps. Because of this, "addmethods" is somewhat misleading. - %extend more precisely describes this operation---extension of a - class or structure. - - *** POTENTIAL INCOMPATIBILITY *** - %addmethods still works via a macro definition. However, - a warning message may be generated. Errors involving %addmethods - will actually refer to the %extend directive. - -04/23/2002: beazley - Further refinement of the type system. Typedef now - propagates through functions, pointers to functions, - and pointers to member functions. - For example: - - typedef int Integer; - void foo(int (*x)(int), Integer (*y)(Integer)); - - In this case, arguments 'x' and 'y' have exactly - the same type (and would obviously accept objects - of either type). - - Similarly, consider this: - - class Foo { - }; - - typedef Foo Bar; - void bar(int (Foo::*x)(int), int (Bar::*y)(int)); - - In this case, arguments x and y are the same - type (via typedef). - -04/22/2002: beazley - SWIG now generates a warning message if any part of - an expression involves values from a private part of a class. - For example: - - class Foo { - private: - static int X; - public: - void blah(int a, int b = X); // Warning - }; - - In this case, the default argument is ignored. There - are workarounds, but they are rather clumsy. For instance, - you might do this: - - %feature("action") blah(int,int) { - if ($nargs == 1) { - result = blah(arg1); - } else { - result = blah(arg1,arg2); - } - } - void blah(int a, int b = 0); - - -04/21/2002: beazley - Use of the %inline directive inside a namespace is - forbidden and now generates an error message. This is - not allowed since the inlined code that is emitted is - not placed inside a namespace. This confuses other - stages of parsing. - -04/21/2002: beazley - Some bug fixes to casting operations and expression - parsing. Due to some parsing issues, it is not - currently possible to use casts for all possible - datatypes. However, the common cases work. - -04/20/2002: beazley (Amsterdam) - Member templates now work. Simply use the %template - directive inside a class or %addmethods to create - instantiations (see Doc/Manual/SWIGPlus.html). Supporting - this was easy---earlier changes to templates made it - possible using only a two-line modification to the parser - and a few minor modifications elsewhere. Hmmm, come to - think of it, the smoke was rather thick in that Internet "cafe". - *** NEW FEATURE *** - -04/19/2002: beazley (TGV) - Improved handling of non-type template parameters. For example: - - vector<int,100>; - - Simple numbers and strings can be used with the %template - directive as well. For example: - - %template(vecint100) vector<int,100>; - - Note: Arithmetic expressions are not currently allowed. - - Default template arguments now work and do not have to - be given to %template. - -04/18/2002: beazley (Paris) - Change in internal template handling. Template - parameters are now fully integrated into the type - system and are aware of typedefs, etc. This builds - upon the change below. - - *** DEVELOPER WARNING *** - Word of caution to language module writers. The "name" - parameter of certain parse tree nodes (classes, functions, etc.) - may be parameterized with types. This parameterization is - done using SWIG type-strings and not the underlying C version. - For example, - - int max<int *>(int *,int *) - - has a name of "max<(p.int)>". If you use the name directly, - you may get syntax errors in the generated code. To fix this, - use SwigType_namestr(name) to convert a parameterized name - to a C name with valid syntax. The internal version is - used to reduce template types to a common representation - and to handle issues of typedef. - -04/16/2002: beazley (somewhere over the Atlantic) - Enhancement of typedef resolution. The type system is now - aware of template arguments and typedef. For example: - - typedef int Integer; - - foo(vector<int> *x, vector<Integer> *y); - - In this case, vector<int> and vector<Integer> are - the same type. There is some interaction between this - mechanism and the implementation of typemaps. For example, - a typemap defined for vector<int> * would apply to either type. - However, a typemap for vector<Integer> * would only apply to - that type. - - Typedefs and typemaps and matched by left-most expansion. - For example: - - vector<Integer,Integer> --> - vector<int, Integer> --> - vector<int, int> - - -04/24/2002: cheetah (William Fulton) - [Java] Changes to Java shadow classes. - Overcomes a bug where the module assumed that a pointer to a derived - class could be used in place of a pointer to a base class. Thanks - to Stephen McCaul for analysing the bug and submitting patches. - - A consequence is that the getCPtr() method in each shadow class has - disappeared and has been replaced with a getCPtrXXX(), where XXX is the - shadow class name. If you have code that previously used getCPtr(), - and the associated class is wrapping a C struct or a C++ class that - is not involved in an inheritance chain, just use the new method. If - however, the class is involved in an inheritance chain, you'll have - to choose which pointer you really want. Backwards compatibility - has been broken as not using the correct pointer can lead to weird bugs - through ill-defined behaviour. If you are sure you want the old methods, - you could add them back into all shadow classes by adding this at the - beginning of your interface file: - - %pragma(java) allshadowcode=%{ - public long getCPtr(){ - return swigCPtr; - } - %} - - Please see entry dated 07/23/2002 to see how to do this after the deprecation - of the allshadowcode pragma. - - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -04/13/2002: beazley - Fixed problem with default arguments and references. Declarations such - as this should now work: - - void foo(const string &x = "Hello"); - -04/12/2002: beazley - Added typemap $* substitutions for typemaps involving arrays. - Requested by William Fulton. - -04/11/2002: beazley - Template specialization is now supported. For example: - - template<> class vector<int> { - ... - }; - - When the %template directive is used, it will use a specialization - if one is defined. There are still some limitations. Partial - specialization is not supported. A template of type <void *> does - not match all pointers. - *** NEW FEATURE *** - -04/11/2002: beazley - Major change to template wrapping internals. Template declarations are - no longer processed as macros but now result in real parse-tree - nodes. The %template directive expands these nodes into a - specific instantiation. This change enables a number of - new and interesting capabilities: - - Directives such as %rename, %feature, and %addmethods can - now be applied to uninstantiated templates. For example: - - %rename(barsize) vector::bar(char *buf, int len); - ... - template<typename T> class vector { - public: - ... - void bar(char *buf); - void bar(char *buf, int len); // Renamed - ... - }; - - %template(intvector) vector<int>; // Renaming carries through - - - By parsing templates into an internal data structure, it will - be possible to support specialization (and maybe partial - specialization). - - This is highly experimental and a work in progress. - - *** POTENTIAL INCOMPATIBILITY *** - In SWIG-1.3.11, template declarations were simply processed - as weird macros. No other information was retained. This - made it impossible to support more advanced features and - complicated many other parts of the implementation. - -04/09/2002: beazley - Change to template class wrapping. There were a variety of - "issues" with the old approach related to parsing, the type - system, and namespaces. These changes are meant to rectify - some of these problems: - - A specific instantiation of a template can now be specified - by including the class inline like this: - - class vector<int> { - public: - vector(); - ~vector(); - ... whatever ... - }; - - This is template specialization, but partial specialization is - not yet implemented. - - The %template directive has been modified to expand roughly as - follows: - - %template(vecint) vector<int>; - - becomes - - %rename(vecint> vector<int>; - class vector<int> { - public: - vector(); - ... - }; - - Note that this simply builds upon the code above (templates - included inline). - - This modified approach to wrapping fixes some subtle type - issues. For instance, you can now define typemaps and typedefs - like this: - - %typemap(in) vector<int> * { - ... - } - typedef vector<int> intvector; - ... - void blah(intvector *v); // Gets the above typemap - - This did not work in SWIG-1.3.11 due to a peculiarity of - the template implementation. - - %template(name) no longer installs the template as a class - with name "name". This might break %addmethods as described - in the manual. For example: - - %template(vecint) vector<int>; - %addmethods vecint { // Fails. vecint not a class - ... - }; - - To fix this, just use the template name instead: - - %addmethods vector<int> { - ... - } - - Note: This technique might be a way to implement some bizarre - template specialization techniques. For example: - - %addmethods vector<int> { - // Only applied if vector<int> instantiated later - %typemap(in) vector<int> * { - ... - } - ... - }; - - *** POTENTIAL INCOMPATIBILITY *** - -04/08/2002: beazley - Fixed [ 540868 ] #if defined whatever - not parsed. SWIG should - now correctly handle preprocessor directives like this: - - #if defined __cplusplus - ... - #endif - - Note: was implemented previously, but there was a minor bug. - Reported by Adam Hupp. - -04/07/2002: beazley - %readonly and %readwrite are deprecated due to a change in the - implementation. Instead of being pragmas, mutability is now - controlled as a "feature" using the following two directives: - - %immutable; - int x; // read-only variable - int y; // read-only variable - %mutable; - int z; // Modifiable - - %immutable and %mutable are much more powerful than their older - counterparts. They can now pinpoint a specific declaration like - this: - - %immutable x; /* Any x */ - %immutable Foo::x; /* x in class Foo */ - - In fact, the matching algorithm is the same as for %rename, - %ignore, and other directives. This means that the declaration - - %immutable Foo::x; - - would not only apply to class Foo but to all derived classes - as well. - - *** POTENTIAL INCOMPATIBILITY *** - %immutable and %mutable must be terminated by a semi-colon. This - differs slightly from the older %readonly and %readwrite directives. - Since %immutable and %mutable can be applied to declarations the - semicolon is needed to distinguish between a global feature and - one targeted to a single declaration. Note: this incompatibility is the - primary reason for changing the name of the directive. - -04/07/2002: beazley - New handling of copy constructors. If a class defines - constructors like this: - - class Foo { - public: - Foo(); - Foo(const Foo &); // Copy constructor - ... - }; - - SWIG now generates a function copy_Foo() for the copy - constructor. - - In previous verions, this generated a name-clash and an - error message. To preserve backwards compatibility, SWIG - does not change the behavior if %rename is used to resolve - the name conflict. However, if no name resolution is made, - this new approach is used. - - Copy constructors may be handled as a special case in the - target language. However, this is up to the language module - itself. - -04/07/2002: beazley - The %template directive is now namespace aware. This allows - code like this: - - namespace foo { - template<typename T> max(T a, T b) { return a > b ? a : b; } - } - - using namespace foo; - %template(maxint) max<int>; // Ok - - namespace bar { - using foo::max; - %template(maxdouble) max<double>; // Ok - } - - Caveat: the template name supplied to %template must be defined in the - same scope in which the %template directive appears. This code is - illegal: - - %template(maxint) foo::max<int>; - -04/07/2002: beazley - Minor enhancement to preprocessor. The preprocessor can now perform - string comparison. For example: - - #define A "hello" - ... - #if A == "hello" - ... - #endif - - The primary use of this is in SWIG macros. For example: - - %define FOO(x) - #if #x == "int" - /* Special handling for int */ - ... - #endif - %enddef - - Normal users can probably safely ignore this feature. However, it may - be used in parts of the SWIG library. - -04/07/2002: beazley - Further refinement of default constructor/destructor wrapper generation. - SWIG is now much more aware of pure virtual methods. For instance: - - class A { /* Abstract */ - public: - virtual void method1() = 0; - virtual void method2() = 0; - }; - class B : public A { /* Abstract */ - public: - virtual void method1() { }; - }; - - class C : public B { /* Ok */ - public: - virtual void method2() { }; - }; - - In this case, SWIG will only generate default constructors for C. - Even though B looks fine, it's missing a required method and is abstract. - -04/04/2002: beazley - Subtle change to structure data member access. If you - have a structure like this: - - struct Foo { - Bar b; - }; - - The accessor functions for b are generated as follows: - - (1) If b is *not* defined as a structure or class: - - Bar Foo_b_get(Foo *self) { - return self->b; - } - void Foo_b_set(Foo *self, Bar value) { - self->b = value; - } - - (2) If b *is* defined as a structure or class: - - Bar *Foo_b_get(Foo *self) { - return &self->b; - } - void Foo_b_set(Foo *self, Bar *value) { - self->b = *value; - } - See the "Structure data members" section of Doc/Manual/SWIG.html - for further details. - - *** POTENTIAL INCOMPATIBILITY *** - This may break interfaces that relied on a lot of a undeclared - structure and class names. To get the old behavior, simply - use a forward declaration such as "struct Bar;" - -04/04/2002: beazley - C++ namespace support added. SWIG supports all aspects of - namespaces including namespace, using, and namespace alias - declarations. The default behavior of SWIG is to flatten - namespaces in the target language. However, namespaces are - fully supported at the C++ level and in the type system. - See Doc/Manual/SWIGPlus.html for details on the implementation. - -04/02/2002: cheetah (William Fulton) - [Java] Sun has modified javac in jdk1.4 to no longer compile - an import of an unnamed namespace. To fix this SWIG no longer - generates the import for packageless classes. - http://developer.java.sun.com/developer/bugParade/bugs/4361575.html - As reported SF #538415. - -03/27/2002: ljohnson (Lyle Johnson) - [Ruby] Added support for pointer-to-member, similar to that - for the Python module. Remarkably similar. Also added a new - example for this (Examples/ruby/mpointer), which is remarkably - similar to the Python example of the same name. - -03/26/2002: ljohnson (Lyle Johnson) - [Ruby] Made a few minor edits to the "Advanced Topics" - chapter of the SWIG manual and added a new major section - about how to create multi-module Ruby packages with SWIG. - -03/26/2002: ljohnson (Lyle Johnson) - [Ruby] Removed all of the old Ruby pragmas. If any of this - functionality is truly missed we can resurrect it, preferably - with some kind of feature-based directive. - -03/25/2002: ljohnson (Lyle Johnson) - [Ruby] Fixed SWIG exception library support for Ruby, which - has apparently been broken for some time. Luckily, no one seems - to have noticed. - -03/23/2002: beazley - C++-namespace support in SWIG directives. - - %addmethods: - - The %addmethods directive now accepts a fully qualified classname - and can be used inside C++ namespace declarations. For example: - - // Attaches to the class Foo::Bar below - %addmethods Foo::Bar { - int somemethod() { ... } - }; - - namespace Foo { - class Bar { - public: - ... - }; - - // Attaches to the class Bar above - %addmethods Bar { - int othermethod() { ... }; - } - } - - %feature, %rename, %ignore, %exception, and related directives: - - Namespaces are fully integrated into the renaming and declaration - matcher. For example: - - %rename(display) Foo::print; // Rename in namespace Foo - %ignore Foo::Bar::blah; // Ignore a declaration - - %rename directives can be placed inside namespace blocks as well. For - example: - - namespace Foo { - %rename(display) print; // Applies to print below - - void print(); - }; - - Most other SWIG directives should work properly inside namespaces. - No other changes are needed. - -03/22/2002: beazley - Some changes to internal symbol table handling. SWIG no longer - manages structures and unions in a separate namespace than normal - declarations like ANSI C. This means you can't have a structure - with the same name as a function. For example: - - struct Foo { - ... - } - - int Foo() { ... } - - This approach is more like C++. It's not clear that SWIG ever - really supported the ANSI C anyways---using the same name would - almost certainly generate a name-clash in the target language. - -03/22/2002: ljohnson (Lyle Johnson) - [Ruby] Fixed [ 517302 ] for handling of renamed overloaded - constructors. Now, renamed overloaded constructors are converted - into class singleton methods (basically acting as "factory" - methods). - -03/21/2002: beazley - Fixed [ 532957 ] %ignore parse error and casting operator. - Reported by William Fulton. - -03/18/2002: beazley (** ADVANCED USERS ONLY **) - Added support for dynamic casting in return values. A somewhat - common problem in certain C++ programs is functions that hide - the identity of underlying objects when they are returned - from methods and functions. For example, a program might include - some generic method like this: - - Node *getNode(); - - However, Node * may just be base class to a whole hierarchy - of different objects. Instead of returning this generic Node *, - it might be nice to automatically downcast the object into the - appropriate type using some kind dynamic cast. - - Assuming you understand the peril involved, a downcast can now - be performed using the following function in the run-time type - checker: - - swig_type_info *SWIG_TypeDynamicCast(swig_type_info *, void **ptr); - - This function checks to see if the type can be converted to another - type. If so, a different type descriptor (for the converted type) - is returned. This type descriptor would then be used to create - a pointer in the target language. - - To use this, you would write a typemap similar to this: - - %typemap(out) Node * { - swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); - $result = SWIG_NewPointerObj($1, ty); - } - - Alternatively, - - %typemap(out) Node * = SWIGTYPE *DYNAMIC; - - To make the typemap have any effect, you have to write a supporting - function that knows how to perform downcasting. For example: - - %{ - static swig_type_info * - Node_dynamic_cast(void **ptr) { - Node **nptr = (Node **) ptr; - Element *e = dynamic_cast<Element *>(*nptr); - if (e) { - *ptr = (void *) e; - return SWIGTYPE_p_Element; - } - Data *d = dynamic_cast<Data *>(*nptr); - if (d) { - *ptr = (void *) d; - return SWIGTYPE_p_Data; - } - return 0; - } - %} - - There is no restriction on how types are determined. dynamic_cast<> - uses C++ RTTI. However, if you had some other mechanism for determining - the type, you could use that here. Note: it is important to save - the new pointer value back into the argument as shown. When downcasting, - the value of the pointer could change. - - Finally, to make the casting function available, you have to register - it with the run-time type checker. Put this macro in your interface file. - - DYNAMIC_CAST(SWIGTYPE_p_Node, Node_dynamic_cast); - - Note: this feature does not introduce a performance penalty on - normal SWIG operation. The feature is only enabled by writing - a new typemap that explicitly calls SWIG_TypeDynamicCast() to - make a conversion. - - Examples/test-suite/dynamic_cast.i contains a simple example. - This feature is not supported in the Java module due to differences - in the type-checking implementation. - - *** EXPERIMENTAL FEATURE *** - -03/17/2002: beazley - Small change to type-name handling of unnamed structures and - typedef. If a structure of this form appears: - - typedef struct { - ... - } Foo; - - Then 'Foo' is used as the proper typename for the structure. - Furthermore, Foo can now be used as a name in C++ inheritance. - SWIG was already kind of doing this, but this modification refines - the implementation to more closely follow the C++ ARM, section - 7.1.3, p. 106. This fixes a couple of obscure corner cases. - -03/16/2002: beazley - Modified C++ inheritance with a few enhancements. First, type information - needed for casting and type-equivalence is generated even when base-classes - aren't defined in the interface. For example: - - class Foo : public Bar { /* Bar unspecified */ - public: - ... - }; - - void blah(Bar *b); - - In this case, the blah() function still accepts Foo * even though nothing - is really known about Bar. Previous SWIG versions would just generate - a type error. - - Inheritance has also been modified to work through typedef. For example: - - class Bar { - }; - - typedef Bar OtherBar; - class Foo: public OtherBar { - } - - In this case, the base class of OtherBar is correctly resolved back to - Bar. The use of the name OtherBar is lost in this resolution (the wrappers - will simply use Bar instead of the typedef name OtherBar). - -03/13/2002: beazley - %typemap, %apply, and related directives can now appear inside - class definitions. - -03/13/2002: beazley - Fixed a variety of problems related to compiling SWIG on 64-bit - platforms. - -03/12/2002: beazley - Fixed problem with "ignore" and "in" typemaps. Local variables - associated with "in" were being added to the wrapper function even - though they were never used. Mostly harmless, but it would lead - to a variety of compilation warnings. - -03/12/2002: beazley - Some changes to the internal type system and handling of nested C++ - types. In previous versions of SWIG, if you had the following: - - class Foo { - public: - typedef int Blah; - }; - class Bar : public Foo { - public: - void somemethod(Blah x); - }; - - The argument type in somemethod() would implicitly be set to Bar::Blah. - Although this is technically allowed, it breaks typemaps. For example: - - %typemap(in) Foo::Blah { ... } - - doesn't match like you expect. This has been changed in SWIG-1.3.12. - Now, types are expanded using the class in which they were defined. - So, the argument type in somemethod() will be Foo::Blah---since the - type Blah was defined in Foo. - -03/10/2002: beazley - Fixed some subtle type scoping problems with typedef and C++ classes. - For example: - - typedef int Blah; - class Bar { - public: - typedef double Blah; - void foo(Blah x, ::Blah y); - ... - } - -03/10/2002: beazley - Highly experimental change to handle variable length arguments. - First, there is no portable or reliable way to wrap - a varargs function in full generality. However, you *can* change - the function signature using %varargs. - - %varargs(char *) fprintf; - ... - void fprintf(FILE *f, char *fmt, ...); - - In this case, the variable length parameter "..." is - simply replaced by the parameters given in %varargs. This - results in a function like this: - - void fprintf(FILE *f, char *fmt, char *s); - - More than one argument can be used and default values - can be defined. For example, this code specifies a - maximum of four arguments. - - %varargs(char *x1 = 0, char *x2 = 0, char *x3 = 0, char *x4 = 0) fprintf; - - *** EXPERIMENTAL NEW FEATURE *** - -03/10/2002: beazley - Change to handling of variable length arguments. varargs - is now handled as a proper parameter and is passed to the - code generator. However, it still can't be handled correctly - (and will generate a typemap warning). This change has been - made to better incorporate variable length arguments with other - directives such as %ignore, %rename, %feature, and so forth. - -03/10/2002: beazley - Fixed [ 522555 ] Syntax error parsing "define" construct. SWIG - is a little more restrictive in determining #define statements - that will be wrapped as constants. Also added a better parser - error rule for handling bad constants. - -03/08/2002: cheetah (William Fulton) - [Java] Bug fix: Classes renamed with %rename that are derived from - another class generate more appropriate shadow class code. - -03/08/2002: cheetah (William Fulton) - [Java] Fixed SF [ #523632 ] and [ #513335 ] both reported by Israel - Tanner. Support for types that are used which are in a typedef. The - appropriate shadow class name is generated. Also generated correct - shadow classname when a templated class is used within another - templated class. See the cpp_typedef.i testcase. - -03/08/2002: cheetah (William Fulton) - [Java] Bug fix: No type was generated in shadow classes for types - that weren't wrapped by SWIG. The type is treated as a raw - pointer, ie no shadow class. - -02/22/2002: beazley - Refined the matching algorithm used by %rename, %ignore, and - %feature. If a type signature is supplied, it must exactly - match that used in the declaration---including any use of - const. For example: - - %rename(foo1) foo(int); - %rename(bar1) bar(int) const; - - class Blah { - public: - void foo(int); // Matched --> foo1 - void foo(int) const; // Not matched - void bar(int); // Not matched - void bar(int) const; // Matched --> bar1 - } - - In previous versions, a non-const specification would match - both the non-const and const declarations. However, the whole - point of %rename and related directives is that they be able - to precisely pinpoint exact declarations in an interface. This - fixes the problem. - -02/21/2002: beazley - Reworked the handling of default constructor and destructors. - SWIG now makes a preliminary pass over the parse tree to discover - which classes support default allocation. This fixes a number - of very subtle issues in code generation and call/return by value. - -02/18/2002: cheetah (William Fulton) - Improved support on Cygwin: Perl, Python, Tcl, Ruby and Java should - work out of the box, barring the runtime library. Removed dllwrap - and replaced with newly working gcc -shared instead for Cygwin. - All this will require the new improved binutils 20010802 and later, - but the latest Cygwin is usually the best recommendation. - -02/15/2002: beazley - Fixed some problems related to wrapping of global variables - and Perl shadow classes. Reported by Chia-liang Kao. - -02/15/2002: ljohnson (Lyle Johnson) - [Ruby] Made a fix to the code generation for C++ class - constructors so that we get both a "new" singleton method - and an "initialize" instance method for each class. This - change enables developers to derive new Ruby classes from - SWIG-wrapped C++ classes and then override their initialize - methods to provide subclass-specific instance initialization. - -02/15/2002: ljohnson (Lyle Johnson) - [Ruby] Massive documentation update for the Ruby module, - contributed by Craig Files. - -02/14/2002: ljohnson (Lyle Johnson) - [Ruby] Bug fix: An error in the SWIG runtime support for Ruby - was causing several of the examples to fail. Reported by - William Fulton. - -02/14/2002: ljohnson (Lyle Johnson) - [Ruby] Bug fix: Enumerations defined within a class (such - as those seen in the Examples/ruby/enum example) were not - being exported with the correct names. Reported by William - Fulton. - -02/13/2002: ljohnson (Lyle Johnson) - [Ruby] Added a warning message when we run across overloaded - class constructors for C++ code, that this is currently not - supported (even if the overloads have been %renamed). For an - example of where this doesn't work, see Examples/ruby/operator. - -02/13/2002: ljohnson (Lyle Johnson) - [Ruby] Added an "ignored" warning message when the parser runs - across an operator!=() declaration for C++ code. - -02/11/2002: ljohnson (Lyle Johnson) - [Ruby] Added the "import", "import_template", "operator" and - "template" examples. - -02/11/2002: ljohnson (Lyle Johnson) - [Ruby] Added multi-module support. - -02/09/2002: ljohnson (Lyle Johnson) - [Ruby] Added the missing "#define SWIG_NOINCLUDE" at the top of - the wrapper code when the '-c' option is used. - -02/09/2002: ljohnson (Lyle Johnson) - Corrected a minor off-by-one error for the size of the - swig_types[] array that's generated in the wrapper code. - -02/08/2002: beazley - Fixed SF [ #515058 ] Wrong code for C++ templates. - Reported by Israel Taller. - -Version 1.3.11 (January 31, 2002) -================================= - -01/30/2002: beazley - Fix to pass/return by value for C++ objects that define - no default constructor. Changes to the typemap system - made it impossible to wrap C++ objects with no default - constructor. This has been fixed, but the solution - involves some clever template magic contributed by - William Fulton. Please see the comments in the file - Lib/swig.swg for further details. This solution is - experimental and may be refined in a future release. - -01/30/2002: beazley - Global variables and member data of type "const char *" - can be set, but the old value is silently discarded without - any garbage collection. This may generate a memory leak. - This change is needed to more safely handle variables - like this: - - const char *foo = "Hello World\n"; - - In this case, it's not safe to free the old value. However, - SWIG can dynamically allocate a new value and make foo point - to it. To fix this memory leak, you can probably do this: - - %clear const char *foo; - %apply char * {const char *foo}; - - *** POTENTIAL INCOMPATIBILITY *** - -01/30/2002: beazley - Two minor typemap enhancements have been added. First, - typemaps can issue a warning message by including a special - warning attribute. For example: - - %typemap(in,warning="I'm going to do something dangerous") ... - - The warning message will show up whenever the typemap is - applied. - - Second, a typemap can force a no-match by defining - - %typemap(in) sometype "pass" - - If this is used, the typemap system will *not* record a - typemap match for "sometype". This can be used to block - selected typemaps. For example, if you wanted to disable - a typemap feature for some type, you could do this. - - // Do not allow global variables of type 'const char *' to be set. - %typemap(varin) const char * "pass" - - It might also be possible to use this to do subtle and - strange things with typemaps. For example, if you wanted to - make 'blah *' an output value and 'const blah *' an input - parameter, you might do this: - - %typemap(ignore) blah *(blah temp) { - $1 = &temp; - } - %typemap(argout) blah * { - ... return a value ... - } - /* Block unqualified typemaps defined above */ - %typemap(ignore) const blah * "pass" - %typemap(argout) const blah * "pass" - %typemap(in) const blah * { - ... get input value ... - } - - (This potential applications of typemaps suggested by Greg Stein). - *** NEW FEATURE *** - -01/29/2002: cheetah (william fulton) - [Java] Bug fix: No enumerations were wrapped when the -shadow - commandline option was not specified. Reported by Israel Taller. - -01/28/2002: cheetah (william fulton) - [Java] Global arrays are successfully wrapped. In fact they started - mostly working in SWIG-1.3.10. - -01/28/2002:richardp - Added first attempt at C++ and -shadow support for PHP4 module, - please test and mail me if any problems/ideas on improving it. - - There is a known problem with uninitialized member variables, - please see Examples/php4/sync/README for details. - - Also more PHP documentation added to Doc/Manual/Php.html - -01/27/2002:beazley - The ANSI C size_t type is now recognized as an integer by default. - -01/26/2002:beazley - long long and unsigned long long support added to many language modules. - This is not a portable feature and will require compiler support - for the long long type. In target languages that do not support - long long (e.g., Tcl and Perl), numbers are converted to a string - of digits. This prevents their use in arithmetic calculations, but - still allows values to be set from a string. - - long long support requires the use of the strtoll() and strtoull() - functions as well as the 'lld' and 'llu' format specifiers - of sprintf(). - -01/26/2002:beazley - Fixed [ #501827 ] Delete method is not called. The Tcl - module wasn't correctly calling destructors when they - were defined using %addmethods. This has been fixed. - Reported by Reinhard Fobbe. - -01/26/2002: beazley - Better support for long long and unsigned long long. Typemaps - have been included in a number of modules for handling these types. - In addition, the parser has been modified to accept long long - literals such as 1234LL and 1234ULL. - -01/27/2002: cheetah (william fulton) - [Java] A C char[] is mapped to a Java String which is the default - SWIG handling of char[] and char*. It used to be mapped to byte[]. - Note that a C signed char[] array is mapped to byte[]. - - *** POTENTIAL INCOMPATIBILITY *** - -01/25/2002: beazley - Fixed a problem with return-by-value, C++, and - objects that define no default constructor. - Reported by Joel Reed. - -01/25/2002: cheetah (william fulton) - [Java] Overhaul of the Java module. The C code generation is now - done from typemaps. - -01/24/2002: cheetah (william fulton) - [Java] Support for arrays of enum pointers - -01/20/2002: cheetah (william fulton) - [Java] Error checking for null Java objects being passed to native - functions. Exception thrown now whereas before the JVM crashed. - -01/18/2002: cheetah (william fulton) - [Java] Corrected behaviour for functions that take arrays. For - example, when this c function: - - void arrayfn(int array[]); - - is wrapped the corresponding native function - - public final static native void arrayfn(int[] array); - - is produced. Previously if the C function made any changes to the - array elements, these were not reflected back into the Java array. - This has now been corrected so that the changes are propogated back - to Java and the calling function will see these changes. This is - how pure Java functions work, ie arrays are passed by reference. - -01/15/2002:mkoeppe - [Guile] New file cplusplus.i with C++ typemaps contributed - by Marcio Luis Teixeira <marciot@holly.colostate.edu>. - -01/11/2002: cheetah (william fulton) - [Java] Changed mapping of C long to Java type. Was mapped to Java - long, now mapped to Java int. If you want the previous mapping to - Java long use this approach in your interface file: - - %clear long; - %typemap(jni) long "jlong" - %typemap(jtype) long "long" - %typemap(jstype) long "long" - - %clear long[ANY]; - %typemap(jni) long[ANY] "jlongArray" - %typemap(jtype) long[ANY] "long[]" - %typemap(jstype) long[ANY] "long[]" - %typemap(in) long[ANY] {write me for array support} - %typemap(out) long[ANY] {write me for array support} - %typemap(argout) long[ANY] {write me for array support} - %typemap(freearg) long[ANY] {write me for array support} - - *** POTENTIAL INCOMPATIBILITY *** - - This new mapping is more appropriate when interfacing to 32 bit - applications which are used in the current 32-bit JVMs. For future - 64-bit JVMs you may have to change these mappings - eg on Unix LP64 - systems, but not on Microsoft 64bit Windows which will be using a - P64 IL32 model. This may be automated in a future version of SWIG. - -01/10/2002:beazley - Fixed [ 501677 ] %init block in wrong place. Reported - by Luigi Ballabio. - -01/09/2002: cheetah (william fulton) - [Java] Default support for the long long type. signed long long is - mapped to a Java long. unsigned long long is mapped to BigInteger. - -01/09/2002:beazley - Experimental change to parser to better support mixing of - int, long, short, unsigned, float, and double. The parser - should now support types like this: - - short unsigned int - int unsigned short - unsigned short int - unsigned int short - - This change also enables a type of 'long double' (previously - unsupported) to be used. - *** NEW FEATURE *** - -01/05/2002: cheetah (william fulton) - [Java] Casting fix for when function return type is a pointer as - reported by Gary Pennington 2002-01-05. The upper 32bits of the - 64 bit jlong will have contained junk for 32bit pointers. - -01/05/2002: cheetah (william fulton) - [Java] Better pointer handling in Java is possible as the - INPUT, OUTPUT and INOUT typemaps have been added into typemaps.i. - -01/05/2002: cheetah (william fulton) - [Java] $null can be used in input typemaps to return early from JNI - functions that have either void or a non-void return type. Example: - - %typemap(check) int * %{ - if (error) { - SWIG_exception(SWIG_IndexError, "Array element error"); - return $null; - } - %} - - If the typemap gets put into a function with void as return, $null - will expand to nothing: - - void jni_fn(...) { - if (error) { - SWIG_exception(SWIG_IndexError, "Array element error"); - return ; - } - ... - } - - otherwise $null expands to zero, where javareturntype is either a - pointer or a primitive type: - - javareturntype jni_fn(...) { - if (error) { - SWIG_exception(SWIG_IndexError, "Array element error"); - return 0; - } - ... - } - -01/02/2002: cheetah (william fulton) - [Java] The Java module incorrectly used argout typemaps for - strings. This is now corrected and the code now resides - in the freearg typemap. The argout array typemaps have been split into - argout and freearg typemaps. This correction may require some user - written typemaps to be modified. - *** POTENTIAL INCOMPATIBILITY *** - -12/28/2001: cheetah (william fulton) - [Java] Multi typemaps now working for Java see multimap example. - [Java] Fix for recently introduced bug - freearg typemap code was appearing - before the function call. - -12/28/2001: cheetah (william fulton) - [Java] JCALL macro for JNI calls that work in both C and C++ typemaps - have been replaced with JCALL0, JCALL1, JCALL2, JCALL3 and JCALL4 - macros. - *** POTENTIAL INCOMPATIBILITY *** - -12/22/2001:beazley - Resolved some inconsistent behavior with %rename and class renaming. - If you specify the following: - - %rename(Foo) Bar; - - class Bar { - public: - Bar(); - ~Bar(); - } - - Then the %rename directive applies to the class itself, the constructor, - and the destructor (all will be renamed to Foo). - - If a class defines more than one constructor, the overloaded variants - can still be renamed by specifying parameters to %rename. For example: - - %rename(Bar_copy) Bar(Bar &); - class Bar { - public: - Bar(); - Bar(Bar &); - ~Bar(); - }; - - There are still some odd corner cases. If you specify - - %rename(Foo) ::Bar; - - then only the name of the class is changed and the constructor/destructor - names are left unmodified. If you specify - - %rename(Foo) *::Bar; - - then the names of the constructor/destructor functions are modified but - the name of the class is not. - -12/21/2001: cheetah (william fulton) - [Java] jni, jtype and jstype typemaps no longer hardcoded but real - typemaps. New variable substitution, $javaclassname, can be used in - the jstype typemaps. It is replaced with the Java shadow class name - where applicable. - [Java] Fix for recently introduced bug to do with inheritance when - using %import. - [Java] A few more bug fixes, todo with %rename and using the kind - with the type, eg - void fn(union uni myuni, struct str mystr, class cl mycl); - -12/20/2001:beazley - Fixed [ #494524 ] Preprocessor bug - apostrophe and #subst. - -12/20/2001:beazley - Added SWIG_VERSION preprocessor symbol. This is a hexadecimal - integer such as 0x010311 (corresponding to SWIG-1.3.11). This can - be used in the interface as follows: - - #if SWIG_VERSION >= 0x010311 - /* Use some fancy new feature */ - #endif - - Note: The version symbol is not defined in the generated SWIG - wrapper file. - - *** NEW FEATURE *** - -12/20/2001:mkoeppe - [MzScheme]: Renamed mzswig_make_boolean to - swig_make_boolean, as the latter is used in the typemaps. - Reported by Luigi Ballabio. - -12/17/2001:mkoeppe - [Guile]: Rewrote list-vector.i using multi-dispatch - typemaps. Updated pointer-in-out.i. Make the - deprecated typemap-substitution of "$source" in "argout" - work as before. - -12/16/2001:mkoeppe - [Guile]: Fixed macros %values_as_list, %values_as_vector, - %multiple_values to use the proper %pragma syntax. New - Guile example/test "multivalue"; new Guile run-test for - test-suite item "list-vector" (currently broken). - -12/14/2001:mkoeppe - [Guile]: Fixed typemap-substition bug for "varin". Relaxed - valid-identifier check to allow all R5RS identifiers. - - -Version 1.3.10 (December 10, 2001) -================================== - -12/08/2001:beazley - Modified %typemap so that %{ ... %} can also be used as a - code block (mostly for completeness). For example: - - %typemap(in) blah %{ - ... - %} - - This form does not introduce a new block scope. Also, the - code enclosed in %{ ... %} is not processed by the preprocessor. - -12/08/2001:beazley - Fixed [ #459614 ] SWIG with multiple TCL interpreters. - -12/08/2001:beazley - Fixed [ #417141 ] rubydec.swg is wrong - Reported by Paul Brannan. - -12/08/2001:beazley - Fixed [ #410557 ] Problem with %addmethods on NT. - Reported by Magnus Ljung. - -12/08/2001:beazley - Fixed [ #445233 ] Enhancement: handle access change. - SWIG now parses (but ignores) C++ access changes for the - the following: - - class A { - protected: - void something() { } - public: - A() {} - }; - - class B : private A { - public: - B() : A() { } - protected: - A::something; <---- Parsed, but ignored - }; - - Suggested by Krzysztof Kozminski. - -12/08/2001: cheetah (william fulton) - Fix for Ruby to work using Visual C++. - -12/06/2001:beazley - Fixed [ #465687 ] unsigned short parameters fail. - Reported by Gerald Williams. - -12/06/2001:beazley - Fixed SF [ #489594 ] PyString_FromString can't take NULL arg. - Reported by John Merritt. SWIG now converts string values - to Python using code like this: - - resultobj = result ? PyString_FromString(result) : Py_BuildValue(""); - -12/06/2001:beazley - Fixed SF [ #463561 ] Type conversions not generated. - Reported by Gerald Williams. - -12/04/2001:beazley - Fixed SF [ #470217 ] Tcl default argument handling. - Reported by Shaun Lowry. - -12/04/2001:beazley - Fixed SF [ #472088 ] defined(MACRO) expanded everywhere. - Embedded preprocessor directives such as - - %#if defined(FOO) - - are not expanded by the SWIG preprocessor. - Reported by Gerald Williams. - -12/04/2001:beazley - Fixed SF [ #476467 ] Problems with #define & commas. - -12/04/2001:beazley - Fixed SF [ #477547 ] wrong declaration of pointer functions. - Bad prototypes in Lib/tcl/ptrlang.i. - -12/04/2001:beazley - Fixed SF [ #483182 ] Constants can take args by mistake. - When swig -perl5 -const is used, constants are declared - with a void prototype. For example: - - sub ICONST () { $examplec::ICONST } - - Patch submitted by Rich Wales. - -12/03/2001:beazley - New %exception directive. This is intended to replace %except. - It works in exactly the same manner except it does not accept a - language specifier. For example: - - %exception { - try { - $action - } - catch(SomeError) { - error - } - } - - %exception is also name aware---allowing it to be applied to - specific declarations in an interface. For example: - - %exception foo { - ... - exception for any function/method foo - ... - } - - %exception Foo::bar { - ... - exception for method bar in class Foo - ... - } - - %exception Foo::bar(double) { - ... - exception for method bar(double) in class Foo - ... - } - - The semantics of this name matching is exactly the same as for %rename. - *** NEW FEATURE *** - -12/03/2001:beazley - Substantial cleanup of the Python shadow class code. Shadow classes - used to be created in this rather complicated manner involving about - a half-dozen strings created in bits and pieces. Shadow classes - are now generated in a more straightforward manner--in the same - order that appears in the interface file. - - *** POTENTIAL INCOMPATIBILITY *** - The order in which declarations appear in the shadow file may differ. - -12/03/2001:beazley - The %insert directive (%{ ... %}, %runtime, %header, %wrapper, etc.) - can now be used inside of a class definition. This has potential - uses when generating shadow class code. For example: - - class Foo { - ... - %insert("shadow") %{ - # Some python code - def blah(self): - print "I'm blah!" - %} - ... - }; - - The support for class code insertion depends on the language module. - However, the intent of this feature is to simplify the task of extending - shadow class code. In the Python module, this inserts code with the - proper level of indendation (regardless of what was used in the SWIG - interface). - *** NEW FEATURE *** - -11/29/2001: cheetah (william fulton) - Modifications for Java and Python modules to work on cygwin. - Unfortunately a lot of the python module has started to produces code - which cannot be auto-imported using cygwin libtools so most of it is - still broken. - -11/28/2001:beazley - The %rename and %feature directive can now be used inside - of a class definition. For example: - - class Foo { - %rename(foo_i) foo(int); - %rename(foo_d) foo(double); - public: - ... - void foo(int); - void foo(double); - ... - }; - - When used in this manner, the %rename directive only applies - to members of the class in which it appears as well as all - derived classes. In fact, this is really just the same - as saying: - - %rename(foo_i) Foo::foo(int); - %rename(foo_d) Foo::foo(double); - class Foo { - ... - }; - - *** NEW FEATURE *** - -11/26/2001:beazley - Added the experimental %feature directive. %feature can be - used to attach arbitrary string attributes to parse tree nodes. - For example: - - %feature("except") blah { - try { - $function - } catch (Error) { - whatever; - } - } - - or - - %feature("set") *::x_set "x"; - - or - - %feature("blah") Foo::bar(int,double) const "spam"; - - The syntax is borrowed from the %rename directive. In fact, the - exact same semantics apply (inheritance, matching, etc.). - - %feature is a very powerful low-level primitive that can be used to - customize individual language modules and to provide hints to - any stage of code generation. Features are attached to - parse tree nodes as attributes with names like "feature:*" where * - is replaced by the feature name (e.g., "feature:except", "feature:set", - etc.). Language modules can then look for the features using - a simple attribute lookup. - - %feature is intended to be a replacement for a number of - older SWIG directives including %except and specialized - pragmas. It is more powerful (due to its parameterized - name matching) and it provides very precise control over - how customization features are attached to individual - declarations. There are future expansion plans that will - build upon this capability as well. - - It's not certain that %feature will ever be used directly - by SWIG users. Instead, it may be a low-level primitive - that is used in high-level macro definitions. For instance, - to support properties, you might define a macro like this: - - %define %property(name, setf, getf) - %feature("set") setf #name; - %feature("get") getf #name; - %enddef - - Which allows a user to specify things like this: - - %property(p, get_p, set_p); - - class Blah { - public: - int get_p(); - void set_p(int); - }; - - *** EXPERIMENTAL NEW FEATURE *** - -11/24/2001:beazley - The Tcl module has been expanded with some new features for - managing object ownership. For example: - - set c [Circle -args 20] - $c area # Invoke a method - $c -disown # Releases ownership of the object - $c -acquire # Acquires ownership of the object - - If Tcl owns the object, its destructor is invoked when the - corresponding object command is deleted in Tcl. - - To simplify the destruction of objects, the following syntax - can be used: - - $c -delete # Delete an object - - This is an alternative for the more obscure variant of - - rename $c {} - - These features also add functionality at the C API level. - The following functions manage ownership from C and - can be used in typemaps. - - SWIG_Acquire(void *ptr); - SWIG_Disown(void *ptr); - - A new function for constructing instances is also available: - - Tcl_Obj * - SWIG_NewInstanceObj(Tcl_Interp *interp, void *ptr, - swig_type_info *type, int own); - - When used in a typemap, this creates a pointer object and - an interpreter command that can be used to issue methods and - access attributes as shown above. - *** NEW FEATURE *** - -11/23/2001:beazley - All Python-related %pragma operations have been eliminated. - Most of these were written for older SWIG versions in order to - compensate for limitations in earlier releases. In an effort - to reduce the amount of code-clutter and potential for errors, - it is easier to simply eliminate the pragmas and to start over - (if needed). To be honest, I'm not even sure the pragmas - worked in 1.3.9 and recent releases. - - Note: If you need to insert code into the shadow class file - created by SWIG, simply use the %shadow directive like this: - - %shadow %{ - def some_python_code(): - print "blah!" - %} - - *** POTENTIAL INCOMPATIBILITY *** - -11/22/2001:beazley - Sweeping changes to the way in which the Python module handles - shadow classes. In early implementations, shadow classes were - merely Python wrappers around typed pointer objects. However, - some users actually wanted to receive the shadow class object in C. - To accommodate this, the dereferencing of the "this" pointer in - a shadow class was moved to C as described in CHANGES [8/8/99]. - However, the process of returning pointers to Python was still - somewhat problematic. Specifically, shadow classes never worked - in situations such as these: - - - Use of any kind of output typemap ('out' or 'argout') - - Global variables (broken as far as I can tell). - - In the past, some users have dealt with this by manually trying - to create shadow class objects themselves from C/C++. However, - this was difficult because the C wrappers don't really know how - to get access to the corresponding Python class. - - The Python module has now been modified to automatically attach - shadow class objects to pointers when they are returned to - Python. This process occurs in the function SWIG_NewPointerObj() - so the process is completely transparent to users. As a result, - shadow classes are now more seamlessly integrated with typemaps - and other features of SWIG. - - This change may introduce a number of incompatibilities. The - SWIG_NewPointerObj() now takes an extra parameter "own" to - indicate object ownership. This can be used to return a pointer - to Python that Python should destroy. In addition, older code - that tries to manually construct shadow class objects or which - expects bare pointers may break---such pointers may already be - encapsulated by a shadow class. - *** POTENTIAL INCOMPATIBILITY *** - -11/20/2001:beazley - Modified the %insert directive to accept single braces { ... }. - For example: - - %insert("header") { - ... some code ... - } - - This works exactly like %{ ... %} except that the code in the - braces is processed using the preprocessor. This can be useful - in certain contexts such as low-level code generation in - language modules. - *** NEW FEATURE *** - -11/20/2001:beazley - Command line options are now translated into preprocessor - symbols. For example: - - ./swig -python -shadow -module blah interface.i - - Creates the symbols: - - SWIGOPT_PYTHON 1 - SWIGOPT_SHADOW 1 - SWIGOPT_MODULE blah - - Modules can look for these symbols to alter their code generation - if needed. - *** NEW FEATURE *** - -11/20/2001:beazley - Massive overhaul of the Perl5 module. A lot of code generation is - now driven by tables and typemaps. The generated wrapper code - also makes use of tables to install constants, variables, and - functions instead of inlining a bunch of procedure calls. The - separate variable initialization function is gone. Most - code generation is controlled via the perl5.swg file in the - library. - *** POTENTIAL INCOMPATIBILITY *** - -11/13/2001:beazley - Added parsing support for the C++ typename keyword. Primarily this - is added to better support templates. For example: - - template<typename T> void blah(C& v) { - typename C::iterator i = v.begin(); - } - - Note: typename is supported in the parser in the same way as 'struct' - or 'class'. You probably shouldn't use it anywhere except in templates. - *** NEW FEATURE *** - -11/11/2001:beazley - Massive overhaul of the language module API. Most functions now - use a common, very simple, API. There are also a number of - interesting semantic side-effects of how code is actually generated. - Details will be forthcoming in Doc/Manual/Extending.html. - - *** POTENTIAL INCOMPATIBILITY *** Language modules written for - previous versions of SWIG will no longer work, - -11/10/2001:beazley - Fixed a very subtle bug due to unnamed class wrapping. For example, if - you did this - - typedef struct { - int x,y; - } gdPoint, *gdPointPtr; - - void foo(gdPointPtr x); - - Then the foo function would get a type-error. The problem has - to do with internal typedef handling and the fact that the typedef - declarations after the struct appear later in the parse tree. - It should work now. Problem reported by Vin Jovanovic. - -11/09/2001:beazley - Subtle change to "out" typemaps (and related variations). The name - that is attached to the typemap is now the raw C identifier that - appears on a declaration. This changes the behavior of - member functions. For example: - - %typemap(out) int foo { - ... - } - - class Blah { - public: - int foo(); // typemap gets applied - } - - Previous versions never really specified how this was supposed to - work. In SWIG1.1, you could probably write a typemap for the - wrapper name like this: - - %typemap(out) int Blah_foo { ... } - - However, this old behavior is now withdrawn and not supported. - Just use the member name without any sort of special prefix. - *** POTENTIAL INCOMPATIBILITY *** - -11/06/2001:beazley - Changes to Tcl module initialization: - - (1) SWIG now automatically includes the code needed to work with - Tcl stubs. Simply compile with -DUSE_TCL_STUBS. - - (2) SWIG now automatically calls Tcl_PkgProvide to register - a package name. The package name is the same as the name - specified with the %module directive. The version number is - set to "0.0" by default. To change the version number, use - swig -pkgversion 1.2 interface.i. - - *** POTENTIAL INCOMPATIBILITY *** - Modules that provided stubs and Tcl_PkgProvide on their own might - break. Simply remove that code. - -11/05/2001:beazley - Changed code generation of constants in the Tcl module. Constants - are now stored in a large table that get installed at module startup. - There are also no longer any static variables so it should generate - somewhat less code. - -11/04/2001:beazley - The "const" typemap has been renamed to "constant" in many language - modules. "const" is a C keyword which made the handling of the typemap - directive somewhat awkward in the parser. - *** POTENTIAL INCOMPATIBILITY *** - -11/04/2001:beazley - %typemap directive can now accept nearly arbitrary keyword parameters. - For example: - - %typemap(in,parse="i",doc="integer") int "..." - - The purpose of the keyword parameters is to supply code generation - hints to the target language module. The intepretation of the - parameters is language specific. - *** NEW FEATURE *** - -11/04/2001:beazley - Slight semantic change to internal call/return by value handling. - In previous versions of SWIG, call-by-value was translated - into pointers. For example: - - double dot_product(Vector a, Vector b); - - turned into this: - - double wrap_dot_product(Vector *a, Vector *b) { - return dot_product(*a,*b); - } - - This translation was normally performed by the SWIG core, outside - of the control of language modules. However, a side effect - of this was a lot of bizarre typemap behavior. For example, - if you did something like this: - - %typemap(in) int32 { - ... - } - - You would find that int32 was transformed into a pointer everywhere! - (needless to say, such behavior is unexpected and quite awkward to - deal with). To make matters worse, if a typedef was also used, - the pointer behavior suddenly disappeared. - - To fix this, the pointer transformation is now pushed to the - language modules. This produces wrappers that look roughly - like this: - - double wrap_dot_product(Vector *a, Vector *b) { - Vector arg1 = *a; - Vector arg2 = *b; - return dot_product(arg1,arg2); - } - - This change also makes it easy to define typemaps for - arbitrary undefined types. For example, you can do this (and it - will work regardless what int32 is): - - %typemap(in) int32 { - $1 = (int32) PyInt_AsLong($input); - } - - *** POTENTIAL IMCOMPATIBILITY *** - This change may break call/return by value code generation in - some language modules. - -11/03/2001:beazley - Changed the name of the default typemaps to the following: - - %typemap() SWIGTYPE { - ... an object ... - } - %typemap() SWIGTYPE * { - ... a pointer ... - } - %typemap() SWIGTYPE & { - ... a reference ... - } - %typemap() SWIGTYPE [] { - ... an array ... - } - %typemap() enum SWIGTYPE { - ... an enum value ... - } - %typemap() SWIGTYPE (CLASS::*) { - ... pointer to member ... - } - - - These types are used as the default for all types that don't match - anything else. See CHANGES log entry for 8/27/2000 for the - old behavior. The role of these types is also described in - Doc/Manual/Typemaps.html - - *** POTENTIAL INCOMPATIBILITY *** - -10/25/2001:beazley - Modified Guile and Mzscheme modules to support - multi-argument typemaps. - -10/25/2001: cheetah (william fulton) - [Java] Fix to handle pointers to arrays. - -10/24/2001:beazley - Defining a typemap rule for enum SWIGENUM can now be used - to define default behavior for enum variables. - -10/22/2001:beazley - Ruby module modified to support multi-argument typemaps. - -10/22/2001:beazley - The Ruby module can now handle functions with an arbitrary - number of arguments. Previous versions were limited to - to functions with only 9 or 16 arguments depending on - the use of default arguments. Note: from some inspection - of the Ruby interpreter source, the new approach might be - a little faster as well. - -10/18/2001:beazley - Fixed a bug with forward class declarations and - templates. - - class Foo <S,T>; - - Bug reported by Irina Kotlova. - -10/16/2001:beazley - Support for multivalued typemaps added. The typemaps - are specified using the syntax below. Within each - typemap, variable substitution is handled as follows: - - %typemap(in) (int argc, char *argv[]) { - $arg; // The input object in the target language - $1; // C local variable for first argument - $2; // C local variable for second argument - - // These variables refer to either argument - $1_type, $1_ltype, $1_basetype, etc... (argc) - $2_type, $2_ltype, $2_basetype, etc... (argv[]) - - // Array dimension of argv - $2_dim0 - } - - Basically any variable that was available in normal typemaps - is available for either argument by prefacing the variable - name by '$n_' where n is the argument position. - - Notes: - (1) Multi-valued typemaps can only be applied to a single - object in the target scripting language. For example, - you can split a string into a (char *, int) pair or - split a list into a (int, char []) pair. It is not - possible to map multiple objects to multiple arguments. - - (2) To maintain compatibility with older SWIG versions, the - variables such as $target and $type are preserved and - are mapped onto the first argument only. - - (3) This should not affect compatibility with older code. - Multi-valued typemaps are an extension to typemap handling. - Single valued typemaps can be specified in the usual - way. - - The old $source and $target variables are officially - deprecated. Input variables are referenced through - $arg$ and output values are reference through $result$. - - *** NEW FEATURE *** - -10/16/2001:beazley - Added parsing support for multivalued typemaps. The syntax - is a little funky, but here goes: - - // Define a multivalued typemap - %typemap(in) (int argc, char *argv[]) { - ... typemap code ... - } - - // Multivalued typemap with locals - %typemap(in) (int argc, char *argv[])(int temp) { - ... typemap code ... - } - - // Copy a multivalued typemap - %typemap(in) (int argcount, char **argv) = (int argc, char *argv[]); - - // Apply a multivalued typemap - %apply (int argc, char *argv[]) { (int argcount, char **argv) }; - - Note: this extra parsing support is added for future extension. - No language modules currently support multi-valued typemaps. - -10/11/2001:beazley - Modified the typemap matching code to discard qualifiers when - checking for a match. For example, if you have a declaration - like this: - - void blah(const char *x); - - The typemap checker checks for a match in the following order: - - const char *x - const char * - char *x - char * - - If typedef's are involved, qualifier stripping occurs before - typedef resolution. So if you had this, - - typedef char *string; - void blah(const string x); - - typemap checking would be as follows: - - const string x - const string - string x - string - const char *x - const char * - char *x - char * - - The primary reason for this change is to simplify the implementation - of language modules. Without qualifier stripping, one has to write - seperate typemaps for all variations of const and volatile (which - is a pain). - - *** POTENTIAL INCOMPATIBILITY *** Typemaps might be applied in - places where they weren't before. - - -10/9/2001: beazley - SWIG now generates wrappers that properly disambiguate - overloaded methods that only vary in constness. For - example: - - class Foo { - ... - void blah(); - void blah() const; - ... - }; - - To handle this, the %rename directive can be used normally. - - %rename(blah_const) blah() const; - - In the resulting wrapper code, method calls like this - are now generated: - - (obj)->blah() // Non-const version - ((Foo const *)obj)->blah() // const version - - This should force the right method to be invoked. - Admittedly, this is probably obscure, but we might - as well get it right. - -10/8/2001: beazley - The preprocessor now ignores '\r' in the input. - This should fix the following bug: - [ #468416 ] SWIG thinks macro defs are declarations? - -10/8/2001: beazley - Added support for ||, &&, and ! in constants. This - fixes SF [ #468988 ] Logical ops break preprocessor. - However, at this time, constants using these operators - are not supported (the parser will issue a warning). - -10/4/2001: beazley - Added -show_templates command line option. This makes - SWIG display the code it actually parses to generate - template wrappers. Mostly useful for debugging. - *** NEW FEATURE *** - -10/4/2001: beazley - Change to semantics of %template directive. When - using %template, the template arguments are handled - as types by default. For example: - - %template(vecint) vector<int>; - %template(vecdouble) vector<double>; - - To specify a template argument that is *not* a type, you - need to use default-value syntax. For example: - - %template(vecint) vector<int,int=50>; - %template(vecdouble) vector<int,size=100>; - - In this case, the type name doesn't really matter--only - the default value (e.g., 50, 100) is used during - expansion. This differs from normal C++, but I couldn't - figure out a better way to do it in the parser. Might - implement an alternative later. - *** POTENTIAL INCOMPATIBILITY *** - -10/4/2001: beazley - Major changes to template handling in order to provide - better integration with the C++ type-system. The main - problem is as follows: - - Suppose you have a template like this: - - template<class T> void blah(const T x) { stuff }; - - Now suppose, that you instantiate the template on a - type like this in SWIG: - - %template(blahint) blah<int *>; - - In C++, this is *supposed* to generate code like this: - - void blah(int *const x) { stuff }; - - However, in SWIG-1.3.9, the template substitution gets it wrong - and produces - - void blah(const int *x) { stuff }; - - (notice the bad placement of the 'const' qualifier). - - To fix this, the SWIG parser now generates implicit typedefs - for template type arguments that produces code roughly - equivalent to doing this: - - typedef int *__swigtmpl1; - %template(blahint) blah<__swigtmpl1>; - - which generates code like this: - - void blah(const __swigtmpl1 x) { stuff }; - - Since this is correct in both C++ and SWIG, it provides the right - semantics and allows everything to compile properly. However, - to clean up the generated code a little bit, the parser keeps - track of the template types and performs back-substitution to - the original type when building the parse tree. Thus, even - though the implicit typedef is used in the input and may appear - in the generated wrapper file (for proper compilation), the parse - tree will hide a lot of these details. For example: - - void blah(const __swigtmpl1 x) { stuff }; - - will look like it was declared as follows (which is what - you want): - - void blah(int *const x) { stuff } - - The only place you are likely to notice the typedef hack - is in bodies of template functions. For example, if you - did this, - - template<class T> class blah { - ... - %addmethods { - void spam() { - T tempvalue; - ... - } - } - } - - you will find that 'T tempvalue' got expanded into some - strange typedef type. This *still* compiles correctly - so it's not a big deal (other than looking kind of ugly - in the wrapper file). - -10/4/2001: beazley - Fixed some inheritance problems in Tcl Object interface. - -10/1/2001: beazley - Tcl module has changed to use byte-backed pointer strings. This - implementation should be safe on 64-bit platforms. However, - the order in which digits appear in pointer values no longer - directly corresponds to the actual numerical value of a - pointer (on little-endian machines, pairs of digits appear - in reverse order). - -10/1/2001: beazley - Perl5 module is now driven by a configuration file 'perl5.swg' - in the SWIG library. - -10/1/2001: beazley - The perl5 module no longer tries to apply the "out" typemap - in code generated for magic variables. I'm surprised that - this ever worked at all (since all of the code that was there - was wrong anyways). Use the "varout" typemap to handle - global variables. - -10/1/2001: beazley - Fixed a bug related to character array members of structures. - For example: - - struct Foo { - char name[32]; - }; - - SWIG is normally supposed to return a string, but this was - broken in 1.3.9. The reason it was broken was actually - due to a subtle new feature of typemaps. When a data member - is set to an array like this, the return type of the related - accessor function is actually set to an array. This means - that you can now write typemaps like this: - - %typemap(python,out) char [ANY] { - $target = PyString_FromStringAndSize($source,$dim0); - } - - This functionality can be used to replace the defunct - memberout typemap in a more elegant manner. - -9/29/2001: beazley - Some further refinement of qualified C++ member functions. - For example: - - class Foo { - ... - void foo() const; - ... - }; - - (i) The SWIG parser was extended slightly to allow 'volatile' - and combinations of 'const' and 'volatile' to be used. This - is probably rare, but technically legal. Only added for - completeness. - - (ii) For the purposes of overloading, qualified and non-qualified - functions are different. Thus, when a class has methods like this: - - void foo(); - void foo() const; - - Two distinct methods are declared. To deal with this, %rename - and similar directives have been extended to recognize const. - Thus, one can disambiguate the two functions like this: - - %rename(fooconst) Foo::foo() const; - - or simply ignore the const variant like this: - - %ignore Foo::foo() const; - - Note: SWIG currently has no way to actually invoke the const - member since the 'const' is discarded when generating wrappers - for objects. - -9/27/2001: beazley - New directive. %namewarn can be used to issue warning - messages for certain declaration names. The name - matching is the same as for the %rename directive. - The intent of this directive is to issue warnings for - possible namespace conflicts. For example: - - %namewarn("print is a python keyword") print; - - The name matching algorithm is performed after a name - has been resolved using %rename. Therefore, a - declaration like this will not generate a warning: - - %rename("Print") print; - ... - void print(); /* No warning generated */ - - Since the warning mechanism follows %rename semantics, it is - also to issue warnings for specific classes or just for - certain member function names. - - (Dave - I've been thinking about adding something like this - for quite some time. Just never got around to it) - *** NEW FEATURE *** - - -9/27/2001: beazley - Enhanced the %ignore directive so that warning messages - can be issued to users. This is done using %ignorewarn - like this: - - %ignorewarn("operator new ignored") operator new; - - The names and semantics of %ignorewarn is exactly the - same as %ignore. The primary purpose of this directive - is for module writers who want to ignore certain types - of declarations, but who also want to alert users about it. - A user might also use this for debugging (since messages - will appear whenever an ignored declaration appears). - *** NEW FEATURE *** - -9/26/2001: beazley - Super-experimental support for overloaded operators. - This implementation consists of a few different parts. - - (i) Operator names such as 'operator+' are now allowed - as valid declarator names. Thus the 'operator' syntax - can appear *anyplace* a normal declarator name was used - before. On the surface, this means that operators can - be parsed just like normal functions and methods. - However, it also means that operator names can be used - in many other SWIG directives like %rename. For example: - - %rename(__add__) Complex::operator+(const Complex &); - - (ii) Operators are wrapped *exactly* like normal functions - and methods. Internally, the operator name is used - directly meaning that the wrapper code might contain - statements like this: - - arg0->operator*((Complex const &)*arg1); - - This all seems to parse and compile correctly (at least - on my machine). - - (iii) SWIG will no longer wrap a declaration if its symbol - table name contains illegal identifier characters. If - illegal characters are detected, you will see an error - like this: - - Warning. Can't wrap operator* unless renamed to a valid identifier. - - The only way to fix this is to use %rename or %name to bind - the operator to a nice name like "add" or something. Note: - the legal identifier characters are determined by the target - language. - - There are certain issues with friend functions and operators. - Sometimes, friends are used to define mixed operators such - as adding a Complex and a double together. Currently, SWIG - ignores all friend declarations in a class. A global operator - declaration can probably be made to work, but you'll have to - rename it and it probably won't work very cleanly in the - target language since it's not a class member. - - SWIG doesn't know how to handle operator specifications - sometimes used for automatic type conversion. For example: - - class String { - ... - operator const char*(); - ... - }; - - (this doesn't parse correctly and generates a syntax error). - - Also: operators no longer show up as separate parse-tree - nodes (instead they are normal 'cdecl' nodes). I may - separate them as a special case later. - - See Examples/python/operator for an example. - - *** SUPER-EXPERIMENTAL NEW FEATURE *** - -Version 1.3.9 (September 25, 2001) -================================== - -9/25/2001: beazley - Fixed parsing problem with type declarations like - 'char ** const'. SWIG parsed this correctly, but the - internal type was represented incorrectly (the pointers - and qualifiers were in the wrong order). - -9/25/2001: beazley - Withdrew experimental feature (noted below) that was - causing serious parsing problems. - -Version 1.3.8 (September 23, 2001) -================================== - -9/23/2001: beazley - Included improved distutils setup.py file in the Tools - directory (look for the setup.py.tmpl file). Contributed by - Tony Seward. - -9/23/2001: beazley - Included two new RPM spec files in the Tools directory. Contributed - by Tony Seward and Uwe Steinmann. - -9/21/2001: beazley - Fixed SF Bug [ #463635 ] Perl5.swg does not compile in Visual C++ - -9/21/2001: beazley - Two new directives control the creation of default - constructors and destructors: - - %nodefault - %makedefault - - These replace %pragma nodefault and %pragma makedefault. - (old code will still work, but documentation will only - describe the new directives). - -9/21/2001: beazley - Fixed SF Bug [ #462354 ] %import broken in 1.3.7. - -9/20/2001: beazley - - Parser modified to ignore out-of-class constructor - and destructor declarations. For example: - - inline Foo::Foo() : - Bar("foo") - { - } - - inline Foo::~Foo() { - } - - Suggested by Jason Stewart. - *** EXPERIMENTAL FEATURE *** - -9/20/2001: beazley - Modified the parser to ignore forward template class - declarations. For example: - - template <class V, long S> class MapIter; - - Suggested by an email example from Irina Kotlova. - -9/20/2001: beazley - Fixed problem with undeclared tcl_result variable in - the "out" typemap for Tcl. Reported by Shaun Lowry. - -9/20/2001: beazley - Incorporated changes to make SWIG work with ActivePerl. - Contributed by Joel Reed. - -9/20/2001: beazley - Slight change to the parsing of C++ constructor initializers. - For example: - - class Foo : public Bar { - public: - Foo() : Bar(...) {...} - }; - - SWIG now discards the contents of the (...) regardless of - what might enclosed (even if syntactically wrong). SWIG - doesn't need this information and there is no reason to - needless add syntax rules to handle all of the possibilities - here. - -9/20/2001: beazley - Change to typemaps for structure members. If you have a - structure like this: - - struct Vector { - int *bar; - }; - - The member name 'bar' is now used in any accessor functions. - This allows the "in" typemap to be used when setting the value. - For example, this typemap - - %typemap(python,in) int *bar { - ... - } - - now matches Vector::bar. It should be noted that this will also - match any function with an argument of "int *bar" (so you should - be careful). - *** NEW FEATURE. POTENTIAL INCOMPATIBILITY *** - -9/20/2001: beazley - Fixed SF bug #462642 setting string values in structures - -9/20/2001: beazley - Fixed SF bug #462398 problem with nested templates. - -9/20/2001: beazley - Fixed SF bug #461626 problem with formatting and C++ comments. - -9/20/2001: beazley - Fixed SF bug #462845 Wrong ownership of returned objects. - -9/19/2001: beazley - Fixed SF bug #459367. Default constructors for classes - with pure virtual methods. - -9/19/2001: beazley - Fixed problem with default arguments and class scope. For - example: - - class Foo { - public: - enum bar { FOO, BAR }; - void blah(bar b = FOO); - ... - } - - SWIG now correctly generates a default value of "Foo::FOO" for - the blah() method above. This used to work in 1.1, but was - broken in 1.3.7. Bug reported by Mike Romberg. - -Version 1.3.7 (September 3, 2001) -================================== - -9/02/2001: beazley - Added special %ignore directive to ignore declarations. This - feature works exactly like %rename. For example: - - %ignore foo; // Ignore all declarations foo - %ignore ::foo; // Only ignore foo in global scope - %ignore Spam::foo; // Only ignore in class Spam - %ignore *::foo; // Ignore in all classes - - %ignore can also be parameterized. For example: - - %ignore foo(int); - %ignore ::foo(int); - %ignore Spam::foo(int); - %ignore *::foo(int); - - *** NEW FEATURE *** - - -9/02/2001: cheetah (william fulton) - [Java] shadowcode pragma modified so that the code that is output - in the shadow file is placed relative to where it is placed in the - c/c++ code. This allows support for JavaDoc function comments. - -9/01/2001: beazley - Fixed SF Patch [ #447791 ] Fix for python -interface option. - Submitted by Tarn Weisner Burton. - -9/01/2001: beazley - SWIG no longer generates default constructors/destructors - for a class if it only defines a private/protected constructor - or destructor or if any one of its base classes only has - private constructors/destructors. This was reported in - SF Patch [ #444281 ] nonpublic/default/inhereted ctor/dtor - by Marcelo Matus. - -9/01/2001: beazley - Added patch to Perl5 module that allows constants to be - wrapped as constants that don't require the leading $. - This feature is enabled using the -const option. - Patch contributed by Rich Wales. - *** NEW FEATURE *** - -8/31/2001: beazley - Added parsing support for the 'volatile' type qualifier. - volatile doesn't mean anything to SWIG, but it is - needed to properly generate prototypes for declarations - that use it. It's also been added to make the SWIG type - system more complete. - *** NEW FEATURE *** - -8/30/2001: beazley - Added support for parameterized %rename directive. *** This - new feature can be used to greatly simplify the task of - resolving overloaded methods and functions. *** - - In prior versions of SWIG, the %rename directive was - used to consistently apply an identifier renaming. For - example, if you said this: - - %rename foo bar; - - Every occurrence of 'foo' would be renamed to 'bar'. - Although this works fine for resolving a conflict with a - target language reserved word, it is useless for - for dealing with overloaded methods. This is because - all methods are simply renamed to the same thing - (generating the same conflict as before). - - Therefore, the only way to deal with overloaded methods - was to go through and individually rename them all using - %name. For example: - - class Foo { - public: - virtual void bar(void); - %name(bar_i) virtual void bar(int); - ... - }; - - To make matters worse, you had to do this for all - derived classes too. - - class Spam : public Foo { - public: - virtual void bar(void); - %name(bar_i) virtual void bar(int); - ... - }; - - Needless to say, this makes it extremely hard to resolve - overloading without a lot of work and makes it almost - impossible to use SWIG on raw C++ .h files. - - To fix this, %rename now accepts parameter declarators. - The syntax has also been changed slightly. For example, - the following declaration renames all occurrences of 'bar(int)' - to 'bar_i', leaving any other occurrence of 'bar' alone. - - %rename(bar_i) bar(int); - - Using this feature, you can now selectively rename - certain declarations in advance. For example: - - %rename(bar_i) bar(int); - %rename(bar_d) bar(double); - - // Include raw C++ header - %include "header.h" - - When %rename is used in this manner, all occurrence of bar(int) - are renamed wherever they might occur. More control is obtained - through explicit qualification. For example, - - %rename(bar_i) ::bar(int); - - only applies the renaming if bar(int) is defined in the global scope. - The declaration, - - %rename(bar_i) Foo::bar(int); - - applies the renaming if bar(int) is defined in a class Foo. - This latter form also supports inheritance. Therefore, if you - had a class like this: - - class Spam : public Foo { - public: - void bar(int); - } - - The Spam::bar(int) method would also be renamed (since Spam - is a subclass of Foo). This latter feature makes it easy - for SWIG to apply a consistent renaming across an entire - class hierarchy simply by specifying renaming rules for - the base class. - - A class wildcard of * can be used if you want to renaming - all matching members of all classes. For example: - - %rename(bar_i) *::bar(int); - - will rename all members bar(int) that are defined in classes. - It will not renamed definitions of bar(int) in the global - scope. - - The old use of %rename is still supported, but is somewhat - enhanced. - - %rename(foo) bar; // Renames all occurrences of 'bar'. - %rename(foo) ::bar; // Rename all 'bar' in global scope only. - %rename(foo) *::bar; // Rename all 'bar' in classes only. - %rename(foo) Foo::bar; // Rename all 'bar' defined in class Foo. - - *** NEW FEATURE *** - -8/30/2001: beazley - Added support for data-member to member-function - transformation. For example, suppose you had a - structure like this: - - struct Vector { - double x,y; - }; - - Now suppose that you wanted to access x and y - through a member function interface instead - of the usual SWIG behavior. For example: - - f.set_x(3.4) # instead of f.x = 3.4 - x = f.get_x() # instead of x = f.x - - To do this, simply use the new %attributefunc - directive. For example: - - %attributefunc(get_%s,set_%s) - struct Vector { - double x,y; - }; - %noattributefunc - - The arguments to %attributefunc are C-style printf - format strings that determine the naming convention - to use. %s is replaced with the actual name of the - data member. SWIG provides a number of printf - extensions that might help. For example, if you - wanted to title case all of the attributes, you - could do this: - - %attributefunc(get%(title)s,set%(title)s); - - This will turn an attribute 'bar' to 'getBar()' and 'setBar()'. - - (someone requested this long ago, but I finally figured - how to implement it in a straightforward manner). - *** EXPERIMENTAL NEW FEATURE *** - -8/30/2001: beazley - SWIG now automatically generates default constructors - and destructors if none are defined. This used to be - enabled with a command line switch -make_default, but - most people want these functions anyways. To turn - off this behavior use the -no_default option or include - the following pragma in the interface file: - - %pragma no_default; - - This may break certain interfaces that defined their - own constructors/destructors using the same naming - convention as SWIG. If so, you will get duplicate - symbols when compiling the SWIG wrapper file. - *** POTENTIAL INCOMPATIBILITY *** - -8/29/2001: beazley - Changes to Perl5 shadow class code generation. Iterators - are no longer supported (FIRSTKEY, NEXTKEY). Also, attribute - access has been changed to rely on inheritance in order - to provide better behavior across modules. - -8/28/2001: beazley - Various obscure improvements to the type system and classes. - Strange declarations like this are now wrapped correctly - (i.e., the generated wrapper code doesn't cause the C++ - compiler to die with a type error). - - class Foo { - public: - typedef double Real; - Real foo(Real (*op)(Real,Real), Real x, Real y); - }; - - Inheritance of types is also handled correctly. - -8/28/2001: beazley - Changes to class wrappers. When SWIG sees two classes like this, - - class X { - public: - void foo(); - ... - } - - class Y : public X { - public: - void bar(); - ... - } - - it now only generates two wrapper functions: - - X_foo(X *x) { x->foo(); } - Y_bar(Y *y) { y->bar(); } - - Unlike SWIG1.15, the foo() method does *not* propagate to a wrapper - function Y_foo(). Instead, the base class method X_foo() must be - used. - - This change should not affect modules that use shadow classes, but - it might break modules that directly use the low-level C wrappers. - This change is being made for a number of reasons: - - - It greatly simplifies the implementation of SWIG--especially - with anticipated future changes such as overloaded methods. - - - It results in substantially less wrapper code--especially - for big C++ class hierarchies (inherited declarations - are no longer copied into every single derived class). - - - It allows for better code generation across multiple - SWIG generated modules (code isn't replicated in - every single module). - - *** POTENTIAL INCOMPATIBILITY *** - -8/22/2001: cheetah (william fulton) - Provided some Windows documentation in the Win directory and some - Visual C++ project files for running examples on Windows. - -8/28/2001: mkoeppe - [Guile] Handle renamed overloaded functions properly; - thanks to Marc Zonzon <Marc.Zonzon@univ-rennes1.fr> for the - patch. See the new test case name_cxx. - -8/27/2001: mkoeppe - [Tcl] Removed lots of warnings issued by the Sun Forte - compilers, which were caused by mixing function pointers - of different linkages (C++/C). - -8/23/2001: mkoeppe - Improved the MzScheme module by porting Guile's pointer - type checking system and making type dispatch - typemap-driven. - -8/22/2001: beazley - Entirely new symbol table processing. SWIG should be able to - report much better error messages for multiple declarations. - Also, the new symbol table allows for overloaded functions - (although overloading isn't quite supported in the language - modules yet). - -8/22/2001: cheetah (william fulton) - * [Java] %new support added. - * [Java] Package JNI name refixed! - -8/19/2001: beazley - Python module modified to support pointers to C++ members. This - is an experimental feature. - *** NEW FEATURE *** - -8/19/2001: beazley - Added limited parsing and full type-system support for pointers to - members. None of SWIG's language modules really know how to deal with - this so this is really only provided for completeness and future - expansion. Note: SWIG does not support pointers to members which - are themselves pointers to members, references to pointers to members, - or other complicated declarations like this. - *** NEW FEATURE *** - -8/19/2001: beazley - SWIG is much better at parsing certain C++ declarations. Operators and - friends generally don't cause anymore syntax errors. However, neither - are really supported. - -8/18/2001: beazley - Added *highly* experimental support for wrapping of C++ - template declarations. Since C++ templates are essentially - glorified macros and SWIG has a fully operational C - preprocessor with macro support, the parser now converts - template declarations to macros. For example, a function - template like this - - template<class T> T max(T a, T b); - - is internally converted into a macro like this: - - %define %_template_max(__name,T) - %name(__name) T max(T a, T b); - %enddef - - To instantiate a version of the template, a special %template declaration - is used like this: - - %template(maxint) max<int>; - %template(maxdouble) max<double>; - - The parameter to the %template directive must be proper C identifier that's - used to uniquely name the resulting instantiation. When used, the - the expanded macro looks like this: - - %name(maxint) int max(int a, int b); - %name(maxdouble) double max(double a, double b); - - A similar technique is used for template classes. For instance: - - template<class T> class vector { - T *data; - int sz; - public: - vector(int nitems); - T *get(int n); - ... - }; - - Gets converted into a macro like this: - - %define %_template_vector(__name, T) - %{ - typedef vector<T> __name; - %} - class __name { - T *data; - int sz; - public: - __name(int nitems); - T *get(int n); - ... - }; - typedef __name vector<T>; - %enddef - - A specific instantiation is created in exactly the same way: - - %template(intvec) vector<int>; - - The resulting code parsed by SWIG is then: - - %{ - typedef vector<int> intvec; - %} - class intvec { - int *data; - int sz; - public: - intvec(int nitems); - int *get(int n); - ... - }; - typedef intvec vector<int>; - - Note: the last typedef is non-standard C and is used by SWIG to provide - an association between the name "intvec" and the template type - "vector<int>". - - CAUTION: This is an experimental feature and the first time SWIG has - supported C++ templates. Error reporting is essential non-existent. - It will probably break in certain cases. - *** EXPERIMENTAL NEW FEATURE **** - -8/15/2001: beazley - Change to wrapping of multi-dimensional arrays. Arrays - are now properly mapped to a pointer to an array of - one less dimension. For example: - - int [10]; --> int * - int [10][20]; --> int (*)[20]; - int [10][20][30]; --> int (*)[20][30]; - - This change may break certain SWIG extensions because - older versions simply mapped all arrays into a single - pointer such as "int *". Although possibly unusual, - the new version is correct in terms of the C type system. - *** POTENTIAL INCOMPATIBILITY *** - -8/06/2001: cheetah (william fulton) - * [Java] Array setters generated for struct/class array members. - -8/13/2001: beazley - Many improvements to Tcl/Perl/Python modules to better - work with multiple interface files and the %import directive. - -8/13/2001: beazley - Fixed up the behavior of %import in the Python module. - SWIG no longer pollutes the module namespace by using - 'from module import *' to refer to the other module. - Instead, it does a proper 'import module'. Also, SWIG - may work a lot better when importing modules that include - references to other imported modules. - -8/13/2001: mkoeppe - Added new typemap substitutions, generalizing those of the - Guile-specific 5/27/2001 changes: - * $descriptor is the same as SWIGTYPE$mangle, but also - ensures that the type descriptor of this name gets - defined. - * $*type, $*ltype, $*mangle, $*descriptor are the same as - the variants without star, but they REMOVE one level of - pointers from the type. (This is only valid for pointer - types.) - * $&type, $<ype, $&mangle, $&descriptor are the same as - the variants without ampersand, but they ADD one level of - pointers to the type. - The Guile-specific substitution $basedescriptor was removed - because it was useless. - -8/12/2001: beazley - The %extern directive is now deprecated and withdrawn. The - purpose of this directive was to import selected definitions - from other interface files and headers. However, the same - functionality is better handled through %import. This - leaves SWIG with two file inclusion directives: - - %include filename - Inserts into current interface - %import filename - Import types and classes from - another module - - *** POTENTIAL INCOMPATIBILITY *** - -8/09/2001: beazley - Added new support for wrapping C/C++ callback functions. - A common problem with some C libraries is that many - functions take a function pointer as an argument. For example: - - int do_op(..., int (*op)(int,int), ...); - - Unfortunately, the only way to call such a function is to - pass it a function pointer of some compatible type. In - previous versions of SWIG, you had to solve this problem - with some really gross hacks. For example, if you wanted to - use the following function as a callback, - - int foo(int, int); - - you had to install a pointer to it as a constant. For example: - - %constant int (*FOO)(int,int) = foo; - - or - - const int (*FOO)(int,int) = foo; - - or if you had a really old SWIG version: - - typedef int (*OP_FUNC)(int,int); - int do_op(..., OP_FUNC, ...); - const OP_FUNC FOO = foo; - - - Now, you can do one of two things: - - %constant int foo(int,int); - - This creates a constant 'foo' of type int (*)(int,int). - Alternatively, you can do this: - - %callback("%s"); - int foo(int,int); - int bar(int,int); - %nocallback; - - In this case, the functions are installed as constants where - the name is defined by the format string given to %callback(). - If the names generated by the format string differ from the - actual function name, both a function wrapper and a callback - constant are created. For example: - - %callback("%(upper)s"); - int foo(int,int); - int bar(int,int); - %nocallback; - - Creates two wrapper functions 'foo', 'bar' and additionally - creates two callback constants 'FOO', 'BAR'. - - Note: SWIG still does not provide automatic support for - writing callback functions in the target language. - *** NEW FEATURE *** - -8/06/2001: cheetah (william fulton) - * struct nesting fixes as per SF bug #447488. - -8/03/2001: beazley - The %name directive now applies to constants created with - #define and %constant. However, most language modules - were never written to support this and will have to be - modified to make it work. Tcl, Python, and Perl modules - are working now. - *** NEW FEATURE *** - -8/03/2001: beazley - Massive changes and simplification of C declaration parsing. - Although SWIG is still not a full C parser, its ability - to handle complex datatypes including pointers to functions - and pointers to arrays has been vastly improved. - -8/03/2001: cheetah (william fulton) - * Distribution fixes: autoconf no longer needed to install SWIG. - -8/02/2001: beazley - Removed two undocumented parsing features. SWIG no longer - supports out-of-class static function or variable - declarations. For example: - - static int Foo::bar; - - This feature may return if there is sufficient demand. - However, since SWIG is most often used with header files, - it is more likely for these definitions to be included - in the class definition. - *** POTENTIAL INCOMPATIBILITY *** - -8/02/2001: cheetah (william fulton) - * Cleanup of the GIFPlot examples. Upgraded Java GIFPlot example. - -8/01/2001: cheetah (william fulton) - * [Java] Efficiency changes: _cPtr used where possible rather than - getCPtr(). Bug fixes for inheritance - derived class sometimes - didn't delete the c memory when _delete() was called. - * [Java] Abstract c++ classes are wrapped with a java abstract shadow - class. Also a pure virtual function is mapped with an abstract method. - * The default output file has always been <module>_wrap.c. It is now - <module>_wrap.cxx if the -c++ commandline option is passed to swig. - This has been done as otherwise c++ code would appear in a c file. - *** POTENTIAL INCOMPATIBILITY *** - -7/31/2001: beazley - Modified the %constant directive to be more C-like in syntax. - The syntax is now: - - %constant NAME = VALUE; - %constant TYPE NAME = VALUE; - - For example: - - %constant Foo *Bar = &Spam; - - A more subtle case is as follows: - - %constant int (*FOO)(int,int) = blah; - - *** POTENTIAL INCOMPATIBILITY *** Modules that were using - the %constant directive directly will need to be modified. - -7/30/2001: beazley - Removed obscure and undocumented form of the %inline directive: - - %inline int blah(int a, int b) { - ... - } - - *** POTENTIAL INCOMPATIBILITY *** - (note: this feature was never documented and is withdrawn) - -7/30/2001: beazley - Removed support for functions with no explicitly declared - return type. For example: - - foo(int); - - In C, such functions were implicitly assumed to return an 'int'. - In C++, this is illegal. Either way, it's considered bad - style. Removing support for this in SWIG will simplify - certain issues in parsing. - *** POTENTIAL INCOMPATIBILITY *** - -7/30/2001: mkoeppe - * Partial merge from the CVS trunk. The Source/DOH directory - and most of the Source/Swig directory is up-to-date now. - * [Guile] %scheme is now a macro for %insert("scheme"). - New syntax: %scheme "FILENAME"; - New syntax: %scheme %{ SCHEME-CODE %} - New macros %multiple_values, %values_as_list, - %values_as_vector. - -7/29/2001: beazley - %readonly and %readwrite have been turned into SWIG pragmas. - %pragma(swig) readonly and %pragma(swig) readwrite. Macros - are used to provide backwards compatibility. - -7/29/2001: beazley - Minor changes to %pragma directive. %pragma must always - be directed to a specific language. For example: - - %pragma(swig) make_default; - %pragma(perl5) include = "blah.i"; - - Also extended the pragma directive to allow code blocks - - %pragma(foo) code = %{ - ... some code ... - %} - - *** POTENTIAL INCOMPATIBILITY *** - -7/29/2001: beazley - Change to the way 'const' variables are wrapped. In - previous versions of SWIG, a 'const' variable was - wrapped as a constant. Now, 'const' variables are - wrapped as read-only variables. There are several - reasons for making this change, mostly pertaining to - subtle details of how 'const' actually works. - - This will probably break old interfaces that used 'const' - to create constants. As a replacement, consider using this: - - const int a = 4; ===> %constant int a = 4; - *** POTENTIAL INCOMPATIBILITY *** - -7/29/2001: beazley - Reorganization and simplification of type parsing. - Types with 'const' should work correctly now. - -7/29/2001: beazley - Most swig directives related to the documentation system - are now deprecated. - -7/29/2001: beazley - Removed support for Objective-C in order to simplify - parser reconstruction. Will return if there is sufficient - demand. - *** POTENTIAL INCOMPATIBILITY *** - -7/29/2001: beazley - Code inclusion has been modified in the parser. A common - directive %insert is now used for everything. This - inserts a file into the output: - - %insert(header) "foo.swg" - - This inserts some inline code into the output - - %insert(header) %{ - ... some code ... - %} - - There are five predefined targets for the insert directive: - - "header" - Header section of wrapper file - "runtime" - Runtime section of wrapper file - "wrapper" - Wrapper section - "init" - Initialization function - "null" - Nothing. Discard. - - The following directives are still supported, but are - now defined in terms of macros: - - %{ ... %} -> %insert(header) %{ ... %} - %init %{ ... %} -> %insert(init) %{ ... %} - %wrapper %{ ... %} -> %insert(wrapper) %{ ... %} - %runtime %{ ... %} -> %insert(runtime) %{ ... %} - - Language modules can define new named targets by using the - C API function Swig_register_filebyname() (see main.cxx). - For example, if you wanted to expose a shadow class file, - you could do this: - - Swig_register_filebyname("shadow", f_shadow); - - Then in the interface file: - - %insert(shadow) %{ ... %} - - Note: this change should not affect any old interfaces, but - does open up new possibilities for enhancements. - -7/29/2001: beazley - SWIG now always includes a standard library file 'swig.swg'. - This file defines a large number of macro definitions - that define the behavior of various SWIG directives. - Previously, all SWIG directives were handled as special - cases in the parser. This made the parser a large - bloated mess. Now, the parser is stripped down to a few - simple directives and macros are used to handle everything else. - -7/26/2001: cheetah (william fulton) - * Fixes for Sourceforge bug #444748 - new testcase cpp_static: - [TCL] Class with just static member variable/function fix - [Java] Fixed static variables support - [Ruby] Static variables workaround removed - -7/27/2001: mkoeppe - * stype.c (SwigType_default): Strip qualifiers first. The - default type of "int * const" is now "SWIGPOINTER *". - * main.cxx: Define "__cplusplus" in SWIG's preprocessor if - in C++ mode. - * [Guile]: Added some support for arrays and C++ - references, fixing the "constant_pointers" test case. - * Moved most tests from the old Guile-specific test-suite - to the new test-suite. Also moved perl5/pointer-cxx - example there. - -7/26/2001: cheetah (william fulton) - * Test-suite added. - * Initial testcases: constant_pointers cpp_enum defines - sizeof_pointers unions virtual_destructor - * Make clean improvements. - -7/24/2001: cheetah (william fulton) - * [Java] Underscores in the package name and/or module name - no longer give linking problems. - -7/17/2001: cheetah (william fulton) - * More parser bug fixes for constant pointers - -7/19/2001: mkoeppe - * [Guile] Aesthetic improvement in variable wrappers. - -7/18/2001: beazley - * Fixed core-dump problem in pointer library when - freeing character arrays. - SF Bug [ #415837 ] pointer lib core dump - -7/18/2001: beazley - * Fixed problem with default destructors and shadow - classes. SF bug #221128. - -7/18/2001: beazley - * To provide better line-number tracking in interfaces - with lots of macros, special locator comments are - now generated by the SWIG preprocessor. For example: - - /*@foo.i,42,BLAH@*/expanded macro/*@@*/ - - The first /*@...@*/ sequence sets the context - to point to the macro code. The /*@@*/ comment - terminates the context. The SWIG parser should - ignore all of the locator comments as should - the C compiler (should such comments end up - in generated wrapper code). - -7/18/2001: mkoeppe - * The parser now handles severely constified types in - typemaps. This introduced a new shift/reduce conflict, but - only with a heuristic function-pointer catch-all rule. - * [Guile]: Added typemaps for severely constified types. - * Fixed the "template-whitespace" problem by canonicalizing - whitespace, especially around angle brackets and commas. - -7/17/2001: mkoeppe - * [Guile]: A Scheme file is emitted if the -scmstub FILE.SCM - command-line option is used. The %scheme directive - (implemented as a macro for a pragma) allows to insert - arbitrary code here. In "simple" and "passive" linkage, - the file gets filled with define-module and export - declarations. - -7/17/2001: cheetah (william fulton) - * Parser bug fix to support constant pointers, eg int* const ptr. - Fixed everywhere - variables, parameters, return types etc. Note that - when wrapping a constant pointer variable only the getter is generated. - -7/17/2001: mkoeppe - * Fixed SF bug #441470 (#define X "//" would not be parsed, - see test-suite entry "preproc-1"), reported by T. W. Burton - <twburton@users.sf.net>. - * Changed the type of character constants to "char", rather - than "char *". Changed the individual language modules - to keep the old behaviour, except for the Guile module, - where it is desired to make them Scheme characters. This - fixes SF bug #231409, test-suite entry "char-constant". - * Applied patch for DOH/Doh/memory.c by Les Schaffer - <schaffer@optonline.net> (avoid required side effects in - assert). - -7/17/2001: cheetah (william fulton) - * Bug fix in parser for virtual destructor with void as parameter - * Bug fix in parser #defines embedded within classes/structs/unions - Consequently %constant can now also be placed within a struct/class/union. - * Bug fix in parser to allow sizeof(*I_am_a_pointer) within a #define - -7/16/2001: mkoeppe - * Added changes for the Macintosh contributed by Luigi - Ballabio <ballabio@mac.com>. - * Some "const" fixes in the code. - * [Guile]: Made the constant-wrapper functions much shorter. - -7/13/2001: mkoeppe - * [Guile]: Some "const" fixes for Guile version 1.3.4. - * Handle anonymous arguments with default values and static - array members of classes. Both bugs reported by Annalisa Terracina - <annalisa.terracina@datamat.it>; see the files - Examples/guile/test-suite/static-array-member.i and - anonymous-arg.i. - -Version 1.3.6 (July 9, 2001) -============================= - -7/09/2001: cheetah (william fulton) - * GIFPlot examples: FOREGROUND and BACKGROUND definition missing - after TRANSPARENT #define fix in GIFPlot - -7/03/2001: beazley - Fixed up the version numbers so that the release is known - as 1.3.6. All future releases should have a similar - version format. - -7/02/2001: mkoeppe - * [Python]: Prevent the problem of self.thisown not being - defined if the C++ class constructor raised an exception. - Thanks to Luigi Ballabio <ballabio@mac.com>. - -6/29/2001: mkoeppe - * More portability fixes; fixed "gcc -Wall" warnings. - -6/29/2001: cheetah (william fulton) - * GIFPlot examples: TRANSPARENT #define multiple times on Solaris - (clashes with stream.h). - * Multiple definition bug fix for shadow classes. The perl and python - modules had workarounds which have been replaced with fixes in - the core. Many of the Language::cpp_xxxx functions now set a - flag which the derived classes can access through - is_multiple_definition() to see whether or not code should be - generated. The code below would have produced varying degrees - of incorrect shadow class code for the various modules: - class TestClass - { - public: - TestClass() {} - TestClass(int a) {} - ~TestClass() {} - unsigned long xyz(short k) {} - unsigned long xyz(int n) {} - static void static_func() {} - static void static_func(int a) {} - }; - void delete_TestClass(int a); - -6/27/2001: mkoeppe - * [Perl] Another const-related portability fix. - -6/26/2001: cheetah (william fulton) - * [Java] Added in cpp_pragma() support with a host of new pragmas - see - jswig.html. These are designed for better mixing of Java and c++. It - enables the user to specify pure Java classes as bases and/or interfaces - for the wrapped c/c++. - * [Java] Old pragmas renamed. Warning given for the moment if used. - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -6/25/2001: mkoeppe - * Incorporated more build changes contributed by Wyss Clemens - <WYS@helbling.ch> for swig/ruby on cygwin. - -6/20/2001: cheetah (william fulton) - * Makefile mods so that 'make check' uses the swig options in the makefiles - * [Java] Removed Generating wrappers message - * [Java] NULL pointer bug fix - * [Java] Bug fix for Kaffe JVM - -6/20/2001: mkoeppe - * SWIG_TypeQuery from common.swg now returns a - swig_type_info* rather than a void*. This fixes a problem - when using pointer.i and C++, as illustrated by the new - test-suite example perl5/pointer-cxx. - * Portability fixes (const char *). - * Incorporated build changes contributed by Wyss Clemens - <WYS@helbling.ch>, which make swig runnable on cygwin. - -6/19/2001: cheetah (william fulton) - * [Java] Bug fix for SF bug #211144. This fix is a workaround - until fixed in the core. - -6/19/2001: mkoeppe - * [Guile]: Portability fixes for use with the Sun Forte - compilers. - * [Tcl]: Portability fix (const char *). - * [Tcl]: Configure now first tries to find a tclConfig.sh - file in order to find the Tcl include directory, library - location and library name. - * [Python]: Added a few possible library locations. - -6/18/2001: mkoeppe - * [Guile]: Don't call scm_c_export if nothing is to be - exported. Don't warn on %module if module has been set - already (this frequently occurs when %import is used). - -6/16/2001: mkoeppe - * [Guile]: New "passive" linkage, which is appropriate for - multi-module extensions without Guile module magic. - -6/15/2001: mkoeppe - * [Guile]: Fixed printing of smobs (space and angle were - missing). - * Properly generate type information for base classes - imported with the %import directive. Thanks to Marcelo - Matus <mmatus@acms.arizona.edu> for the report and the - patch; this closes SF bug #231619; see also - Examples/guile/test-suite/import*. - * [Guile]: Fix casting between class and base class; the - runtime type system had it the wrong way around; see - Examples/guile/test-suite/casts.i - * Make typemaps for SWIGPOINTER * with arg name take - precedence over those without arg name, to match normal - typemap precedence rules. - * Fixed the random-line-numbers problem reported as SF bug - #217310; thanks to Michael Scharf <scharf@users.sf.net>. - * [Guile]: Handle the %name and %rename directives. - * New syntax: %name and %rename now optionally take double - quotes around the scripting name. This is to allow scripting - names that aren't valid C identifiers. - -6/14/2001: beazley - Made a minor change to the way files are loaded in - order to get file/line number reporting correct in - the preprocessor. - -6/14/2001: mkoeppe - * The parser now understands the (non-standard) "long long" - types. It is up to the individual language modules to - provide typemaps if needed. Reported by Sam Steingold, SF - bug #429176. - * The parser now understands arguments like "const int * - const i". This fixes SF bug #215649. - * Fixed the Guile test-suite. - -6/13/2001: mkoeppe - Partial merge from the CVS trunk at tag - "mkoeppe-merge-1". This covers the following changes: - -| 01/16/01: ttn -| Wrote table of contents for Doc/engineering.html. Added section -| on CVS tagging conventions. Added copyright to other docs. -| 9/25/00 : beazley -| Modified the preprocessor so that macro names can start with a '%'. -| This may allow new SWIG "directives" to be defined as macros instead -| of having to be hard-coded into the parser. -| -| *** Also a yet-to-be-documented quoting mechanism with backquotes -| *** has been implemented? - -6/13/2001: mkoeppe - * When configure does not find a language, don't use default - paths like /usr/local/include; this only causes build - problems. - * New directory: Examples/Guile/test-suite, where a few - bugs in 1.3a5 are demonstrated. - * Handle C++ methods that have both a "const" and a "throw" - directive (see Examples/Guile/test-suite/cplusplus-throw.i); - thanks to Scott B. Drummonds for the report and the fix. - * Handle C++ pointer-reference arguments (like "int *& arg") - (see Examples/Guile/test-suite/pointer-reference.i, - reported as SF bug #432224). - * [Ruby] Fixed typo in rubydec.swg; thanks to Lyle Johnson! - * Don't stop testing when one test fails. - * [Guile, MzScheme] Don't print "Generating wrappers...". - -6/12/2001: mkoeppe - [Guile] VECTORLENINPUT and LISTLENINPUT now have separate - list length variables. TYPEMAP_POINTER_INPUT_OUTPUT - attaches argument documentation involving SCM_TYPE to the - standard pointer typemaps. INOUT is now an alias for BOTH. - -6/12/2001: cheetah (william fulton) - Some Java documentation added. - [Java] Fixed bugs in import pragma and shadow pragma. - -6/12/2001: mkoeppe - Fix declarations of SWIG_define_class - (Lib/ruby/rubydec.swg) and SWIG_TypeQuery - (Lib/common.swg). Thanks to Lyle Johnson - <ljohnson@resgen.com> for the patches. - -6/11/2001: mkoeppe - [Guile] Use long instead of scm_bits_t; this makes the - generated wrapper code compatible with Guile 1.3.4 - again. Thanks to Masaki Fukushima for pointing this out. - -6/11/2001: cheetah (william fulton) - The generic INSTALL file from autoconf added. Few changes to README file. - -6/11/2001: mkoeppe - Fixed typo in Makefile.in; thanks to Greg Troxel - <gdt@ir.bbn.com>. - -6/08/2001: cheetah (william fulton) - make check works again. Examples/GIFPlot configure generated by - top level autoconf now. - -6/08/2001: mkoeppe - Another build change: The new script autogen.sh runs - autoconf in the appropriate directories. The top-level - configure also configures in Examples/GIFPlot. - -6/07/2001: mkoeppe - Made the Makefile work with non-GNU make again. - -6/07/2001: cheetah (william fulton) - [Java] Class/struct members that are arrays of pointers to classes/structs - - Shadow class's get/set accessors now use Java classes instead of longs (pointers). - [Java] Shadow classes will now clean up memory if function return type - is a class/struct. - [Java] New example called reference based on the same example from other modules. - -6/06/2001: mkoeppe - New configure option --with-release-suffix allows for - attaching a suffix to the swig binary and the swig runtime - libraries. Minor changes to the build system. "swig - -swiglib" works again. If invoked with the new option - "-ldflags", SWIG prints a line of linker flags needed to - link with the runtime library of the selected language - module. - -6/06/2001: mkoeppe - [Guile] gswig_list_p is an int, not a SCM. This typo - caused warnings when compiling with a Guile configured with - strict C type checking. In INPUT and BOTH typemaps - generated by the SIMPLE_MAP macro, use the SCM_TO_C - function to convert from Guile to C (rather than C_TO_SCM). - Use scm_intprint to print pointers (rather than - sprintf). Allow using "-linkage" instead of "-Linkage". - -6/05/2001: cheetah (william fulton) - [Java] Mods for using inherited c++ classes from Java - [Java] New example called class based on the same example from other modules - -6/05/2001: cheetah (william fulton) - [Java] destructor (_delete()) was not aware of %name renaming - [Java] extends baseclass did not know about %name renaming - [Java] extends baseclass did extend even when the baseclass was not known to swig - [Java] sometimes enum-declarations occurred before the Java class declaration - [Java] unrelated enum initialisations no longer appear in Java class - [Java] if module ends in '_' correct JNI names are now produced - -6/04/2001: cheetah (william fulton) - [Java] Shadow class mods - Modified constructor replaces - newInstance(). _delete() now thread safe. getCPtr() replaces - _self. _selfClass() removed as now redundant. - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - - [Java] Not all output java files had SWIG banner. New banner. - - [Java] Shadow class finalizers are output by default: Command - line option -finalize deprecated and replaced with -nofinalize. - *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** - -6/ 1/2001: mkoeppe - [Guile] Cast SCM_CAR() to scm_bits_t before shifting it. - This is required for compiling with a Guile configured with - strict C type checking. - -6/ 1/2001: mkoeppe - Added configure option "--with-swiglibdir". - -5/31/2001: mkoeppe - [Guile] Support multiple parallel lists or vectors in - the typemaps provided by list-vector.i. New typemaps file, - pointer-in-out.i. - -5/25/2001: cheetah (william fulton) - [Java] HTML update for examples. - -5/28/2001: mkoeppe - Minor changes to the build system. Added subdirectory for - Debian package control files. - -5/28/2001: mkoeppe - [Guile] Build a runtime library, libswigguile. - -5/28/2001: mkoeppe - [Guile] New typemap substitution $*descriptor. Use the {} - syntax, rather than the "" syntax for the standard - typemaps, in order to work around strange macro-expansion - behavior of the SWIG preprocessor. This introduces some - extra braces. - -5/27/2001: mkoeppe - [Guile] Handle pointer types with typemaps, rather than - hard-coded. New typemap substitutions $descriptor, - $basedescriptor; see documentation. Some clean-up in the - variable/constants wrapper generator code. New convenience - macro SWIG_Guile_MustGetPtr, which allows getting pointers - from smobs in a functional style. New typemap file - "list-vector.i", providing macros that define typemaps for - converting between C arrays and Scheme lists and vectors. - -5/25/2001: cheetah (william fulton) - [Java] STL string moved into its own typemap as it is c++ code and - it break any c code using the typemaps.i file. - - Fixes for wrappers around global variables - applies to primitive - types and user types (class/struct) and pointers to these. - - Structure member variables and class public member variables getters - and setters pass a pointer to the member as was in 1.3a3 and 1.1 - (1.3a5 was passing by value) - - Parameters that were arrays and return types were incorrectly - being passed to create_function() as pointers. - - Fix for arrays of enums. - [Java] Updated java examples and added two more. - [Java] Java module updated from SWIG1.3a3 including code cleanup etc. - [Java] enum support added. - [Java] Array support implemented - [Java] Shadow classes improved - Java objects used rather than - longs holding the c pointer to the wrapped structure/c++class - -5/22/2001: mkoeppe - [Guile] Fixed extern "C" declarations in C++ mode. Thanks - to Greg Troxel <gdt@ir.bbn.com>. - -5/21/2001: mkoeppe - [Guile] New linkage "module" for creating Guile modules for - Guile versions >= 1.5.0. - -4/18/2001: mkoeppe - [MzScheme] Added typemaps for passing through Scheme_Object - pointers. - -4/9/2001 : mkoeppe - [MzScheme] Added typemaps for `bool'. Inclusion of headers - and support routines is now data-driven via mzscheme.i. - Headers come from the new file mzschemdec.swg. Don't abort - immediately when a type-handling error is reported. When - searching for typemaps for enums, fall back to using int, - like the Guile backend does. Support char constants. Emit - correct wrapper code for variables. - -3/12/2001: mkoeppe - [Guile] Fixed typemaps for char **OUTPUT, char **BOTH. - -3/2/2001 : mkoeppe - [Guile] Every wrapper function now gets a boolean variable - gswig_list_p which indicates whether multiple values are - present. The macros GUILE_APPEND_RESULT, GUILE_MAYBE_VALUES - and GUILE_MAYBE_VECTOR use this variable, rather than - checking whether the current return value is a list. This - allows for typemaps returning a list as a single value (a - list was erroneously converted into a vector or a - multiple-value object in this case). - -3/1/2001 : mkoeppe - [Guile] Added support for returning multiple values as - vectors, or passing them to a muliple-value - continuation. By default, multiple values still get - returned as a list. - -3/1/2001 : mkoeppe - [Guile] Added a "beforereturn" pragma. The value of this - pragma is inserted just before every return statement. - -3/1/2001 : mkoeppe - [Guile] Added support for Guile 1.4.1 procedure - documentation formats, see internals.html. - -2/26/2001: mkoeppe - [Guile] Made the wrapper code compile with C++ if the - "-c++" command-line switch is given. Thanks to - <monkeyiq@dingoblue.net.au>. - -2/26/2001: mkoeppe - [Guile] Now two type tables, swig_types and - swig_types_initial, are used, as all other SWIG language - modules do. This removes the need for the tricky - construction used before that the broken Redhat 7.0 gcc - doesn't parse. Reported by <monkeyiq@dingoblue.net.au>. - -2/26/2001: mkoeppe - [Guile] Fixed typemaps for char *OUTPUT, char *BOTH; a bad - free() would be emitted. Added typemap for SCM. - - -Version 1.3 Alpha 5 -=================== - -9/19/00 : beazley - [Python] Python module generates more efficient code for - creating the return value of a wrapper function. Modification - suggested by Jon Travis. - -9/19/00 : beazley - Library files specified with the -l option are now included at the - end of the interface file (reverting to the old behavior). - -9/19/00 : beazley - Fixed some problems with enum handling. enums are now manipulated as - 'int', but cast into the enum type when values are passed to the - corresponding C function. - -9/19/00 : mkoeppe - [Guile] Removed "-with-smobs" command-line option, as this is the - default now. Added "-emit-setters" command-line option, - which turns on generating procedures-with-setters; see - internals.html. - -9/18/00 : mkoeppe - Incorporated patch #101430, fixing bugs in the Guile module: - 1. Some arguments were erroneously taken as *optional* arguments when - ignored arguments were present. - 2. Guile 1.3.4 was not supported since functions introduced in Guile - 1.4 were used. - 3. Added handling of `const char *'. - -9/17/00 : beazley - Fixed problem with failed assertion and large files. - -9/17/00 : beazley - Fixed problem with the '%' character appearing in added methods - and function bodies. Preprocessor bug. - -Version 1.3 Alpha 4 (September 4, 2000) -======================================= - -9/3/00 : ttn - Added instructions for maintainers in Examples/README on how - to make examples also be useful in the testing framework. - Also, "make check" now uses ./Lib by via env var `SWIG_LIB'. - This is overridable like so: - make chk-swiglib=/my/experimental/swig/Lib check - -9/3/00 : beazley - Added $typemap variable to typemaps. This gets replaced with - a string indicating the typemap that is applied. Feature - request from rsalz. - -9/3/00 : beazley - Experimental optimization to code generation for virtual - member functions. If you have two classes like this: - - class A() { - virtual void foo(); - } - - class B() : public A { - virtual void foo(); - } - - Swig now will generate a single wrapper function for this - - A_foo(A *a) { - a->foo(); - } - - and use it as the implementation of both A_foo() and B_foo(). - This optimization only takes place if both methods are declared - as virtual and both take identical parameters. - *** EXPERIMENTAL FEATURE *** - -9/3/00 : beazley - Restored the "memberin" typemap for setting structure members. - Unlike the old version, the new version is expanded inline in the - wrapper function allowing access to scripting language - internals (a sometimes requested feature). The "memberout" typemap - is gone. Use the "out" typemaps instead. - *** POTENTIAL INCOMPATIBILITY *** - -9/3/00 : beazley - Attribute set methods no longer return the value of a member. - For example: - - struct Foo { - int x; - ... - } - - now gets set as follows: - - void Foo_x_set(Foo *f, int x) { - f->x = x; - } - - In SWIG1.1 it used to be this: - - int Foo_x_set(Foo *f, int x) { - return (f->x = x); - } - - This has been changed due to the complexity created by trying - to do this with more exotic datatypes such as arrays. It also - complicates inlining and handling of the "memberin" typemap. - *** POTENTIAL INCOMPATIBILITY *** - -9/2/00 : beazley - Removed the ptrcast() and ptrmap() functions from the - pointer.i library file. Old implementation is incompatible - with new type system. - *** POTENTIAL INCOMPATIBILITY *** - -9/2/00 : beazley - New runtime function SWIG_TypeQuery(const char *name) added. - This function can be used to extract the type info structure - that is used for type-checking. It works with either the - nice C name or mangled version of a datatype. For example: - - swig_type_info *ty = Swig_TypeQuery("int *"); - swig_type_info *ty = Swig_TypeQuery("_p_int"); - - This is an advanced feature that has been added to support some - exotic extension modules that need to directly manipulate - scripting language objects. - *** NEW FEATURE *** - -9/2/00 : beazley - New directive %types() added. This is used to - explicitly list datatypes that should be included in - the runtime type-checking code. Normally it is never - necessary to use this but sometimes advanced extensions - (such as the pointer.i library) may need to manually - add types to the type-checker. - *** NEW FEATURE *** - -8/31/00 : beazley - Improved handling of string array variables. For example, - a global variable of the form "char name[64]" is automatically - managed as a 64 character string. Previously this didn't - work at all or required the use of a special typemap. - *** NEW FEATURE (Tcl, Perl, Python) *** - -8/31/00 : ttn - Added Makefile target `check-c++-examples', which uses new - files under Examples/C++ contributed by Tal Shalif. Now "make - check" also does "make check-c++-examples". Also, expanded - actions in `check-gifplot-example' and `check-aliveness'. - -8/30/00 : mkoeppe - Major clean-up in the Guile module. Added typemap-driven - documentation system. Changed to handle more than 10 - args. Updated and extended examples. - *** NEW FEATURE *** - -8/29/00 : beazley - Added new %insert directive that inserts the contents of a file - into a portion of the output wrapper file. This is only intended - for use by writers of language modules. Works as follows: - - %insert(headers) "file.swg"; - %insert(runtime) "file.swg"; - %insert(wrappers) "file.swg"; - %insert(init) "file.swg"; - - *** NEW FEATURE *** - -8/29/00 : beazley - Added new %runtime directive which includes code into the runtime - portion of the wrapper code. For example: - - %runtime %{ - ... some internal runtime code ... - %} - - There is no practical reason for ordinary users to use this - feature (almost everything can be done using %{ ... %} - instead). However, writers of language modules may want to - use this in language configuration files. - *** NEW FEATURE *** - -8/28/00 : beazley - Typemaps can now be specified using string literals like - this: - - %typemap(in) int "$target = SvIV($source);" - - When code is specified like this, it is *NOT* enclosed - inside a local scope (as with older typemap declarations). - Note: character escape sequences are interpreted in the - code string so if you want to include a quote or some - other special character, make sure you use a (\). - *** NEW FEATURE *** - -8/27/00 : beazley - Typemaps have been modified to follow typedef declarations. - For example, if you have this: - - typedef int Number; - - %typemap(in) int { - ... get an integer ... - } - - void foo(Number a); - - The typemap for 'int' will be applied to the argument 'Number a'. - Of course, if you specify a typemap for 'Number' it will take - precedence (nor will it ever be applied to an 'int'). - *** POTENTIAL INCOMPATIBILITY *** - -8/27/00 : beazley - Default typemap specification has changed. In older - versions of swig, you could do this: - - %typemap(in) int SWIG_DEFAULT_TYPE { - ... - } - - To specify the default handling of a datatype. Now that - SWIG follows typedef declarations, this is unnecessary. - Simply specifying a typemap for 'int' will work for all - variations of integers that are typedef'd to 'int'. - - Caveat, specifying the default behavior for pointers, - references, arrays, and user defined types is a little - different. This must be done as follows: - - %typemap() SWIGPOINTER * { - ... a pointer ... - } - %typemap() SWIGREFERENCE & { - ... a reference ... - } - %typemap() SWIGARRAY [] { - ... an array ... - } - %typemap() SWIGTYPE { - ... a user-defined type (by value) ... - } - *** POTENTIAL INCOMPATIBILITY *** - -8/15/00 : dustin - The file swig-1.3a1-1.spec has been added to the Tools directory. - It can be used to build a redhat package for SWIG, although it - will need to be updated for the next public release. - -8/15/00 : beazley - Typemaps have been completely rewritten. Eventually they may be - replaced with something better, but for now they stay. However, - there are a number of a significant changes that may trip some - people up: - - 1. Typemap scoping is currently broken. Because of this, the - following code won't work. - - %typemap(in) blah * { - ... - } - class Foo { - ... - int bar(blah *x); - } - %typemap(in) blah *; /* Clear typemap */ - - (this breaks because the code for the class Foo is actually - generated after the entire interface file has been processed). - This is only a temporary bug. - - 2. In SWIG1.1, the %apply directive worked by performing a - very complex type-aliasing procedure. From this point on, - %apply is simply a generalized typemap copy operation. - For example, - - %apply double *OUTPUT { double *x, double *y }; - - Copies *ALL* currently defined typemaps for 'double *OUTPUT' and - copies them to 'double *x' and 'double *y'. - - Most people probably won't even notice this change in - %apply. However, where it will break things is in code like - this: - - %apply double *OUTPUT { double *x }; - %typemap(in) double *OUTPUT { - ... whatever ... - } - - void foo(double *x); - - In SWIG1.1, you will find that 'foo' uses the 'double *OUTPUT' rule - even though it was defined after the %apply directive (this is - the weird aliasing scheme at work). In SWIG1.3 and later, - the 'double *OUTPUT' rule is ignored because it is defined - after the %apply directive. - - 3. The %clear directive has been modified to erase all currently - defined typemaps for a particular type. This differs from - SWIG1.1 where %clear only removed rules that were added using - the %apply directive. - - 4. Typemap matching is now performed using *exact* types. - This means that things like this - - %typemap(in) char * { } - %typemap(in) const char * { } - - are different typemaps. A similar rule applies for pointers, - arrays, and references. For example: - - %typemap(in) double * { } - - used to apply to 'double &', 'double []', Now, it only applies - to 'double *'. If you want a 'double &', you'll need to handle - that separately. - - 5. Array matching has been simplfied. In SWIG1.1, array matching - was performed by trying various combinations of dimensions. - For example, 'double a[10][20]' was matched as follows: - - double [10][20] - double [ANY][20] - double [10][ANY] - double [ANY][ANY] - - In SWIG1.3, only the following matches are attempted: - - double [10][20] - double [ANY][ANY] - - On the positive side, typemap matching is now *significantly* faster - than before. - *** POTENTIAL INCOMPATIBILITY *** - -8/15/00 : beazley - Secret developer feature. Since datatypes are now represented as - strings internally, you can bypass limitations of the parser and - create a wild datatype by simply enclosing the raw string encoding - in backticks (``) and sticking it in the interface file anywhere a - type is expected. For example, `a(20).a(10).p.f(int,int)`. This - feature is only intended for testing (i.e., you want to see what - happens to your language module if it gets a reference to a pointer - to an array of pointers to functions or something). - *** SICK HACK *** - -8/14/00 : beazley - Completely new type-system added to the implementation. - More details later. - -8/11/00 : beazley - Cleaned up some of the I/O handling. SWIG no longer generates - any temporary files such as _wrap.wrap, _wrap.ii, _wrap.init. - Instead, these "files" are kept around in memory as strings - (although this is transparent to language modules). - -8/4/00 : ttn - Added Makefile target "check" and variants. - This can be used like "make check" or, to explicitly skip a - language LANG: "make skip-LANG=true check". LANG is skipped - automatically if ./configure determines that LANG support is - insufficient. - - Currently, the check is limited to doing the equivalent of - "make all" in some of the Examples directories. This should - be expanded both horizontally (different types of tests) and - vertically (after "make all" in an Examples subdir succeeds, - do some additional tests with the resulting interpreter, etc). - -8/4/00 : ttn - Added Makefile target "distclean", which deletes all the - files ./configure creates, including config.status and friends. - -8/3/00 : harcoh - java changes??? [todo: document changes] - -7/23/00 : beazley - Typemaps have been modified to key off of the real datatypes - used in the interface file. This means that typemaps for - "const char *" and "char *" will be difference as will typemaps - for "Vector" and "Vector *." - *** POTENTIAL INCOMPATIBILITY *** - This is likely to break interfaces that rely on the odd type - handling behavior of typemaps in SWIG1.1--especially with - respect to interfaces involving pass-by-value. - -7/23/00 : beazley - New %constant directive. This directive can be used to - create true constants in the target scripting language. - It's most simple form is something like this: - - %constant FOO 42; - - In this case, the type is inferred from the syntax of the - value (in reality, all #define macros are translated into - directives of this form). - - An expanded version is as follows: - - %constant(Foo *) FOO = &FooObj; - - In this case, an explicit type can be specified. This - latter form may be useful for creating constants that - used to be specified as - - const Foo *FOO = &FooObj; - - (which are now treated as variables). - *** EXPERIMENTAL FEATURE *** The syntax may change in - the final release. - -7/23/00 : beazley - Modified the parser so that variable declarations of the form - "const type *a" are handled as variables, not constants. - Note: SWIG1.1 handled this case erroneously because - const char *a is a pointer variable that can be reassigned. - *** POTENTIAL INCOMPATIBILITY *** - Note: just because this is the "right" way to do things, - doesn't mean it's the most appropriate interpretation. - I suspect that many C programmers might use 'const char *' - with the intent of creating a constant, without realizing - that they've created a reassignable global variable. - -7/23/00 : beazley - The C/C++ wrapping layer has been completely redesigned and - reimplemented. This change should iron out a few rough - spots with the handling of datatypes. In addition, the - wrapper code is somewhat cleaner. - *** POTENTIAL INCOMPATIBILITY *** - This change may break interfaces that involve - subtle corner-cases with typemaps and the %addmethods - directive since some of these features had somewhat - type handling behavior in SWIG1.1. - -7/23/00 : beazley - The "memberin" and "memberout" typemaps are gone for the - moment, but they might return as soon as I figure out - how to integrate them with some of the streamlined C wrapper - functions. - *** POTENTIAL INCOMPATIBILITY *** - -7/22/00 : beazley - A variety of old type handling functions such as print_type(), - print_full(), print_mangle(), etc... are gone and have been - replaced with a smaller set of functions. See the file - Doc/internals.html for details. This will break all third - party language modules. - *** POTENTIAL INCOMPATIBILITY *** - -7/20/00 : beazley - Deprecated the %val and %out directives. These directives - shouldn't really be necessary since typemaps can be used - to achieve similar results. This also cleans up the - handling of types and parameters quite a bit. - *** POTENTIAL INCOMPATIBILITY *** - -7/20/00 : ttn - Fixed unspecified-module bug in Guile support and removed - more non-"with-smobs" functionality using patches submitted - by Matthias Koeppe. - - Re-enable recognition of "-with-smobs" (with no effect since - we use smobs by default now) for the time being. After the - 1.3a4 release, this option will signal an error. - -7/17/00 : ttn - Fixed NULL-input bug in parameter list handling. - Reported by Matthias Koeppe. - -7/12/00 : beazley - Fixed memory leak in Python type-checking code. Reported by - Keith Davidson. Bug #109379. - -7/10/00 : beazley - Changed internal data structures related to function parameters. - -7/10/00 : beazley - Fixed some bugs related to the handling of the %name() directive - and classes in the Tcl module. Problem reported by James Bailey. - -7/10/00 : beazley - Fixed parsing and enum handling problems with character constants. - Reported by Greg Kochanski. - -7/10/00 : beazley - Removed WrapperFunction class from the core and updated the language - module. This will break third party modules. - *** POTENTIAL INCOMPATIBILITY *** - -7/9/00 : beazley - Implementation of SWIG no longer makes use of C++ operator overloading. - This will almost certainly break *all* third party language modules - that are not part of the main SWIG CVS tree. Sorry. - *** POTENTIAL INCOMPATIBILITY *** - -7/8/00 : beazley - Removed the experimental and undocumented "build" typemap that - was intended to work with multiple arguments. Simply too weird - to keep around. Besides, a better replacement is in the works. - -7/6/00 : ttn - Removed non-"with-smobs" functionality (Guile support), i.e., - "-with-smobs" is now the default and no longer needs to be - specified on the command-line. - -7/5/00 : ttn - Incorporated Ruby support contributed by Masaki Fukushima. - -6/28/00 : ttn - Applied more-than-10-args bugfix patch contributed - by Matthias Koeppe. - -6/27/00 : beazley - Rewrote some of the string handling and eliminated the C++ - implementation (which is now just a wrapper). - -6/27/00 : ttn - Added Doc/index.html and Doc/internals.html. The target - audience for the latter is new SWIG developers. - - -Version 1.3 Alpha 3 (June 18, 2000) -=================================== - -6/18/00 : beazley - Removed the naming.cxx, hash.cxx, and symbol.cxx files from - the SWIG1.1 directory. Continued to migrate things away - from the C++ base (although there's still a lot of work to do). - -6/17/00 : beazley - Added a few more examples to the Examples directory. Still - need to do a lot of work on this. - -6/16/00 : beazley - Added -includeall to follow all #include statements in the - preprocessor. - -6/15/00 : beazley - Tried to fix as many C++ warnings as possible when compiling - with the Sun Workshop C++ compiler. Unfortunately, this means - that there are a lot of statements that contain string literals - of the form (char*)"Blah". - -6/15/00: beazley - A variety of cleanup and performance optimization in the - low-level DOH library. This seems to result in a speedup - of 50-100% for preprocessing and other related tasks. - -5/10/00 : ttn - Applied variable-wrapping bugfix patch contributed - by Matthias Koeppe. - -4/17/00 : ttn - Updated MzScheme support contributed by Oleg Tolmatcev. - We now use a `Scheme_Type'-based structure to wrap pointers. - -4/11/00 : ttn - Incorporated further Guile-support patch by Matthias Koeppe. - Typemaps previously deleted have been re-added. There is now - exception handling (see Doc/engineering.html). `SWIG_init' is now - declared extern only for simple linkage. Some bugs were fixed. - -4/06/00 : ttn - Incorporated MzScheme support contributed by Oleg Tolmatcev. - This includes new directories Lib/mzscheme and Examples/mzscheme. - -4/03/00 : ttn - Added Examples/guile and children. This is an adaptation of - the same-named directory from the SWIG-1.1p5 distribution. - Added Guile-specific section to Doc/engineering.html. - -4/02/00 : ttn - Incorporated new guilemain.i by Martin Froehlich. - Incorporated Guile-support rewrite patch by Matthias Koeppe. - The command line option "-with-smobs" enables implementation of - pointer type handling using smobs, the canonical mechanism for - defining new types in Guile. Previous implementation (using - strings) is at the moment still supported but deprecated. At - some point, "-with-smobs" will be the default and no longer - required. - -3/13/00 : beazley - Added purify patches submitted by Ram Bhamidipaty. - -3/02/00 : ttn - Added support for different Guile "linkage" schemes. - Currently, "-Linkage hobbit" works. - - -Version 1.3 Alpha 2 (March 1, 2000) -=================================== - -2/29/00 : beazley - Made SWIG ignore the 'mutable' keyword. - -2/29/00 : beazley - Incorporated some patches to the Perl5 module related to - the -hide option and the destruction of objects. - Patch submitted by Karl Forner. - -2/27/00 : ttn - Incorporated Guile support contributed by Matthias Koeppe. - This includes a cpp macro in Lib/guile/guile.swg and the - entire file Lib/guile/typemaps.i. - -2/25/00 : ttn - Modified configure.in and Makefile.in files to support - non-local build (useful in multi-arch environments). - -2/24/00 : ttn - Incorporated Guile support contributed by Clark McGrew. - This works with Guile 1.3, but since it depends heavily - on the gh_ interface, it should work for all later versions. - It has not been tested with versions before 1.3. - WARNING: Code is unstable due to experimentation by ttn. - -2/16/00 : beazley - A variety of performance improvements to the Python shadow - class code generation. Many of these result in substantial - runtime performance gains. However, these have come at - a cost of requiring the use of Python 1.5.2. For older - versions, use 'swig -noopt -python' to turn off these - optimization features. - -Version 1.3 Alpha 1 (February 11, 2000) -======================================= - -2/11/00 : Added 'void' to prototype of Python module initializer. - Reported by Mark Howson (1/20/00). - -2/11/00 : beazley - Modified the Python shadow class code to discard ownership of an - object whenever it is assigned to a member of another object. - This problem has been around for awhile, but was most recently - reported by Burkhard Kloss (12/30/99). - -2/11/00 : beazley - Added braces around macros in the exception.i library. Reported - by Buck Hodges (12/19/99) - -2/11/00 : beazley - Fixed bug in the constraints.i library. Reported by Buck - Hodges (12/14/99) - -2/11/00 : beazley - The %native directive now generates Tcl8 object-style command calls. - A full solution for Tcl7 and Tcl8 is still needed. Patch suggested - by Mike Weiblen (11/29/99) - -2/11/00 : beazley - Modified the typemap code to include the $ndim variable for arrays. - Patch provided by Michel Sanner (11/12/99). - -2/11/00 : beazley - Modified the Python module to raise a Runtime error if an attempt - is made to set a read-only member of a shadow class. Reported by - Michel Sanner (11/5/99). - -2/10/00 : The documentation system has been removed. However, it is likely - to return at some point in the future. - -2/1/00 : Added a number of performance enhancements to the Python shadow - classing and type-checking code. Contributed by Vadim Chugunov. - - 1. Remove _kwargs argument from the shadow wrappers when -keyword - option is not specified. This saves us a construction of keyword - dictionary on each method call. - - def method1(self, *_args, **_kwargs): - val = apply(test2c.PyClass1_method1, (self,) + _args, _kwargs) - return val - - becomes - - def method1(self, *_args): - val = apply(test2c.PyClass1_method1, (self,) + _args) - return val - - 2. Incorporate self into the _args tuple. This saves at least one tuple - allocation per method call. - - def method1(self, *_args): - val = apply(test2c.PyClass1_method1, (self,) + _args) - return val - - becomes - - def method1(*_args): - val = apply(test2c.PyClass1_method1, _args) - return val - - 3. Remove *Ptr classes. - Assume that we are SWIGging a c++ class CppClass. - Currently SWIG will generate both CppClassPtr class - that hosts all methods and also CppClass that is derived - from the former and contains just the constructor. - When CppClass method is called, the interpreter will try - to find it in the CppClass's dictionary first, and only then - check the base class. - - CppClassPtr functionality may be emulated with: - - import new - _new_instance = new.instance - def CppClassPtr(this): - return _new_instance(CppClass, {"this":this,"thisown":0}) - - This saves us one dictionary lookup per call. - - <DB>The new module was first added in Python-1.5.2 so it - won't work with older versions. I've implemented an - alternative that achieves the same thing</DB> - - 4. Use CObjects instead of strings for pointers. - - Dave: This enhancements result in speedups of up to 50% in some - of the preliminary tests I ran. - -2/1/00 : Upgraded the Python module to use a new type-checking scheme that - is more memory efficient, provides better performance, and - is less error prone. Unfortunately, it will break all code that - depends on the SWIG_GetPtr() function call in typemaps. - These functions should be changed as follows: - - if (SWIG_GetPtr(string,&ptr,"_Foo_p")) { - return NULL; - } - - becomes - - if (SWIG_ConvertPtr(pyobj, &ptr, SWIG_TYPE_Foo_p) == -1) { - return NULL; - } - - Note: In the new implementation SWIG_TYPE_Foo_p is no longer - a type-signature string, but rather an index into a type - encoding table that contains type information. - *** POTENTIAL INCOMPATIBILITY *** - -1/30/00 : loic - Conditionally compile experimental code with --enable-experiment - configure flag. - Fix .cvsignore to ignore configure & yacc generated files - -1/28/00 : loic - Apply automake everywhere - Keep configure scripts so that people are not *forced* to autoconf - Keep sources generated by yacc so that compilation without yacc - is possible. - Source/LParse/cscanner.c: change lyacc.h into parser.h to please - default yacc generation rules. - Use AC_CONFIG_SUBDIRS in configure.in instead of hand made script. - Update all relevant .cvsignore to include .deps - Fixed missing ; line 136 Source/Swig/swig.h - -1/13/00 : beazley - Fixed a number of minor end-of-file parsing problems in the - preprocessor. - -1/13/00 : beazley - Added -freeze option that forces SWIG to freeze upon exit. - This is only used as a debugging tool so that I can more - easily examine SWIG's memory footprint. - -1/13/00 : beazley - Added patch to guile module for supporting optional arguments - Patch contributed by Dieter Baron. - -1/13/00 : loic - Added .cvsignore, Examples/.cvsignore, Source/DOH/Doh/.cvsignore - Source/SWIG1.1/main.cxx: Fixed -I handling bug - Source/Modules1.1/java.cxx: fixed char* -> const char* warnings that are - errors when compiling with gcc-2.95.2 - Source/SWIG1.1/main.cxx: cast const char* to char* for String_replace - token and rep should really be const. - -1/12/00 : beazley - Added Harco's Java modules. - -1/12/00 : beazley - Revoked the %ifdef, %ifndef, %endif, %if, %elif, and %else - directives. These are no longer needed as SWIG now has a real - preprocessor. - *** POTENTIAL INCOMPATIBILITY *** - -1/12/00 : beazley - Moved the documentation modules from the SWIG directory - to the Modules directory (where they really should have been - to begin with). - -1/12/00 : beazley - Removed the -stat option for printing statistics. The - statistics reporting was inadequate and mostly broken - anyway. - *** POTENTIAL INCOMPATIBILITY *** - -1/12/00 : beazley - Removed the -t option for reading a typemap file. More - trouble than it's worth. Just include typemaps at the top - of the interface file. - *** POTENTIAL INCOMPATIBILITY *** - -1/12/00 : beazley - Removed the %checkout directive. - *** POTENTIAL INCOMPATIBILITY *** - -1/12/00 : beazley - Removed the -ci option for file checkin. Too problematic - to implement. Probably better to just put your SWIG library - under CVS instead. - *** POTENTIAL INCOMPATIBILITY ***. - -1/11/00 : beazley - Deleted the LATEX module. Sorry... Didn't know anyone - who was using it. Besides, I'm looking to simplify - the documentation system. - *** POTENTIAL INCOMPATIBILITY *** - -1/11/00 : beazley - Modified the ASCII documentation module to use a .txt - suffix for its output file instead of .doc. - -1/11/00 : beazley - Added the long-lost SWIG preprocessor back to the system. - It should be enabled by default. Raw preprocessed output - can be viewed using swig -E file.i. - *** NEW FEATURE *** - -1/11/00 : beazley and djmitche - Completely reorganized the SWIG directory structure. The - basic organization is now: - - Source/ SWIG source code - Lib/ SWIG library files (swig_lib) - Doc/ Documentation - Examples/ Examples - - More directories will be added as needed. - -12/08/99: Loic Dachary (loic@senga.org) - Enhanced package handling for perl5 and c++. - - With new option -hide Foo::Bar, every perl5 object (Frob) is - qualified by Foo::Bar::Frob. The package name is solely used - to encapsulate C/C++ wrappers output in <module>_wrap.c and the - corresponding perl package in <module>.pm. Note that a package - name may contain :: (Frob::Nitz) and will be relative to the - package name provided by -hide (Foo::Bar::Frob::Nitz). - - In *_wrap.c, SWIG_init macro is used. Was previously defined - but not used and simplifies code. - - Added typemap(perl5,perl5in) and typemap(perl5,perl5out) that - do the equivalent of typemap(perl5,in) and typemap(perl5,out) - but contain perl code and applies to wrappers generated by - -shadow. - - Lacking proper regression tests I used - Examples/perl5/{c++,constraint,defarg,except, - graph/graph[1234],multinherit,nested,shadow,simple,tree, - typemaps/{argv,argv2,arraymember,database,file,ignore,integer, - output,passref,reference,return}}/. I ran swig with and without - the patches, diff the generatedsources, run the .pl files - and checked that the results are identical. In all those examples - I had no error. - -11/21/99: Modified the Tcl module to provide full variable linking capabilities - to all datatypes. In previous versions, a pair of accessor functions - were created for datatypes incompatible with the Tcl_LinkVar() function. - Now, we simply use variable traces to support everything. This may - break scripts that rely upon the older behavior. - *** POTENTIAL INCOMPATIBILITY *** - -11/21/99: Added slight tweak to wrapper generator to collect local variables - of similar type. Produces somewhat more compact wrapper code. - -11/20/99: Modified the Tcl module to use SWIG_GetArgs() to parse - arguments. This is a technique borrowed from Python in which - arguments are converted using a format string convention similiar - to fprintf(). This results in a *substantial* reduction in the - size of the resulting wrapper code with only a modest runtime overhead - in going through the extra conversion function. - -11/13/99: Completely rewrote the class/structure generation code for the - Tcl module. Now, a small set of runtime functions are used - to implement the functionality for all classes (instead of a - massive amount of runtime code being generated for each class). - Class specific information is simply encoded in a series of - static tables. This results in a *HUGE* reduction in wrapper - code size--especially for C++. - -11/13/99: Removed the -tcl (Tcl 7.x) module. Tcl 8.0 is now several - years old and the defacto standard--no real reason to keep - supporting the old version at this point. - -11/13/99: Cleaned up -c option for Python module. The pyexp.swg file - is now gone. - -11/13/99: Fixed external declarations to work better with static linking - on Windows. Static linking should now be possible by defining - the -DSTATIC_LINK option on the command line. Patch contributed - by Alberto Fonseca. - -11/5/99 : Fixed an obscure code generation bug related to the generation - of default constructors. Bug reported by Brad Clements. - -11/5/99 : Fixed a few memory problems found by purify. - -11/5/99 : Officially deprecated the -htcl, -htk, and -plugin options - from the Tcl and Tcl8 modules. - -10/26/99: Removed unused variable from python/typemaps.i. Patch - contributed by Keith Davidson. - -8/16/99 : Added _WIN32 symbol to libraries to better support Windows. - -8/16/99 : Deprecated the Perl4 module. It is no longer included in the - distribution and no longer supported. In the entire 3 years SWIG - has been around I never received a single comment about it so I'm - assuming no one will miss it... - -8/16/99 : Modified the type-checking code to register type mappings using a - table instead of repeated calls to SWIG_RegisterMapping(). This - reduces the size of the module initialization function somewhat. - -8/15/99 : Cleaned up the pointer type-checking code in the Tcl module. - -8/15/99 : Many changes to the libraries to support runtime libraries. - -8/13/99 : Eliminated C++ compiler warning messages about extern "C" linkage. - -8/13/99 : Some cleanup of Python .swg files to better support runtime libraries - on Windows. - -8/13/99 : Modified the %pragma directive to attach pragmas declared inside - a class definition to the class itself. For example: - - class foo { - ... - %pragma(python) addtomethod = "insert:print `hello world'" - ... - } - - Most people don't need to worry about how this works. For people - writing backend modules, class-based pragmas work like this: - - lang->cpp_open_class() // Open a class - lang->cpp_pragma() // Supply pragmas - ... // Emit members - - lang->cpp_close_class() // Close the class - - All of the pragmas are passed first since they might be used to - affect the code generation of other members. Please see - the Python module for an example. Patches contributed - by Robin Dunn. - -8/13/99 : Patch to Python shadow classes to eliminate ignored - exception errors in destructors. Patch contributed - by Robin Dunn. - -8/11/99 : Minor patch to swig_lib/python/swigptr.swg (added SWIGSTATIC - declaration). Patch contributed by Lyle Johnson. - -8/11/99 : Added FIRSTKEY/NEXTKEY methods to Perl5 shadow classes - Patch contributed by Dennis Marsa. - -8/11/99 : Modified Python module so that NULL pointers are returned - and passed as 'None.' Patch contributed by Tal Shalif. - -8/10/99 : Fixed missing 'int' specifiers in various places. - -8/10/99 : Added Windows makefile for Runtime libraries. Contributed - by Bob Techentin. - -8/10/99 : Fixed minor problem in Python runtime makefile introduced - by keyword arguments. - -8/8/99 : Changed $target of perl5(out) typemap from ST(0) to - ST(argvi). Patch contributed by Geoffrey Hort. - -8/8/99 : Fixed bug in typemap checking related to the ANY keyword - in arrays and ignored arguments. Error reported by - Geoffrey Hort. - -8/8/99 : %enabledoc and %disabledoc directives can now be used - inside class/structure definitions. However, no check - is made to see if they are balanced (i.e., a %disabledoc - directive inside a class does not have to have a matching - %enabledoc in the same class). - -8/8/99 : Keyword argument handling is now supported in the Python - module. For example: - - int foo(char *bar, int spam, double x); - - Can be called from Python as - - foo(x = 3.4, bar="hello", spam=42) - - To enable this feature, run SWIG with the '-keyword' command - line option. Mixing keyword and default arguments - should work as well. Unnamed arguments are assigned names - such as "arg1", "arg2", etc... - - *** POTENTIAL INCOMPATIBILITY *** - Functions with duplicate argument names such as - bar(int *OUTPUT, int *OUTPUT) will likely cause problematic - wrapper code to be generated. To fix this, use different - names or use %apply to map typemaps to alternate names. - -8/8/99 : Handling of the 'this' pointer has been changed in Python shadow - classes. Previously, dereferencing of '.this' occurred in the - Python shadow class itself. Now, this step occurs in the C - wrappers using the following function: - - SWIG_GetPtrObj(PyObject *, void **ptr, char *type) - - This function can accept either a string containing a pointer - or a shadow class instance with a '.this' attribute of - appropriate type. This change allows the following: - - 1. The real shadow class instance for an object is - passed to the C wrappers where it can be examined/modified - by typemaps. - - 2. Handling of default/keyword arguments is now greatly - simplified. - - 3. The Python wrapper code is much more simple. - - Plus, it eliminated more than 300 lines of C++ code in the - Python module. - - *** CAVEAT : This requires the abstract object interface. - It should work with Python 1.4, but probably nothing older - than that. - - -8/8/99 : Fixed handling of "const" and pointers in classes. In particular, - declarations such as - - class foo { - ... - const char *msg; - const int *iptr; - } - - are handled as assignable variables as opposed to constant - values (this is the correct behavior in C/C++). Note: - declarations such as "char *const msg" are still unsupported. - Constants declared at the global level using const are also - broken (because I have a number of interfaces that rely upon - this behavior). - - *** POTENTIAL INCOMPATIBILITY *** This may break interfaces that - mistakenly treat 'const char *' types as constant values. - -8/8/99 : Modified the parser to support bit-fields. For example: - - typedef struct { - unsigned int is_keyword : 1; - unsigned int is_extern : 1; - unsigned int is_static : 1; - } flags; - - Bit-fields can only be applied to integer types and their - are other restrictions. SWIG performs no such type-checking - (although the C compiler will catch problems when it tries to - compile the wrapper code). - -8/8/99 : Removed trailing space of $basetype substitution in typemaps. - This is to allow things like this: - - %typemap(python, argout) spam** OUTPUT{ - ... - char* a = "$basetype_p"; - ... - } - - (Patch suggested by Nathan Dunfield). - -6/22/99 : Made a very slight tweak to the Perl5 shadow class - code that allows typemaps to alter the return type - of objects (to support polymorphic types). Patch - contributed by Drake Diedrich. - -4/8/99 : Fixed null pointer handling bug in Perl module. - Patch contributed by Junio Hamano. - -3/17/99 : Fixed bug in perl5ptr.swg for ActiveState Perl. - Patch contributed by Greg Anderson. - -2/27/99 : Eliminated segmentation fault when Swig runs on - empty files. - -2/27/99 : Added patch to Guile module to eliminate unused - variables. Contributed by Mike Simons. - -2/27/99 : Fixed problem with %addmethods returning references. - -2/27/99 : Fixed Runtime/Makefile. Patch contributed by - Mike Romberg. - -2/27/99 : Incorporated patches to the type-checker. - -2/27/99 : Fixed problem with -exportall switch and shadow classes - in Perl5 module. Patch contributed by Dennis Marsa. - -2/27/99 : Modified Perl5 module to recognize 'undef' as a NULL char *. - Patch contributed by Junio Hamano. - -2/27/99 : Fixed the Perl5 module to support the newer versions of - ActiveState Perl for Win32. - -2/27/99 : Fixed the include order of files specified with the - -I option. - -2/5/98- : Dave finishes his dissertation, goes job hunting, moves to -2/5/99 Chicago and generally thrashes about. - -Version 1.1 Patch 5 (February 5, 1998) -====================================== - -2/4/98 : Fixed a bug in the configure script when different package - locations are specified (--with-tclincl, etc...). - -2/2/98 : Fixed name-clash bug related to the switch to C macros for accessor - functions. The new scheme did not work correctly for objects - with members such as 'obj', 'val', etc... Fixed the bug by - appending the word 'swig' to macro argument names. Patch - contributed by Rudy Albachten. - -2/2/98 : Slight fix to the Perl5 module to eliminate warning messages - about 'varname used only once : possible typo'. Fix - contributed by Rudy Albachten. - -1/9/98 : Fixed a bug in the Perl 5 module related to the creation of - constants and shadow classes. - -1/9/98 : Fixed linking bug with Python 1.5 embed.i library file. - -Version 1.1 Patch 4 (January 4, 1998) -===================================== - -1/4/98 : Changed structured of the Examples directory to be more friendly - to Borland C++. - -1/4/98 : Added the function Makefile.win.bc for compiling the examples - under Borland 5.2. - -1/4/98 : Slight change to the perl5 module and C++ compilation. The - <math.h> library is now included before any Perl headers - because Perl the extern "C" linkage of math.h screws alot - of things up (especially on Windows). - -1/2/98 : Change to the Python module that reduces the number of constants - created by C++ classes, inheritance, and shadow classes. This - modification may introduce a few slight incompatibilities if - you attempt to use the non-shadow class interface with shadow - classes enabled. Patch contributed by Mike Romberg. - -1/2/98 : Support for Tcl 8.0 namespaces has been added. This *replaces* - the original SWIG mechanism that assumed [incr Tcl] namespaces. - To use namespaces, simply run SWIG with the following options - - swig -tcl -namespace foo.i - - This places everything in a namespace that matches - the module name - - swig -tcl -namespace -prefix bar foo.i - - This places everything in the namespace 'bar' - - The use of namespaces is new in Tcl 8.0. However, the wrapper code - generated by SWIG will still work with all versions of Tcl newer - than and including Tcl 7.3/Tk3.6 even if the -namespace option is - used. - - *** POTENTIAL INCOMPATIBILITY *** - This change may break existing applications that relied on the - -prefix and -namespace options. - -1/2/98 : Added the following constants to the Tcl wrapper code - - SWIG_name - Name of the SWIG module - SWIG_prefix - Prefix/namespace appended to command names - SWIG_namespace - Name of the namespace - - SWIG library writers can use these to their advantages. - -1/2/98 : Fixed a bug in the Tcl8 module related to the creation of - pointer constants (the function SWIG_MakePtr was missing from - the wrapper code). - -1/2/98 : Added the consthash.i library file to the Tcl and Tcl8 modules. - -1/1/98 : Changed and cleaned up the Python typemaps.i file. The following - significant changes were made : - - 1. The OUTPUT typemap now returns Python tuples instead of - lists. Lists can be returned as before by using the - L_OUTPUT type. If compatibility with older versions - is needed, run SWIG with the -DOUTPUT_LIST option. - - 2. The BOTH typemap has been renamed to INOUT. For backwards - compatibility, the "BOTH" method still exists however. - - 3. Output typemaps now generate less code than before. - - Changes to typemaps.i may break existing Python scripts that assume - output in the form of a list. - *** POTENTIAL INCOMPATIBILITY *** - -12/31/97: Fixed long overdue problems with the testing scripts and certain - makefiles that required the use of the bash shell. Everything should - work properly with the standard Bourne shell (sh) now. - -12/31/97: Modified typemaps to allow $basetype as a valid local variable. - This allows for all sorts of bizarre hackish typemaps that - do cool things. Patch contributed by Dominique Dumont. - -12/31/97: Switched accessor functions generated for member data to - C preprocessor macros (except in cases involving typemaps - or char *). - -12/31/97: Fixed a bug related to C++ member data involving references. - -12/31/97: Changed accessor functions for C++ member functions to - preprocessor macros. This cleans up the wrapper code - and results in fewer function definitions. - -12/31/97: Changed the default C constructor to use calloc() instead - of malloc() - -12/30/97: Changed the creation of constants in the Perl5 module. - For all practical purposes, they should work in exactly the - same way as before except that they now require much less - wrapper code. Modules containing large numbers of - constants may see greater than a 50% reduction in wrapper - code size. - -12/30/97: Modified the Python module to be more intelligent about the - creation of constants. SWIG no longer generates redundant - global variables and the size of the module initialization - function should be reduced. (Many thanks to Jim Fulton). - -12/29/97: Fixed a bug in C++ code generation related to member functions, - default arguments, and references. - -12/29/97: Fixed configure script and a few makefiles to support Python 1.5 - -12/29/97: Added 'embed15.i' library file. This file should be used to - statically link versions of Python 1.5. To make it the default, - simply copy 'swig_lib/python/embed15.i' to 'swig_lib/python/embed.i' - -Version 1.1 Patch 3 (November 24, 1997) -======================================== - -11/23/97: Fixed a bug in the Perl5 module with shadow classes and - static class functions that return class instances. - Note : The fix for this bug requires a slight restructuring of - of the .pm files created by SWIG. - -11/23/97: Fixed a bug in the Tcl/Tcl8 modules related to variable linking - of character arrays. If you declared a global variable 'char foo[10]', - the generated wrapper code would either cause a segmentation fault - immediately upon loading or weird memory corruption elsewhere. - This should now be fixed although character arrays can only be - read-only. - -11/23/97: Fixed a bug with the %import directive that caused it to - fail if files were imported from directories other than - the current working directory. - -11/23/97: Fixed incorrect diagnostic message in the ASCII documentation - module. - -11/23/97: Changed the behavior of the -o option when used with shadow - classes. If -o was used to specify both the pathname and filename - of SWIG's output such as - - swig -o /home/swig/wrapper.c -shadow -perl5 foo.i - - The wrapper code would be placed the file specified with -o, - but the .pm file and documentation would be placed in the - directory where SWIG was run. Now, these files are placed - in the same directory as the file specified with the -o option. - This change is also needed for proper operation on the - Macintosh. - -11/23/97: Added a 'this()' method to Perl5 shadow classes. This can - be used to return the normal pointer value from a shadow - class that is represented as a tied hash. To use just - invoke as a method like this : - - $l = new List; # Create an object - $ptr = $l->this(); # Get the normal pointer value - - *** NEW FEATURE *** - -11/23/97: Fixed the Tcl 8 pointer.i library file (which was completely - broken in 1.1p2). - -11/23/97: Modified the Perl5 type-checker to fix a few problems - with global variables of pointer types and to allow - tied hashes to be used interchangably with normal - pointer values. - -11/23/97: Modified the typemap mechanism to allow output - typemaps of type 'void'. These were ignored previously, - but now if you specify, - - %typemap(lang,out) void { - ... return a void ... - } - - You can change or assign a return value to the function. - -11/23/97: Fixed processing of 'bool' datatypes in the Python module. - -11/23/97: Fixed minor parsing error with C++ initializers. For example, - - class B : public A { - public: - B() : A() { ... }; - ... - } - -11/23/97: Fixed the Tcl8 module so that C functions that call back into - Tcl don't corrupt the return result object (SWIG was gathering - the result object too early which leads to problems if subsequent - Tcl calls are made). - -11/23/97: Fixed a code generation bug in the Python module when two or - more output parameters were used as the first arguments of a - function. For example : - - %include typemaps.i - void foo(double *OUTPUT, double *OUTPUT, double a); - - Previously, doing this resulted in the creation of an - extraneous comma in the output, resulting in a C syntax error. - -11/22/97: Fixed a bug when template handling that was stripping whitespace - around nested templates. For example : - - Foo<Bar<double> > - - was getting munged into Foo<Bar>> which is a syntax error in - in the C++ compiler. - -11/22/97: Fixed bugs in the Borland C++ makefiles. - -11/22/97: Fixed memory corruption bug when processing integer - arguments in Tcl8 module. - -11/21/97: Fixed a bug in the Runtime/Makefile related to Tcl 8. - -11/21/97: Fixed a bug with the %new directive and Perl5 shadow classes. - No longer generates a perl syntax error. - -11/9/97 : Changed a strncpy() to strcpy() in the pointer type-checker. - This results in a substantial performance improvement in - type-checking. - -10/29/97: Fixed a bug in the code generation of default arguments and - user-defined types. For example : - - void foo(Vector a, Vector b = d); - - should now work properly. - -Version 1.1 Patch 2 (September 4, 1997) -======================================= - -9/4/97 : Fixed problem with handling of virtual functions that - was introduced by some changes in the C++ module. - -Version 1.1 Patch 1 (August 27, 1997) -===================================== - -8/26/97 : Fixed compilation and run-time bugs with Tcl 8.0 final. - -8/21/97 : Fixed code generation bug with arrays appearing as arguments - to C++ member functions. For example : - - class Foo { - public: - void Bar(int a[20][20]); - }; - - There is still a bug using arrays with added methods - however. - -8/20/97 : Fixed a bug with generating the code for added methods - involving pass-by-value. - -8/19/97 : Modified the typemapper to substitute the '$arg' value - when declaring local variables. For example : - - %typemap(in) double * (double temp_$arg) { - ... do something ... - } - - When applied to a real function such as the following : - - void foo(double *a, double *b, double *result); - - three local variables will be created as follows : - - double temp_a; - double temp_b; - double temp_result; - - This can be used when writing multiple typemaps that need - to access the same local variables. - - -7/27/97 : Fixed a variety of problems with the %apply directive and arrays. - The following types of declarations should now work : - - %apply double [ANY] { Real [ANY] }; - %apply double [4] { double [10] }; - - A generic version of apply like this : - - %apply double { Real }; - - should now work--even if arrays involving doubles and Reals are - used later. - -7/27/97 : Changed warning message about "Array X has been converted to Y" to - only appear if running SWIG in verbose mode. - -7/27/97 : Added the variables $parmname and $basemangle to the typemap - generator. $parmname is the name of the parameter used - when the typemap was matched. It may be "" if no parameter - was used. $basemangle is a mangled version of the base - datatype. Sometimes used for array handling. - -7/27/97 : Changed the behavior of output arguments with Python shadow classes. - Originally, if a function returned an object 'Foo', the shadow class - mechanism would create code like this : - - def return_foo(): - val = FooPtr(shadowc.return_foo()) - val.this = 1 - return val - - The problem with this is that typemaps allow a user to redefine - the output behavior of a function--as a result, we can no longer - make any assumptions about the return type being a pointer or - even being a single value for that matter (it could be a list, - tuple, etc...). If SWIG detects the use of output typemaps - (either "out" or "argout") it returns the result unmodified like - this : - - def return_foo(): - val = shadowc.return_foo() - return val - - In this case, it is up to the user to figure out what to do - with the return value (including the possibility of converting it - into a Python class). - -7/26/97 : Fixed a parsing problem with types like 'unsigned long int', - 'unsigned short int', etc... - -7/24/97 : Minor bug fix to Tcl 8 module to parse enums properly. Also - fixed a memory corruption problem in the type-checker. - (patch contributed by Henry Rowley. - -7/24/97 : Added Python-tuple typemaps contributed by Robin Dunn. - -7/24/97 : Incorporated some changes to the Python module in support of - Mark Hammond's COM support. I'm not entirely sure they - work yet however. Needs documentation and testing. - -7/24/97 : Fixed code generation bugs when structures had array members - and typemaps were used. For example : - - %typemap(memberin) double [20][20] { - ... get a double [20][20] ... - } - struct Foo { - double a[20][20]; - } - - Originally, this would generate a compiler-type error when - the wrapper code was compiled. Now, a helper function like - this is generated : - - double *Foo_a_set(Foo *a, double val[20][20]) { - ... memberin typemap here ... - return (double *) val; - } - - When writing typemaps, one can assume that the source variable - is an array of the *same* type as the structure member. This - may break some codes that managed to work around the array bug. - *** POTENTIAL INCOMPATIBILITY *** - -7/13/97 : Fixed bug in Perl5 module when using C global variables that - are pointers. When used in function calls and other operations, - the value of the pointer would be invalid---causing core - dumps and other problems. SWIG implements global variables - using Perl magic variables. As it turns out, the error - was caused by the fact that the pointer-extraction code - was somehow bypassing the procedure used to resolve magical - variables (hence, leaving the value undefined). To fix - the problem, SWIG now explicitly resolves magic before - extracting pointer values. - -7/12/97 : Eliminated the last remnants of free() and malloc() from - the SWIG compiler. - -7/12/97 : Fixed parsing problems with typemaps involving arrays and - temporary variables of arrays. Also made it possible for - SWIG to handle typemaps like this : - - %typemap(in) double [ANY] (double temp[$dim0]) { - ... store data in temp[$dim0] ... - } - - Not only does this typemap match any double [] array, it - creates a local variable with precisely the right dimensions. - (ie. $dim0 gets filled in with the real number of dimensions). - Of course, off the record, this will be a way to add more - functionality to the typemaps.i libraries. - -7/9/97 : Fixed some problems with Perl5, static linking, and shadow - classes. When statically linking multiple modules together, write - a top-level interface file like this when shadow classes are not - used : - - %module swig, foo, bar, glob; - %include perlmain.i - - When shadow classes are used, the module names have an extra 'c' - appended so it should read as : - - %module swig, fooc, barc, globc; - %include perlmain.i - - When linking multiple modules, consider using the SWIG runtime - library. - -7/8/97 : Incorporated fixed versions of the Borland C++ Makefiles. - -7/8/97 : First cut at trying to eliminate excessive compiler warnings. - As it turns out, alot of warnings go away if you just make - declarations like this - - clientData = clientData; - - in the resulting wrapper code. Most compilers should just - ignore this code (at least would can hope). - -7/8/97 : Fixed bizarre code generation bug with typemaps and C++ classes. - In some cases, typemaps containing printf formatting strings such as - - %typemap(memberout) int * { - printf("%d",42); - } - - Would generate completely bogus code with garbage replacing - the '%d'. Caused by one faulty use of printf (wasn't able to find - any other occurrences). - -7/7/97 : Fixed bug in Python shadow class generation with non-member - functions that are returning more than one value. - -7/7/97 : Incorporated modifications to make SWIG work with Guile 1.2. - Still need to test it out, but it is rumored to work. - -7/2/97 : Fixed some bugs related to output arguments and Python shadow - classes. If an output argument is detected, SWIG assumes - that the result is a list and handles it appropriately. - If the normal return type of an function is an object, - it will be converted into a shadow class as before, but - with the assumption that it is the first element of a - list. *** NOTE : This behavior has been subsequently changed *** - -6/29/97 : Changed EXPORT to SWIGEXPORT in all of the language modules. - Should provide better compatibility with Windows. - -6/29/97 : Modified Python shadow classes so that output arguments - work correctly (when typemaps are used). - -Version 1.1 (June 24, 1997) -=========================== - -6/24/97 : Fixed Objective-C constructor bug when working with Perl5 - shadow classes. - -6/23/97 : Fixed some parsing problems with Objective-C. Declarations - such as the following should work now : - - - foo : (int) a with: (int) b; - -6/22/97 : Added SWIG Runtime library. This library contains - the SWIG pointer type-checker and support functions - that are normally included in every module. By using - the library, it is easier to work with multiple SWIG - generated modules. - -6/22/97 : Fixed minor bug in Perl5 module related to static linking - of multiple modules. - -6/22/97 : Fixed some bugs with the %import directive. When used with - Perl5 shadow classes, this generates a 'require' statement - to load in external modules. - -6/22/97 : Added -swiglib option. This prints out the location of the - SWIG library and exits. This option is only really useful to - configuration tools that are looking for SWIG and its library - location (e.g. autoconf, configure, etc...). - -6/21/97 : Fixed export bug with Perl5.004 on Windows-NT. - -6/20/97 : Minor change to code generation of class/structure members in - order to work better with typemaps. Should have no noticable - impact on existing SWIG modules. - -6/19/97 : Added -t option. This allows SWIG to load a typemap file before - processing any declarations. For example : - - swig -t typemaps.i -python example.i - - At most, only one typemap file can be specified in this manner. - *** NEW FEATURE *** - -6/18/97 : Need a Makefile fast? Type - - swig [-tcl, -perl5, -python] -co Makefile - - and you will get a Makefile specific to that target language. - You just need to modify it for your application and you're - ready to run. - -6/18/97 : Completed the -ci option. This option checks a file into the - SWIG library. It should be used in conjunction with a - language option. For example : - - swig -tcl -ci foobar.i - - Checks the file foobar.i into the Tcl part of the library. - In order to check a file into the general library (accessible - to all languages modules), do the following - - swig -ci -o ../foobar.i foobar.i - - (Admittedly this looks a little strange but is unavoidable). - The check-in option is primarily designed for SWIG maintenance - and library development. The command will fail if the user does - not have write permission to the SWIG library. Third party library - extensions can easily install themselves by simply providing - a shell script that uses 'swig -ci' to install the appropriate - library files. It is not necessary to know where the SWIG library - is located if you use this mechanism. - *** NEW FEATURE *** - -6/16/97 : Fixed a bug in shadow class generation when %name() was applied - to a class definition. Unfortunately, fixing the bug required - a change in the Language C API by adding an extra argument to - the Language::cpp_class_decl() function. This may break - SWIG C++ extensions. - *** POTENTIAL INCOMPATIBILITY *** - -6/15/97 : Added a warning message if no module name is specified with the - %module directive or -module option. - -6/15/97 : Fixed line number bug when reporting errors for undefined - base classes. - -6/15/97 : Added new %rename directive. This allows the forward declaration - of a renaming. For example : - - %rename OldName NewName; - - .... later ... - int OldName(int); - - Unlike %name, %rename will rename any occurrence of the old name. - This applies to functions, variables, class members and so forth. - There is no way to disable %rename once set, but you can change the - name by redeclaring it to something else. - *** NEW FEATURE *** - -6/15/97 : Improved the implementation of the %name directive so that it - could be used with conditional compilation : - - #ifdef SWIG - %name(NewName) - #endif - int OldName(int); - -6/15/97 : Added support for functions with no return datatype. In this case, - SWIG assumes a return type of 'int'. - -6/11/97 : Improved error reporting in the parser. It should be a little - less sensitive to errors that occur inside class definitions - now. Also reports errors for function pointers. - -6/11/97 : Made '$' a legal symbol in identifiers. This is to support - some Objective-C libraries. Some compilers (such as gcc) may also - allow identifiers to contain a $ in C/C++ code as well (this is - an obscure feature of C). When '$' appears in identifier, SWIG - remaps it to the string '_S_' when creating the scripting language - function. Thus a function 'foo$bar' would be called 'foo_S_bar'. - -6/11/97 : Fixed bug in Python shadow classes with __repr__ method. If - supplied by the user, it was ignored, but now it should work. - -6/9/97 : Fixed the Tcl 8.0 module to work with Tcl 8.0b1. SWIG is no - longer compatible with *any* alpha release of Tcl 8.0. - *** POTENTIAL INCOMPATIBILITY *** - -6/7/97 : Put a maximal error count in (currently set to 20). SWIG will bail out - if it generates more errors than this (useful for preventing SWIG - from printing 4000 syntax errors when it gets confused). - -6/7/97 : Fixed segmentation fault when parsing variable length arguments. - -6/7/97 : Minor change to Perl5 module. C++ static functions are now - put in the same package as their class when using shadow classes. - -6/7/97 : Centralized the naming of functions, members, wrappers etc... By - centralizing the naming scheme, it should be possible to make - some multi-file optimizations. Also, it should be possible to - change SWIG's naming scheme (perhaps a new feature to be added - later). - -6/2/97 : Added 'arginit' typemap. This can be used to assign initial values - to function arguments. Doing so makes it somewhat easier to detect - improper argument passing when working with other typemaps. - -6/2/97 : Fixed code generation bug when read-only variables were inherited - into other classes. Under inheritance, the variables would - become writable, but this has now been corrected. - -5/30/97 : An empty %name() directive is no longer allowed or supported. - This directive was originally used to strip the prefix - off of a class or structure. Unfortunately, this never really - seemed to work right and it complicated the C++ code generator - significantly. As far as I can tell no one uses it, so it - is now history. *** POTENTIAL INCOMPATIBILITY *** - -5/28/97 : Fixed a parsing bug with #define and C++ comments. Declarations - such as the following now work properly : - - #define CONST 4 // A Comment - -5/28/97 : Made some performance improvements to the SWIG String class. - (only affects the SWIG compiler itself). - -5/28/97 : Modified the parser to skip template definitions and issue a - warning message. - -5/28/97 : Preliminary support for parameterized types added (ie. templates). - Types such as the following should pass through the SWIG compiler - - void foo(vector<complex> *a, vector<double> *b); - - When used, the entire name 'vector<complex>' becomes the name - of the datatype. Due to space limitations in datatype - representations, the name should not exceed 96 characters. - - Note : This is only part of what is needed for template support. - Template class definitions are not yet supported by SWIG. - - The template notation above may also be used when specifying - Objective-C protocol lists. - *** NEW FEATURE *** - -5/24/97 : First cut at Objective-C support added. As it turns out, almost - everything can be handled with only a few minor modifications to - the C++ module. - *** NEW FEATURE *** - -5/23/97 : Fixed repeated definition bug in multiple inheritance handling - when multiple base classes share a common base class (ie. - the evil diamond). - -5/21/97 : Fixed rather embarrassing typo that worked its way into the - Tests/Build directory. - -5/19/97 : Fixed code generation bug when using native methods and - shadow classes with Python and Perl5 modules. - -5/19/97 : Modified the %apply directive slightly so that it would work - with pointers a little better. For example : - - %apply unsigned long { DWORD }; - - Applies *all* typemaps associated with "unsigned long" to - "DWORD". This now includes pointers to the two datatypes. - For example, a typemap applied to "unsigned long **" would - also be applied to any occurrence of "DWORD **" as well. - -5/19/97 : Fixed an ownership assignment bug in the Perl5 module when - class members were returning new objects belonging to - different classes. - -5/17/97 : Added a few more typemap variables. - - $name - Name of function/variable/member - $basetype - Base datatype (type without pointers) - $argnum - Argument number - -5/16/97 : Fixed embarrassing underscore error in local variable - allocator. - -5/16/97 : Fixed namespace clash bug in parameterized typemaps - when creating arrays as new local variables. - -5/15/97 : Fixed some bugs with inheritance of added methods across - multiple files. SWIG now uses names of base classes - when generating such functions. - -5/14/97 : Finished support for default typemaps. Primarily used - internally, they can be used to match the basic - built-in datatypes used inside of SWIG. You can - specify them in interface files as well like this : - - %typemap(tcl,in) int SWIG_DEFAULT_TYPE { - $target = atoi($target); - } - - Unlike normal typemaps, this default map will get applied - to *all* integer datatypes encountered, including those - renamed with typedef, etc... - -5/13/97 : Fixed substring bug in type checker. - -5/12/97 : Fixed bug in parameterized typemaps when declaring local - variables of structures. - -Version 1.1 Beta6 (May 9, 1997) -=============================== - -5/9/97 : Fixed bizarre NULL pointer handling bug in Perl5 module. - -5/8/97 : Fixed mysterious segmentation fault when running SWIG on an - empty file. - -5/7/97 : The code generator will now replace the special symbol "$cleanup" - with the cleanup code specified with the "freearg" typemap. - This change needed to properly manage memory and exceptions. - -5/5/97 : Added the 'typemaps.i' library file. This contains a - variety of common typemaps for input values, pointers, - and so on. - -5/5/97 : Changed behavior of "argout" typemap in Python module. - Old versions automatically turned the result into a - Python list. The new version does nothing, leaving the - implementation up to the user. This provides more flexibility - but may break older codes that rely on typemaps. - *** POTENTIAL INCOMPATIBILITY *** - -5/5/97 : Fixed bug in Python module related to the interaction of - "argout" and "ignore" typemaps. - -5/5/97 : Fixed bug in Python module that would generate incorrect code - if all function arguments are "ignored". - -5/4/97 : Added %apply and %clear directives. These form a higher level - interface to the typemap mechanism. In a nutshell, they - can be used to change the processing of various datatypes without - ever having to write a typemap. See the SWIG documentation - for more details. ** NEW FEATURE ** - -5/4/97 : Added a local variable extension to the typemap handler. - For example : - - %typemap(tcl,in) double *(double temp) { - temp = atof($source); - $target = &temp; - } - - In this case, 'temp' is a local variable that exists - in the entire wrapper function (not just the typemap - code). This mechanism provides better support for - certain types of argument handling and also makes it - possible to write thread-safe typemaps. Any number - local variables can be declared by supplying a comma - separated list. Local variables are guaranteed to be - unique, even if the same typemap is applied many times - in a given function. - ** Not currently supported in Perl4 or Guile modules. - -5/2/97 : Fixed processing of %ifdef, %endif, %if, etc... (These are - SWIG equivalents of the C preprocessor directives that - can pass through the C preprocessor without modification). - -5/2/97 : Fixed major (but subtle) bug in the run-time type checker - related to searching and type-checking for C++ inheritance. - To make a long story short, if you had two classes named - "Foo" and "FooObject" the type checker would sometimes - get confused and be unable to locate "Foo" in an internal - table. - -5/2/97 : Fixed some bugs in the -co option. - -4/24/97 : Pointer library added to the SWIG library. - -4/19/97 : Added the %new directive. This is a "hint" that can be used - to tell SWIG that a function is returning a new object. For - example : - - %new Foo *create_foo(); - - This tells SWIG that create_foo() is creating a new object - and returning a pointer to it. Many language modules may - choose to ignore the hint, but when working with shadow classes, - the %new is used to handle proper ownership of objects. - - %new can also be used with dynamically allocated strings. - For example : - - %new char *create_string(); - - When used, all of the language modules will automatically cleanup - the returned string--eliminating memory leaks. - ** NEW FEATURE ** - -4/19/97 : Added a new typemap "newfree". This is used in conjunction with - the %new directive and can be used to change the method by which - a new object returned by a function is deleted. - -4/19/97 : The symbol "__cplusplus" is now defined in the SWIG interpreter - when running with the -c++ option. - -4/17/97 : Added support for static member functions when used inside the - %addmethods directive. - -4/15/97 : Added a special typemap symbol PREVIOUS that can be used to - restore a previous typemap. For example : - - %typemap(tcl,in) int * = PREVIOUS; - - This is primarily used in library files. - -4/13/97 : Added %pragma directive for Perl5 module. Two new pragmas are - available : - - %pragma(perl5) code = "string" - %pragma(perl5) include = "file.pl" - - Both insert code into the .pm file created by SWIG. This can - be used to automatically customize the .pm file created by SWIG. - -4/13/97 : Scanner modified to only recognize C++ keywords when the -c++ - option has been specified. This provides support for C programs - that make use of these keywords for identifiers. - SWIG may need to be explicitly run with the -c++ option when - compiling C++ code (this was allowed, but not recommended in - previous versions). **POTENTIAL INCOMPATIBILITY** - -4/11/97 : Fixed a rather nasty bug in the Perl5 module related to using - variable linking with complex datatypes and pointers. On Unix, - code would work (somehow), but would cause an access violation - under Windows-NT. The fix should correct the problem, - but there may still be a problem using global variables of - complex datatypes in conjunction with shadow classes. Fortunately, - this sort of thing seems to be relatively rare (considering - that the bug has been around for more than a year - yikes!). - -4/11/97 : Fixed bizarre constant evaluation bug in Perl5 code generation - when running under Windows-NT. - -4/8/97 : Bug when using default arguments and C++ references fixed. - -4/8/97 : Fixed code generation bugs in Python and Perl5 modules related to - using class renaming (applying the %name directive to a class - definition) and shadow classes. - -4/7/97 : Fixed minor bugs in swigptr.swg, tcl8ptr.swg, and perl5ptr.swg to - prevent infinite loops when weird datatypes are passed. - -3/29/97 : 'Makefile.win' added. This is used to build most of the examples - in the Examples directory under Windows NT/95. - -3/27/97 : Fixes to SWIG's error return codes. SWIG now returns non-zero - exit codes for certain kinds of errors (which makes it more - friendly to makefiles). An overhaul of the error handling - is on the to-do list and will probably show up in a later release. - -3/25/97 : Bug fix. "freearg" and "argout" typemaps have been fixed in - the Perl5 module. In previous versions, function input parameters - and function output parameters shared the same memory space--causing - all sorts of nasty problems when trying to pass perl values by - reference. SWIG now internally makes a "copy" (which is really - just a pointer) of affected parameters and uses that. This - is done transparently so there is no noticable impact on any - SWIG generated modules. This change is probably only noticable - to expert users. - -3/25/97 : Added type-check to verbose and stat mode. SWIG will now generate a list - of all datatypes that were used but undefined (useful for tracking - down weird bugs). This is enabled with the -v option (which - is now officially known as "overly verbose" mode) or the -stat option. - -3/25/97 : Slight change to the parser to make include guards work correctly. - For example : - - #ifndef INTERFACE_I - #define INTERFACE_I - %module foobar.i - ... declarations ... - #endif - -3/24/97 : %checkout directive added. This allows an interface file to - extract files from the SWIG library and place them in the - current directory. This can be used to extract scripts and - other helper code that might be associated with library files. - For example : - - %checkout array.tcl - - Will look for a file "array.tcl" in the library and copy it - to the current directory. If the file already exists in the - directory, this directive does nothing (it will not overwrite an - existing file). This only an experimental feature for now. - -3/24/97 : SWIG will now look in the SWIG Library for a file if it can't - find it in the current directory. As a result, it is easy to - make modules from SWIG library files. For example, if you - want to make a Python module from the SWIG timers library, just - type this in any directory : - - swig -python timers.i - - You will get the files timers_wrap.c and timers_wrap.doc in - the current directory that you can now compile. The file - remains in the SWIG library (although you can check it out - using the -co option). *** New Feature *** - -3/24/97 : -co option added to SWIG to allow easy access to the SWIG library. - When used, this instructs SWIG to check out a library file and - place it in the current directory. For example : - - unix > swig -co array.i - array.i checked out from the SWIG library - unix > - - Once in your directory you can customize the file to suit your - particular purposes. The checkout option makes it easy to - grab library files without knowing anything about the SWIG - installation, but it also makes it possible to start - including scripts, C code, and other miscellaneous files - in the library. For example, you could put a cool script - in the library and check it out whenever you wanted to use it. - *** New Feature *** - -3/24/97 : #pragma export directives added to Tcl output for compiling - shared libraries on the Mac. - -3/24/97 : Minor changes to wish.i and tclsh.i library files to provide - support for the Macintosh. - -3/19/97 : SWIG's policy towards NULL pointers has been relaxed. The - policy of requiring a special compiler directive -DALLOW_NULL - to use NULL pointers is no longer supported. While this may - seem "unsafe", it turns out that you can use a "check" - typemap to achieve some safety. For example : - - %typemap(perl5,check) Node * { - if (!$target) - croak("NULL Pointers not allowed."); - } - - This prevents any NULL value of a "Node *" pointer to be - passed to a function. (I think this is much cleaner - than the old -DALLOW_NULL hack anyways). - -3/19/97 : Fixed pointer handling errors in Perl5 module. Modules no - longer core dump when a Perl reference is inadvertently - passed in as a C pointer. - -3/18/97 : Added a "check" typemap. This can be used to check the - validity of function input values. For example : - - %typemap(perl5,check) int posint { - if ($target < 0) - croak("Argument is not a positive integer"); - } - -3/18/97 : Added an $arg variable to Tcl typemaps. This makes it easier - to return argument values by "reference". - -3/18/97 : Fixed a code generation bug when using C++ references and - the %addmethods directive. - -3/18/97 : Fixed a few glitches in the typemap module with respect to - chaining. For example : - - %typemap(tcl,in) int { - $in // Inserts prexisting typemap - printf("Received a %d\n", $target); - } - - This has been allowed for quite some time, but didn't work - if no existing typemap was defined. Now, it still doesn't - work if no existing typemap is defined, but it issues a - warning message. There is some support using default typemaps, - but none of the language modules take advantage of it. This - should be considered experimental at this time. - -Version 1.1b5 Patch 1 (March 16, 1997) -====================================== - -3/16/97 : Fixed references bug with C++ code generation. - -3/16/97 : Fixed initialization bug in the documentation system that - was causing weird problems. - -3/16/97 : Fixed fatal bug with -c option in the Python module. - -3/13/97 : Fixed bug in the documentation system involving the %text directive - and sorting. In the old system, %text entries would float to the - top of a section because they were "nameless". Now they are - attached to the previous declaration and will stay in the proper - location relative to the previous entry. - -Version 1.1b5 (March 12, 1997) -============================== - -3/11/97 : Fixed compilation problems introduced by Tcl/Tk 8.0a2. - *** INCOMPATIBILITY *** SWIG no longer works with Tcl/Tk 8.0a1. - -3/10/97 : Fixed bug with ignored arguments and C++ member functions in - the Python module. - -3/9/97 : Parsing bugs with nested class definitions and privately - declared nested class definitions fixed. - -3/9/97 : Fixed a few minor code generation bugs with C++ classes and - constructors. In some cases, the resulting wrapper code - would not compile properly. SWIG now attempts to use - the default copy constructor instead. - -3/8/97 : Added a -l option to SWIG that allows additional SWIG library files - to be grabbed without having them specified in the interface file. - This makes it easier to keep the interface file clean and move certain - options into a Makefile. For example : - - swig -tcl example.i # Build a normal Tcl extension - swig -tcl -lwish.i example.i # Build it as a wish extension - # by including the 'wish.i' file. - - swig -python example.i # Build a dynamically loaded extension - swig -python -lembed.i example.i # Build a static extension - - These kinds of options could previously be accomplished with - conditional compilation such as : - - %module example - ... - #ifdef STATIC - %include embed.i - #endif - -3/8/97 : Incorporated changes to Guile module to use the new gh interface - in FSF Guile 1.0. The older gscm interface used in Cygnus - Guile releases is no longer supported by SWIG. - -3/8/97 : Cleaned up the Tcl Netscape plugin example. It should work with - version 1.1 of the plugin now. - -3/8/97 : Added better array support to the typemap module. The keyword - ANY can now be used to match any array dimension. For example : - - %typemap(tcl,in) double [ANY] { - ... get an array ... - } - - This will match any single-dimensional double array. The array - dimension is passed in the variables $dim0, $dim1, ... $dim9. For - example : - - %typemap(tcl,in) double [ANY][ANY][ANY] { - printf("Received a double[%d][%d][%d]\n",$dim0,$dim1,$dim2); - } - - Any typemap involving a specific array dimension will override any - specified with the ANY tag. Thus, a %typemap(tcl,in) double [5][4][ANY] {} - would override a double [ANY][ANY][ANY]. However, overuse of the ANY - tag in arrays of high-dimensions may not work as you expect due to - the pattern matching rule used. For example, which of the following - typemaps has precedence? - - %typemap(in) double [ANY][5] {} // Avoid this! - %typemap(in) double [5][ANY] {} - -3/7/97 : Fixed a number of bugs related to multi-dimensional array handling. - Typedefs involving multi-dimensional arrays now works correctly. - For example : - - typedef double MATRIX[4][4]; - - ... - extern double foo(MATRIX a); - - Typecasting of pointers into multi-dimensional arrays is now - implemented properly when making C/C++ function calls. - -3/6/97 : Fixed potentially dangerous bug in the Tcl Object-oriented - interface. Well, actually, didn't fix it but issued a - Tcl error instead. The bug would manifest itself as follows: - - % set l [List] # Create an object - ... - % set m [List -this $l] # Make $m into an object assuming $l - # contains a pointer. - # Since $m == $l, $l gets destroyed - # (since its the same command name) - % $m insert Foo - Segmentation fault # Note : the list no longer exists! - - Now, an error will be generated instead of redefining the command. - As in : - - % set l [List] - ... - % set m [List -this $l] - Object name already exists! - - Use catch{} to ignore the error. - -3/3/97 : Better support for enums added. Datatypes of 'enum MyEnum' - and typedefs such as 'typedef enum MyEnum Foo;' now work. - -3/3/97 : Parser modified to ignore constructor initializers such as : - - class Foo : public Bar { - int a,b; - public: - Foo(int i) : a(0), b(i), Bar(i,0) { }; - }; - -3/3/97 : Modified parser to ignore C++ exception specifications such as : - - int foo(double) throw(X,Y); - -3/3/97 : Added %import directive. This works exactly like %extern - except it tells the language module that the declarations are - coming from a separate module. This is usually only - needed when working with shadow classes. - -3/2/97 : Changed pointer type-checker to be significantly more - efficient when working with derived datatypes. This - has been accomplished by storing type-mappings in sorted - order, using binary search schemes, and caching recently - used datatypes. For SWIG generated C++ modules that - make a large number of C function calls with derived types, - this could result in speedups of between 100 and 50000 percent. - However, due to the required sorting operation, module - loading time may increased slightly when there are lots of - datatypes. - -3/2/97 : Fixed some C++ compilation problems with Python - embed.i library files. - -2/27/97 : Slight change to C++ code generation to use copy constructors - when returning complex data type by value. - -2/26/97 : Fixed bug in Python module with -c option. - -2/26/97 : Slight tweak of parser to allow trailing comma in enumerations - such as - - enum Value (ALE, STOUT, LAGER, }; - -2/25/97 : Fixed code generation bug in Tcl module when using the - %name() directive on a classname. - -2/25/97 : Finished code-size optimization of C++ code generation with - inheritance of attributes. Inherited attributes now - only generate one set of wrapper functions that are re-used - in any derived classes. This could provide big code - size improvements in some scripting language interfaces. - -2/25/97 : Perl5 module modified to support both the Unix and Windows - versions. The windows version has been tested with the - Activeware port of Perl 5.003 running under Windows 95. - The C source generated by SWIG should compile without - modification under both versions of Perl, but is now - even more hideous than before. - -2/25/97 : Modified parser to allow scope resolution operation to - appear in expressions and default arguments as in : - - void foo(int a = Bar::defvalue); - -2/25/97 : Fixed bug when resolving symbols inside C++ classes. - For example : - - class Foo { - public: - enum Value {ALE, STOUT, LAGER}; - ... - void defarg(Value v = STOUT); - - }; - -2/24/97 : Fixed bug with member functions returning void *. - -2/23/97 : Modified Python module to be better behaved under Windows - - - Module initialization function is now properly exported. - It should not be necessary to explicitly export this function - yourself. - - - Bizarre compilation problems when compiling the SWIG wrapper - code as ANSI C under Visual C++ 4.x fixed. - - - Tested with both the stock Python-1.4 distribution and Pythonwin - running under Win95. - -2/19/97 : Fixed typedef handling bug in Perl5 shadow classes. - -2/19/97 : Added exception support. To use it, do the following : - - %except(lang) { - ... try part of the exception ... - $function - ... catch part of exception ... - } - - $function is a SWIG variable that will be replaced by the - actual C/C++ function call in a wrapper function. Thus, - a real exception specification might look like this : - - %except(perl5) { - try { - $function - } catch (char *& sz) { - ... process an exception ... - } catch(...) { - croak("Unknown exception. Bailing out..."); - } - } - -2/19/97 : Added support for managing generic code fragments (needed - for exceptions). - -2/19/97 : Fixed some really obscure typemap scoping bugs in the C++ - handler. - -2/18/97 : Cleaned up perlmain.i file by removing some problematic, - but seemingly unnecessary declarations. - -2/18/97 : Optimized handling of member functions under inheritance. - SWIG can now use wrapper functions generated for a - base class instead of regenerating wrappers for - the same functions in a derived class. This could - make a drastic reduction in wrapper code size for C++ - applications with deep inheritance hierarchies and - lots of functions. - -2/18/97 : Additional methods specified with %addmethods can now - be inherited along with normal C++ member functions. - -2/18/97 : Minor internal fixes to make SWIG's string handling a little - safer. - -2/16/97 : Moved some code generation of Tcl shadow classes to - library files. - -2/16/97 : Fixed documentation error of '-configure' method in - Tcl modules. - -2/16/97 : Modified Perl5 module slightly to allow typemaps - to use Perl references. - -2/12/97 : Fixed argument checking bug that was introduced by - default arguments (function calls with too many - arguments would still be executed). Functions now - must have the same number of arguments as C version - (with possibility of default/optional arguments - still supported). - -2/12/97 : Fixed default argument bug in Perl5 module when - generating wrapper functions involving default - arguments of complex datatypes. - -2/12/97 : Fixed typemap scoping problems. For example : - - %typemap(tcl,in) double { - .. get a double .. - } - - class Foo { - public: - double bar(double); - } - - %typemap(tcl,in) double { - .. new get double .. - } - - Would apply the second typemap to all functions in Foo - due to delayed generation of C++ wrapper code (clearly this - is not the desired effect). Problem has been fixed by - assigning unique numerical identifiers to every datatype in - an interface file and recording the "range of effect" of each - typemap. - -2/11/97 : Added support for "ignore" and "default" typemaps. Only use - if you absolutely know what you're doing. - -2/9/97 : Added automatic creation of constructors and destructors for - C structs and C++ classes that do not specify any sort of - constructor or destructor. This feature can be enabled by - running SWIG with the '-make_default' option or by inserting - the following pragma into an interface file : - - %pragma make_default - - The following pragma disables automatic constructor generation - - %pragma no_default - -2/9/97 : Added -make_default option for producing default constructors - and destructors for classes without them. - -2/9/97 : Changed the syntax of the SWIG %pragma directive to - %pragma option=value or %pragma(lang) option=value. - This change makes the syntax a little more consistent - between general pragmas and language-specific pragmas. - The old syntax still works, but will probably be phased - out (a warning message is currently printed). - -2/9/97 : Improved Tcl support of global variables that are of - structures, classes, and unions. - -2/9/97 : Fixed C++ compilation problem in Python 'embed.i' library file. - -2/9/97 : Fixed missing return value in perlmain.i library file. - -2/9/97 : Fixed Python shadow classes to return an AttributeError when - undefined attributes are accessed (older versions returned - a NameError). - -2/9/97 : Fixed bug when %addmethods is used after a class definition whose - last section is protected or private. - -2/8/97 : Made slight changes in include file processing to support - the Macintosh. - -2/8/97 : Extended swigmain.cxx to provide a rudimentary Macintosh interface. - It's a really bad interface, but works until something better - is written. - -1/29/97 : Fixed type-casting bug introduced by 1.1b4 when setting/getting the - value of global variables involving complex data types. - -1/29/97 : Removed erroneous white space before an #endif in the code generated - by the Python module (was causing errors on DEC Alpha compilers). - -1/26/97 : Fixed errors when using default/optional arguments in Python shadow - shadow classes. - -1/23/97 : Fixed bug with nested %extern declarations. - -1/21/97 : Fixed problem with typedef involving const datatypes. - -1/21/97 : Somewhat obscure, but serious bug with having multiple levels - of typedefs fixed. For example : - - typedef char *String; - typedef String Name; - -Version 1.1 Beta4 (January 16, 1997) -==================================== - -Note : SWIG 1.1b3 crashed and burned shortly after take off due -to a few major run-time problems that surfaced after release. -This release should fix most, if not all, of those problems. - -1/16/97 : Fixed major memory management bug on Linux - -1/14/97 : Fixed bug in functions returning constant C++ references. - -1/14/97 : Modified C++ module to handle datatypes better. - -1/14/97 : Modified parser to allow a *single* scope resolution - operator in datatypes. Ie : Foo::bar. SWIG doesn't - yet handle nested classes, so this should be - sufficient for now. - -1/14/97 : Modified parser to allow typedef inside a C++ class. - -1/14/97 : Fixed some problems related to datatypes defined inside - a C++ class. SWIG was not generating correct code, - but a new scoping mechanism and method for handling - datatypes inside a C++ class have been added. - -1/14/97 : Changed enumerations to use the value name instead - of any values that might have appeared in the interface - file. This makes the code a little more friendly to - C++ compilers. - -1/14/97 : Removed typedef bug that made all enumerations - equivalent to each other in the type checker (since - it generated alot of unnecessary code). - -Version 1.1 Beta3 (January 9, 1997) -=================================== - -Note : A *huge* number of changes related to ongoing modifications. - -1. Support for C++ multiple inheritance added. - -2. Typemaps added. - -3. Some support for nested structure definitions added. - -4. Default argument handling added. - -5. -c option added for building bare wrapper code modules. - -6. Rewrote Pointer type-checking to support multiple inheritance - correctly. - -7. Tcl 8.0 module added. - -8. Perl4 and Guile modules resurrected from the dead (well, they - at least work again). - -9. New Object Oriented Tcl interface added. - -10. Bug fixes to Perl5 shadow classes. - -11. Cleaned up many of the internal modules of the parser. - -12. Tons of examples and testing modules added. - -13. Fixed bugs related to use of "const" return values. - -14. Fixed bug with C++ member functions returning void *. - -15. Changed SWIG configuration script. - -Version 1.1 Beta2 (December 3, 1996) -==================================== - -1. Completely rewrote the SWIG documentation system. The changes - involved are too numerous to mention. Basically, take everything - you knew about the old system, throw them out, and read the - file Doc/doc.ps. - -2. Limited support for #if defined() added. - -3. Type casts are now allowed in constant expressions. ie - - #define A (int) 3 - -4. Added support for typedef lists. For example : - - typedef struct { - double x,y,z; - } Vector, *VectorPtr; - -5. New SWIG directives (related to documentation system) - - %style - %localstyle - %subsection - %subsubsection - -6. Reorganized the C++ handling and made it a little easier to - work with internally. - -7. Fixed problem with inheriting data members in Python - shadow classes. - -8. Fixed symbol table problems with shadow classes in both - Python and Perl. - -9. Fixed annoying segmentation fault bug in wrapper code - generated for Perl5. - -10. Fixed bug with %addmethods directive. Now it can be placed - anywhere in a class. - -11. More test cases added to the SWIG self-test. Documentation - tests are now performed along with other things. - -12. Reorganized the SWIG library a little bit and set it up to - self-document itself using SWIG. - -13. Lots and lots of minor bug fixes (mostly obscure, but bugs - nonetheless). - - -Version 1.1 Beta1 (October 30, 1996) -==================================== - -1. Added new %extern directive for handling multiple files - -2. Perl5 shadow classes added - -3. Rewrote conditional compilation to work better - -4. Added 'bool' datatype - -5. %{,%} block is now optional. - -6. Fixed some bugs in the Python shadow class module - -7. Rewrote all of the SWIG tests to be more informative - (and less scary). - -8. Rewrote parameter list handling to be more memory - efficient and flexible. - -9. Changed parser to ignore 'static' declarations. - -10. Initializers are now ignored. For example : - - struct FooBar a = {3,4,5}; - -11. Somewhat better parsing of arrays (although it's - usually just a better error message now). - -12. Lot's of minor bug fixes. - - -Version 1.0 Final (August 31, 1996) -=================================== - -1. Fixed minor bug in C++ module - -2. Fixed minor bug in pointer type-checker when using - -DALLOW_NULL. - -3. Fixed configure script to work with Python 1.4beta3 - -4. Changed configure script to allow compilation without - yacc or bison. - -Version 1.0 Final (August 28, 1996) -=================================== - -1. Changed parser to support more C/C++ datatypes (well, - more variants). Types like "unsigned", "short int", - "long int", etc... now work. - -2. "unions" added to parser. - -3. Use of "typedef" as in : - - typedef struct { - double x,y,z; - } Vector; - - Now works correctly. The name of the typedef is used as - the structure name. - -4. Conditional compilation with #ifdef, #else, #endif, etc... - added. - -5. New %disabledoc, %enabledoc directives allow documentation - to selectively be disabled for certain parts of a wrapper - file. - -6. New Python module supports better variable linking, constants, - and shadow classes. - -7. Perl5 module improved with better compatibility with XS - and xsubpp. SWIG pointers and now created so that they - are compatible with xsubpp pointers. - -8. Support for [incr Tcl] namespaces added to Tcl module. - -9. %pragma directive added. - -10. %addmethods directive added. - -11. %native directive added to allow pre-existing wrapper functions - to be used. - -12. Wrote configure script for SWIG installation. - -13. Function pointers now allowed with typedef statements. - -14. %typedef modified to insert a corresponding C typedef into - the output file. - -15. Fixed some problems related to C++ references. - -16. New String and WrapperFunction classes add to make generating - wrapper code easier. - -17. Fixed command line option processing to eliminate core dumps - and to allow help messages. - -18. Lot's of minor bug fixes to almost all code modules - - -Version 1.0 Beta 3 (Patch 1) July 17, 1996 -========================================== - -1.0 Final is not quite ready yet, but this release fixes a -number of immediate problems : - -1. Compiler errors when using -strict 1 type checking have been fixed. - -2. Pointer type checker now recognizes pointers of the form - _0_Type correctly. - -3. A few minor fixes were made in the Makefile - -Version 1.0 Beta 3 (June 14, 1996) -================================== - - -There are lots of changes in this release : - -1. SWIG is now invoked using the "swig" command instead of "wrap". - Hey, swig sounds cooler. - -2. The SWIG_LIB environment variable can be set to change the - location where SWIG looks for library files. - -3. C++ support has been added. You should use the -c++ option - to enable it. - -4. The %init directive has been replaced by the %module directive. - %module constructs a valid name for the initialization function - for whatever target language you're using (actually this makes - SWIG files a little cleaner). The old %init directive still works. - -5. The syntax of the %name directive has been changed. Use of the - old one should generate a warning message, but may still work. - -6. To support Tcl/Tk on non-unix platforms, SWIG imports a file called - swigtcl.cfg from the $(SWIG_LIB)/tcl directory. I don't have access - to an NT machine, but this file is supposedly allows SWIG to - produce wrapper code that compiles on both UNIX and non UNIX machines. - If this doesn't work, you'll have to edit the file swigtcl.cfg. Please - let me know if this doesn't work so I can update the file as - necessary. - -7. The SWIG run-time typechecker has been improved. You can also - now redefine how it works by supplying a file called "swigptr.cfg" - in the same directory as your SWIG interface files. By default, - SWIG reads this file from $(SWIG_LIB)/config. - -8. The documentation system has been changed to support the following : - - - Documentation order is printed in interface file order by - default. This can be overridden by putting an %alpha - directive in the beginning of the interface file. - - - You can supply additional documentation text using - - %text %{ put your text here %} - - - A few minor bugs were fixed. - -9. A few improvements have been made to the handling of command line - options (but it's still not finished). - -10. Lots of minor bug fixes in most of the language modules have been - made. - -11. Filenames have been changed to 8.3 for compatibility with a SWIG - port to non-unix platforms (work in progress). - -12. C++ file suffix is now .cxx (for same reason). - -13. The documentation has been upgraded significantly and is now - around 100 pages. I added new examples and a section on - C++. The documentation now includes a Table of Contents. - -14. The SWIG Examples directory is still woefully sparse, but is - getting better. - -Special notice about C++ ------------------------- -This is the first version of SWIG to support C++ parsing. Currently -the C++ is far from complete, but seems to work for simple cases. -No work has been done to add special C++ processing to any of -the target languages. See the user manual for details about how -C++ is handled. If you find problems with the C++ implementation, -please let me know. Expect major improvements in this area. - -Note : I have only successfully used SWIG and C++ with Tcl and -Python. - -Notice about Version 1.0Final ------------------------------ - -Version 1.0B3 is the last Beta release before version 1.0 Final is -released. I have frozen the list of features supported in version 1.0 -and will only fix bugs as they show up. Work on SWIG version 2.0 is -already in progress, but is going to result in rather significant -changes to SWIG's internal structure (hopefully for the better). No -anticipated date for version 2.0 is set, but if you've got an idea, -let me know. - -Version 1.0 Beta 2 (April 26, 1996) -=================================== - -This release is identical to Beta1 except a few minor bugs are -fixed and the SWIG library has been updated to work with Tcl 7.5/Tk 4.1. -A tcl7.5 examples directory is now included. - -- Fixed a bug in the Makefile that didn't install the libraries - correctly. - -- SWIG Library files are now updated to work with Tcl 7.5 and Tk 4.1. - -- Minor bug fixes in other modules. - - -Version 1.0 Beta 1 (April 10, 1996). -===================================== - -This is the first "semi-official" release of SWIG. It has a -number of substantial improvements over the Alpha release. These -notes are in no particular order--hope I remembered everything.... - -1. Tcl/Tk - -SWIG is known to work with Tcl7.3, Tk3.6 and later versions. -I've also tested SWIG with expect-5.19. - -Normally SWIG expects to use the header files "tcl.h" and "tk.h". -Newer versions of Tcl/Tk use version numbers. You can specify these -in SWIG as follows : - - % wrap -htcl tcl7.4.h -htk tk4.0.h example.i - -Of course, I prefer to simply set up symbolic links between "tcl.h" and -the most recent stable version on the machine. - -2. Perl4 - -This implementation has been based on Perl-4.035. SWIG's interface to -Perl4 is based on the documentation provided in the "Programming Perl" -book by Larry Wall, and files located in the "usub" directory of the -Perl4 distribution. - -In order to compile with Perl4, you'll need to link with the uperl.o -file found in the Perl4 source directory. You may want to move this -file to a more convenient location. - -3. Perl5 - -This is a somewhat experimental implementation, but is alot less -buggy than the alpha release. SWIG operates independently of -the XS language and xsubpp supplied with Perl5. Currently SWIG -produces the necessary C code and .pm file needed to dynamically -load a module into Perl5. - -To support Perl5's notion of modules and packages (as with xsubpp), -you can use the following command line options : - - % wrap -perl5 -module MyModule -package MyPackage example.i - -Note : In order for dynamic loading to be effective, you need to be -careful about naming. For a module named "MyModule", you'll need to -create a shared object file called "MyModule.so" using something like - - % ld -shared my_obj.o -o MyModule.so - -The use of the %init directive must match the module name since Perl5 -calls a function "boot_ModuleName" in order to initialize things. -See the Examples directory for some examples of how to get things -to work. - -4. Python1.3 - -This is the first release supporting Python. The Python port is -experimental and may be rewritten. Variable linkage is done through -functions which is sort of a kludge. I also think it would be nice -to import SWIG pointers into Python as a new object (instead of strings). -Of course, this needs a little more work. - -5. Guile3 - -If you really want to live on the edge, pick up a copy of Guile-iii and -play around with this. This is highly experimental---especially since -I'm not sure what the official state of Guile is these days. This -implementation may change at any time should I suddenly figure out better -ways to do things. - -6. Extending SWIG - -SWIG is written in C++ although I tend to think of the code as mostly -being ANSI C with a little inheritance thrown in. Each target language -is implemented as a C++ class that can be plugged into the system. -If you want to add your own modifications, see Appendix C of the user -manual. Then take a look at the "user" directory which contains some -code for building your own extenions. - -7. The SWIG library - -The SWIG library is still incomplete. Some of the files mentioned in -the user manual are unavailable. These files will be made available -when they are ready. Subscribe to the SWIG mailing list for announcements -and updates. - -8. SWIG Documentation - -I have sometimes experienced problems viewing the SWIG documentation in -some postscript viewers. However, the documentation seems to print -normally. I'm working on making much of the documentation online, -but this takes time. - -Version 0.1 Alpha (February 9, 1996) -==================================== - -1. Run-time type-checking of SWIG pointers. Pointers are now represented - as strings with both numeric and encoded type information. This makes - it a little harder to shoot yourself in the foot (and it eliminates - some segmentation faults and other oddities). - -2. Python 1.3 now supported. - -3. #define and enum can be used to install constants. - -4. Completely rewrote the %include directive and made it alot more powerful. - -5. Restructured the SWIG library to make it work better. - -6. Various bug fixes to Tcl, Perl4, Perl5, and Guile implementations. - -7. Better implementation of %typedef directive. - -8. Made some changes to SWIG's class structure to make it easier to expand. - SWIG is now built into a library file that you can use to make your - own extenions. - -9. Made extensive changes to the documentation. - -10. Minor changes to the SWIG parser to make it use less memory. - Also took out some extraneous rules that were undocumented and - didn't work in the first place. - -11. The SWIG library files "tclsh", "wish", "expect", etc... in the first - release have been restructured and renamed to "tclsh.i", "wish.i", - and so on. diff --git a/contrib/tools/swig/CHANGES.current b/contrib/tools/swig/CHANGES.current deleted file mode 100644 index d4883e5d6ad..00000000000 --- a/contrib/tools/swig/CHANGES.current +++ /dev/null @@ -1,79 +0,0 @@ -Below are the changes for the current release. -See the CHANGES file for changes in older releases. -See the RELEASENOTES file for a summary of changes in each release. -Issue # numbers mentioned below can be found on Github. For more details, add -the issue number to the end of the URL: https://github.com/swig/swig/issues/ - -Version 4.1.1 (30 Nov 2022) -=========================== - -2022-11-29: bero - Fix mismatch between #pragma GCC diagnostic push and pop statements - -2022-11-26: wsfulton - #2449 Fix undefined behaviour in ccache-swig calculating md4 hashes and possibly - also handling errors when CCACHE_CPP2 is set. - -2022-11-25: wsfulton - #961 Fix syntax error parsing unnamed template parameters with a default value. - -2022-11-25: olly - #2447 Fix undefined behaviour in swig's parser when handling - default parameter expressions containing method calls. - -2022-11-13: olly - [PHP] #2419 Update the documentation to reflect that SWIG 4.1.0 - dropped support for -noproxy when generating PHP wrappers. - -2022-11-05: wsfulton - #2417 Fix -swiglib for Windows when building with CMake. - -2022-11-02: wsfulton - #2418 Fix infinite loop handling non-type template parameters. - - Fixes infinite loop due to () brackets in a non-type template - parameter containing an expression. - -2022-10-28: wsfulton - [R] R rtypecheck typemaps - - Further switch to use rtypecheck typemaps instead of hard coded logic. - The full switch to typemaps is deferred until swig-4.2 as it can't be fully - backwards compatible. For now a warning is provided to help the - transition. It provides the full typemap that should be placed into - a user's interface file, for example: - - %typemap("rtype") int32_t * "integer" - void testmethod(int32_t * i); - void testmethod(); - - If there is no rtypecheck typemap for int32_t *, the warning shown is: - - example.i:7: Warning 750: Optional rtypecheck code is deprecated. Add the - following typemap to fix as the next version of SWIG will not work without it: - %typemap("rtypecheck") int32_t * %{ (is.integer($arg) || is.numeric($arg)) %} - - The warning is shown for any code that previously used "numeric", "integer" or - "character" for the rtype typemap. Copying the rtypecheck typemap as - shown into the user interface file will provide the appropriate fix and - the warning will disappear. This is important to do as swig-4.2 will - not be able to provide this helpful warning. - -2022-10-27: wsfulton - [R] Allow NULL to be used in overloaded functions taking shared_ptr. - Also fixes special variable $argtype expansion in rtypecheck typemaps. - -2022-10-26: wsfulton - [R] Improve R wrapper error message when calling overloaded methods - when incorrect types passed are passed to the overloaded methods. - - Old unhelpful error message: - Error in f(...) : could not find function "f" - - Example of new improved error message: - Error in use_count(k) : - cannot find overloaded function for use_count with argtypes (NULL) - -2022-10-26: wsfulton - [R] #2386 Fix memory leak in R shared_ptr wrappers. - Fix leak when a cast up a class inheritance chain is required. diff --git a/contrib/tools/swig/COPYRIGHT b/contrib/tools/swig/COPYRIGHT deleted file mode 100644 index e6df73ff829..00000000000 --- a/contrib/tools/swig/COPYRIGHT +++ /dev/null @@ -1,113 +0,0 @@ -SWIG Copyright and Authors --------------------------- - -Copyright (c) 1995-2011 The SWIG Developers -Copyright (c) 2005-2006 Arizona Board of Regents (University of Arizona). -Copyright (c) 1998-2005 University of Chicago. -Copyright (c) 1995-1998 The University of Utah and the Regents of the University of California - -Portions also copyrighted by: - Network Applied Communication Laboratory, Inc - Information-technology Promotion Agency, Japan - -Active SWIG Developers: - William Fulton (wsf@fultondesigns.co.uk) (SWIG core, Java, C#, Windows, Cygwin) - Olly Betts (olly@survex.com) (PHP) - Joseph Wang (joequant@gmail.com) (R) - Xavier Delacour (xavier.delacour@gmail.com) (Octave) - David Nadlinger (code@klickverbot.at) (D) - Oliver Buchtala (oliver.buchtala@gmail.com) (Javascript) - Neha Narang (narangneha03@gmail.com) (Javascript) - Simon Marchetto (simon.marchetto@scilab-enterprises.com) (Scilab) - Zackery Spytz (zspytz@gmail.com) (OCaml, SWIG core) - -Past SWIG developers and major contributors include: - Dave Beazley (dave-swig@dabeaz.com) (SWIG core, Python, Tcl, Perl) - Henning Thielemann (swig@henning-thielemann.de) (Modula3) - Matthias Köppe (mkoeppe@mail.math.uni-magdeburg.de) (Guile, MzScheme) - Luigi Ballabio (luigi.ballabio@fastwebnet.it) (STL wrapping) - Mikel Bancroft (mikel@franz.com) (Allegro CL) - Surendra Singhi (efuzzyone@netscape.net) (CLISP, CFFI) - Marcelo Matus (mmatus@acms.arizona.edu) (SWIG core, Python, UTL[python,perl,tcl,ruby]) - Art Yerkes (ayerkes@speakeasy.net) (OCaml) - Lyle Johnson (lyle@users.sourceforge.net) (Ruby) - Charlie Savage (cfis@interserv.com) (Ruby) - Thien-Thi Nguyen (ttn@glug.org) (build/test/misc) - Richard Palmer (richard@magicality.org) (PHP) - Sam Liddicott - Ananova Ltd (saml@liddicott.com) (PHP) - Tim Hockin - Sun Microsystems (thockin@sun.com) (PHP) - Kevin Ruland (PHP) - Shibukawa Yoshiki (Japanese Translation) - Jason Stewart (jason@openinformatics.com) (Perl5) - Loic Dachary (Perl5) - David Fletcher (Perl5) - Gary Holt (Perl5) - Masaki Fukushima (Ruby) - Scott Michel (scottm@cs.ucla.edu) (Java directors) - Tiger Feng (songyanf@cs.uchicago.edu) (SWIG core) - Mark Rose (mrose@stm.lbl.gov) (Directors) - Jonah Beckford (beckford@usermail.com) (CHICKEN) - Ahmon Dancy (dancy@franz.com) (Allegro CL) - Dirk Gerrits (Allegro CL) - Neil Cawse (C#) - Harco de Hilster (Java) - Alexey Dyachenko (dyachenko@fromru.com) (Tcl) - Bob Techentin (Tcl) - Martin Froehlich <MartinFroehlich@ACM.org> (Guile) - Marcio Luis Teixeira <marciot@holly.colostate.edu> (Guile) - Duncan Temple Lang (R) - Miklos Vajna <vmiklos@frugalware.org> (PHP directors) - Mark Gossage (mark@gossage.cjb.net) (Lua) - Raman Gopalan (ramangopalan@gmail.com) (eLua) - Gonzalo Garramuno (ggarra@advancedsl.com.ar) (Ruby, Ruby's UTL) - John Lenz (Guile, MzScheme updates, Chicken module, runtime system) - Baozeng Ding <sploving1@163.com> (Scilab) - Ian Lance Taylor (Go) - Dmitry Kabak (userdima@gmail.com) (Doxygen) - Vadim Zeitlin (PCRE, Python, Doxygen) - Stefan Zager (szager@gmail.com) (Python) - Vincent Couvert (Scilab) - Sylvestre Ledru (Scilab) - Wolfgang Frisch (Scilab) - -Past contributors include: - James Michael DuPont, Clark McGrew, Dustin Mitchell, Ian Cooke, Catalin Dumitrescu, Baran - Kovuk, Oleg Tolmatcev, Tal Shalif, Lluis Padro, Chris Seatory, Igor Bely, Robin Dunn, - Edward Zimmermann, David Ascher, Dominique Dumont, Pier Giorgio Esposito, Hasan Baran Kovuk, - Klaus Wiederänders, Richard Beare, Hans Oesterholt. - (See CHANGES and CHANGES.current and the bug tracker for a more complete list). - -Past students: - Songyan Feng (Chicago). - Xinghua Shi (Chicago). - Jing Cao (Chicago). - Aquinas Hobor (Chicago). - -Historically, the following people contributed to early versions of SWIG. -Peter Lomdahl, Brad Holian, Shujia Zhou, Niels Jensen, and Tim Germann -at Los Alamos National Laboratory were the first users. Patrick -Tullmann at the University of Utah suggested the idea of automatic -documentation generation. John Schmidt and Kurtis Bleeker at the -University of Utah tested out the early versions. Chris Johnson -supported SWIG's developed at the University of Utah. John Buckman, -Larry Virden, and Tom Schwaller provided valuable input on the first -releases and improving the portability of SWIG. David Fletcher and -Gary Holt have provided a great deal of input on improving SWIG's -Perl5 implementation. Kevin Butler contributed the first Windows NT -port. - -Early bug reports and patches: -Adam Hupp, Arthur Smyles, Brad Clements, Brett Williams, Buck Hodges, -Burkhard Kloss, Chia-Liang Kao, Craig Files, Dennis Marsa, Dieter Baron, -Drake Diedrich, Fleur Diana Dragan, Gary Pennington, Geoffrey Hort, Gerald Williams, -Greg Anderson, Greg Kochanski, Greg Troxel, Henry Rowley, Irina Kotlova, -Israel Taller, James Bailey, Jim Fulton, Joel Reed, Jon Travis, -Junio Hamano, Justin Heyes-Jones, Karl Forner, Keith Davidson, -Krzysztof Kozminski, Larry Virden, Luke J Crook, Magnus Ljung, Marc Zonzon, -Mark Howson, Micahel Scharf, Michel Sanner, Mike Romberg, Mike Simons, -Mike Weiblen, Paul Brannan, Ram Bhamidipaty, Reinhard Fobbe, Rich Wales, -Richard Salz, Roy Lecates, Rudy Albachten, Scott Drummonds -Scott Michel, Shaun Lowry, Steve Galser, Tarn Weisner Burton, -Thomas Weidner, Tony Seward, Uwe Steinmann, Vadim Chugunov, Wyss Clemens, -Zhong Ren. - diff --git a/contrib/tools/swig/INSTALL b/contrib/tools/swig/INSTALL deleted file mode 100644 index 666ffd9f8ae..00000000000 --- a/contrib/tools/swig/INSTALL +++ /dev/null @@ -1,226 +0,0 @@ -Basic Installation -================== - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is -disabled by default to prevent problems with accidental use of stale -cache files.) - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' -for details on some of the pertinent environment variables. - - You can give `configure' initial values for variables by setting -them in the environment. You can do that on the command line like this: - - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix - - *Note Environment Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a time -in the source code directory. After you have installed the package for -one architecture, use `make distclean' before reconfiguring for another -architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' cannot figure out -automatically, but needs to determine by the type of host the package -will run on. Usually `configure' can figure that out, but if it prints -a message saying it cannot guess the host type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS - KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the host type. - - If you are _building_ compiler tools for cross-compiling, you should -use the `--target=TYPE' option to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the host -platform (i.e., that on which the generated programs will eventually be -run) with `--host=TYPE'. In this case, you should also specify the -build platform with `--build=TYPE', because, in this case, it may not -be possible to guess the build platform (it sometimes involves -compiling and running simple test programs, and this can't be done if -the compiler is a cross compiler). - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Environment Variables -===================== - - Variables not defined in a site shell script can be set in the -environment passed to configure. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -will cause the specified gcc to be used as the C compiler (unless it is -overridden in the site shell script). - -`configure' Invocation -====================== - - `configure' recognizes the following options to control how it -operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/contrib/tools/swig/LICENSE b/contrib/tools/swig/LICENSE deleted file mode 100644 index d7a422fda11..00000000000 --- a/contrib/tools/swig/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -SWIG is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. See the LICENSE-GPL file for -the full terms of the GNU General Public license version 3. - -Portions of SWIG are also licensed under the terms of the licenses -in the file LICENSE-UNIVERSITIES. You must observe the terms of -these licenses, as well as the terms of the GNU General Public License, -when you distribute SWIG. - -The SWIG library and examples, under the Lib and Examples top level -directories, are distributed under the following terms: - - You may copy, modify, distribute, and make derivative works based on - this software, in source code or object code form, without - restriction. If you distribute the software to others, you may do - so according to the terms of your choice. This software is offered as - is, without warranty of any kind. - -See the COPYRIGHT file for a list of contributors to SWIG and their -copyright notices. diff --git a/contrib/tools/swig/LICENSE-GPL b/contrib/tools/swig/LICENSE-GPL deleted file mode 100644 index 94a9ed024d3..00000000000 --- a/contrib/tools/swig/LICENSE-GPL +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - <program> Copyright (C) <year> <name of author> - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -<http://www.gnu.org/licenses/>. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/contrib/tools/swig/LICENSE-UNIVERSITIES b/contrib/tools/swig/LICENSE-UNIVERSITIES deleted file mode 100644 index 44fcaa13f6e..00000000000 --- a/contrib/tools/swig/LICENSE-UNIVERSITIES +++ /dev/null @@ -1,95 +0,0 @@ -SWIG is distributed under the following terms: - -I. - -Copyright (c) 1995-1998 -The University of Utah and the Regents of the University of California -All Rights Reserved - -Permission is hereby granted, without written agreement and without -license or royalty fees, to use, copy, modify, and distribute this -software and its documentation for any purpose, provided that -(1) The above copyright notice and the following two paragraphs -appear in all copies of the source code and (2) redistributions -including binaries reproduces these notices in the supporting -documentation. Substantial modifications to this software may be -copyrighted by their authors and need not follow the licensing terms -described here, provided that the new terms are clearly indicated in -all files where they apply. - -IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE -UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY -PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, -EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF -THE POSSIBILITY OF SUCH DAMAGE. - -THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH -SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND -THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, -SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - - -II. - -This software includes contributions that are Copyright (c) 1998-2005 -University of Chicago. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. Redistributions -in binary form must reproduce the above copyright notice, this list of -conditions and the following disclaimer in the documentation and/or -other materials provided with the distribution. Neither the name of -the University of Chicago nor the names of its contributors may be -used to endorse or promote products derived from this software without -specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF CHICAGO AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF -CHICAGO OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -III. - -This software includes contributions that are Copyright (c) 2005-2006 -Arizona Board of Regents (University of Arizona). -All Rights Reserved - -Permission is hereby granted, without written agreement and without -license or royalty fees, to use, copy, modify, and distribute this -software and its documentation for any purpose, provided that -(1) The above copyright notice and the following paragraph -appear in all copies of the source code and (2) redistributions -including binaries reproduces these notices in the supporting -documentation. Substantial modifications to this software may be -copyrighted by their authors and need not follow the licensing terms -described here, provided that the new terms are clearly indicated in -all files where they apply. - -THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF ARIZONA AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF -ARIZONA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/contrib/tools/swig/Lib/go/go.swg b/contrib/tools/swig/Lib/go/go.swg deleted file mode 100644 index 348ae5f0d97..00000000000 --- a/contrib/tools/swig/Lib/go/go.swg +++ /dev/null @@ -1,744 +0,0 @@ -/* ------------------------------------------------------------ - * go.swg - * - * Go configuration module. - * ------------------------------------------------------------ */ - -%include <gostring.swg> - -/* Code insertion directives */ -#define %go_import(...) %insert(go_imports) %{__VA_ARGS__%} - -/* Basic types */ - -%typemap(gotype) bool, const bool & "bool" -%typemap(gotype) char, const char & "byte" -%typemap(gotype) signed char, const signed char & "int8" -%typemap(gotype) unsigned char, const unsigned char & "byte" -%typemap(gotype) short, const short & "int16" -%typemap(gotype) unsigned short, const unsigned short & "uint16" -%typemap(gotype) int, const int & "int" -%typemap(gotype) unsigned int, const unsigned int & "uint" -%typemap(gotype) long, const long & "int64" -%typemap(gotype) unsigned long, const unsigned long & "uint64" -%typemap(gotype) long long, const long long & "int64" -%typemap(gotype) unsigned long long, const unsigned long long & "uint64" -%typemap(gotype) float, const float & "float32" -%typemap(gotype) double, const double & "float64" - -%typemap(in) bool, - char, - signed char, - unsigned char, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - unsigned long long, - float, - double -%{ $1 = ($1_ltype)$input; %} - -%typemap(in) const bool &, - const char &, - const signed char &, - const unsigned char &, - const short &, - const unsigned short &, - const int &, - const unsigned int &, - const long long &, - const unsigned long long &, - const float &, - const double & -%{ $1 = ($1_ltype)&$input; %} - -%typemap(in) const long & ($*1_ltype temp), - const unsigned long & ($*1_ltype temp) -%{ temp = ($*1_ltype)$input; - $1 = ($1_ltype)&temp; %} - -%typemap(out) bool, - char, - signed char, - unsigned char, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - unsigned long long, - float, - double -%{ $result = $1; %} - -%typemap(goout) bool, - char, - signed char, - unsigned char, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - unsigned long long, - float, - double -"" - -%typemap(out) const bool &, - const char &, - const signed char &, - const unsigned char &, - const short &, - const unsigned short &, - const int &, - const unsigned int &, - const long &, - const unsigned long &, - const long long &, - const unsigned long long &, - const float &, - const double & -%{ $result = ($*1_ltype)*$1; %} - -%typemap(goout) const bool &, - const char &, - const signed char &, - const unsigned char &, - const short &, - const unsigned short &, - const int &, - const unsigned int &, - const long &, - const unsigned long &, - const long long &, - const unsigned long long &, - const float &, - const double & -"" - -%typemap(out) void "" - -%typemap(goout) void "" - -%typemap(directorin) bool, - char, - signed char, - unsigned char, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - unsigned long long, - float, - double -%{ $input = ($1_ltype)$1; %} - -%typemap(godirectorin) bool, - char, - signed char, - unsigned char, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - unsigned long long, - float, - double -"" - -%typemap(directorin) const bool &, - const char &, - const signed char &, - const unsigned char &, - const short &, - const unsigned short &, - const int &, - const unsigned int &, - const long &, - const unsigned long &, - const long long &, - const unsigned long long &, - const float &, - const double & -%{ $input = ($*1_ltype)$1; %} - -%typemap(godirectorin) const bool &, - const char &, - const signed char &, - const unsigned char &, - const short &, - const unsigned short &, - const int &, - const unsigned int &, - const long &, - const unsigned long &, - const long long &, - const unsigned long long &, - const float &, - const double & -"" - -%typemap(directorout) bool, - char, - signed char, - unsigned char, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - unsigned long long, - float, - double -%{ $result = ($1_ltype)$input; %} - -%typemap(directorout,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) const bool &, - const char &, - const signed char &, - const unsigned char &, - const short &, - const unsigned short &, - const int &, - const unsigned int &, - const long &, - const unsigned long &, - const long long &, - const unsigned long long &, - const float &, - const double & -%{ - $result = new $*1_ltype($input); - swig_acquire_pointer(&swig_mem, $result); -%} - -/* The size_t type. */ - -%typemap(gotype) size_t, const size_t & %{int64%} - -%typemap(in) size_t -%{ $1 = (size_t)$input; %} - -%typemap(in) const size_t & -%{ $1 = ($1_ltype)&$input; %} - -%typemap(out) size_t -%{ $result = $1; %} - -%typemap(goout) size_t "" - -%typemap(out) const size_t & -%{ $result = ($*1_ltype)*$1; %} - -%typemap(goout) const size_t & "" - -%typemap(directorin) size_t -%{ $input = (size_t)$1; %} - -%typemap(godirectorin) size_t "" - -%typemap(directorin) const size_t & -%{ $input = ($*1_ltype)$1; %} - -%typemap(godirectorin) const size_t & "" - -%typemap(directorout) size_t -%{ $result = ($1_ltype)$input; %} - -%typemap(directorout,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) const size_t & -%{ - $result = new $*1_ltype($input); - swig_acquire_pointer(&swig_mem, $result); -%} - -/* Member pointers. */ - -%typemap(gotype) SWIGTYPE (CLASS::*) -%{$gotypename%} - -%typemap(in) SWIGTYPE (CLASS::*) -%{ $1 = *($&1_ltype)$input; %} - -%typemap(out) SWIGTYPE (CLASS::*) -%{ - struct swig_out_type { intgo size; void* val; } *swig_out; - swig_out = (struct swig_out_type*)malloc(sizeof(*swig_out)); - if (swig_out) { - swig_out->size = sizeof($1_ltype); - swig_out->val = malloc(swig_out->size); - if (swig_out->val) { - *($&1_ltype)(swig_out->val) = $1; - } - } - $result = swig_out; -%} - -%typemap(goout) SWIGTYPE (CLASS::*) -%{ - { - type swig_out_type struct { size int; val uintptr } - p := (*swig_out_type)(unsafe.Pointer($1)) - if p == nil || p.val == 0 { - $result = nil - } else { - m := make([]byte, p.size) - a := (*[1024]byte)(unsafe.Pointer(p.val))[:p.size] - copy(m, a) - Swig_free(p.val) - Swig_free(uintptr(unsafe.Pointer(p))) - $result = &m[0] - } - } -%} - -%typemap(directorin) SWIGTYPE (CLASS::*) -%{ $input = *($&1_ltype)$1; %} - -%typemap(godirectorin) SWIGTYPE (CLASS::*) "" - -%typemap(directorout) SWIGTYPE (CLASS::*) -%{ - $result = new $1_ltype($input); - swig_acquire_pointer(&swig_mem, $result); -%} - -/* Pointers. */ - -/* We can't translate pointers using a typemap, so that is handled in - the C++ code. */ -%typemap(gotype) SWIGTYPE * -%{$gotypename%} - -%typemap(in) SWIGTYPE * -%{ $1 = *($&1_ltype)&$input; %} - -%typemap(out) SWIGTYPE * -%{ *($&1_ltype)&$result = ($1_ltype)$1; %} - -%typemap(goout) SWIGTYPE * "" - -%typemap(directorin) SWIGTYPE * -%{ *($&1_ltype)&$input = ($1_ltype)$1; %} - -%typemap(godirectorin) SWIGTYPE * "" - -%typemap(directorout) SWIGTYPE * -%{ $result = *($&1_ltype)&$input; %} - -/* Pointer references. */ - -%typemap(gotype) SWIGTYPE *const& -%{$gotypename%} - -%typemap(in) SWIGTYPE *const& ($*1_ltype temp = 0) -%{ - temp = *($1_ltype)&$input; - $1 = ($1_ltype)&temp; -%} - -%typemap(out) SWIGTYPE *const& -%{ *($1_ltype)&$result = *$1; %} - -%typemap(goout) SWIGTYPE *const& "" - -/* References. */ - -/* Converting a C++ reference to Go has to be handled in the C++ - code. */ -%typemap(gotype) SWIGTYPE & -%{$gotypename%} - -%typemap(in) SWIGTYPE & -%{ $1 = *($&1_ltype)&$input; %} - -%typemap(out) SWIGTYPE & -%{ *($&1_ltype)&$result = $1; %} - -%typemap(goout) SWIGTYPE & "" - -%typemap(directorin) SWIGTYPE & -%{ $input = ($1_ltype)&$1; %} - -%typemap(godirectorin) SWIGTYPE & "" - -%typemap(directorout) SWIGTYPE & -%{ *($&1_ltype)&$result = $input; %} - -%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE *const& -%{ static $*1_ltype swig_temp; - swig_temp = *($1_ltype)&$input; - $result = &swig_temp; %} - -%typemap(gotype) SWIGTYPE && -%{$gotypename%} - -%typemap(in, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) -%{ $1 = *($&1_ltype)&$input; -rvrdeleter.reset($1); %} - -%typemap(out) SWIGTYPE && -%{ *($&1_ltype)&$result = $1; %} - -%typemap(goout) SWIGTYPE && "" - -%typemap(directorin) SWIGTYPE && -%{ $input = ($1_ltype)&$1_name; %} - -%typemap(godirectorin) SWIGTYPE && "" - -%typemap(directorout) SWIGTYPE && -%{ *($&1_ltype)&$result = $input; %} - -/* C arrays turn into Go pointers. If we know the length we can use a - slice. */ - -%typemap(gotype) SWIGTYPE [] -%{$gotypename%} - -%typemap(in) SWIGTYPE [] -%{ $1 = *($&1_ltype)&$input; %} - -%typemap(out) SWIGTYPE [] -%{ *($&1_ltype)&$result = $1; %} - -%typemap(goout) SWIGTYPE [] "" - -%typemap(directorin) SWIGTYPE [] -%{ $input = *($1_ltype)&$1; %} - -%typemap(godirectorin) SWIGTYPE [] "" - -%typemap(directorout) SWIGTYPE [] -%{ *($&1_ltype)&$result = $input; %} - -/* Strings. */ - -%typemap(gotype) - char *, char *&, char[ANY], char[] "string" - -/* Needed to avoid confusion with the way the go module handles - references. */ -%typemap(gotype) char&, unsigned char& "*byte" -%typemap(gotype) signed char& "*int8" - -%typemap(in) - char *, char[ANY], char[] -%{ - $1 = ($1_ltype)malloc($input.n + 1); - memcpy($1, $input.p, $input.n); - $1[$input.n] = '\0'; -%} - -%typemap(in) char *& (char *temp) -%{ - temp = (char *)malloc($input.n + 1); - memcpy(temp, $input.p, $input.n); - temp[$input.n] = '\0'; - $1 = ($1_ltype)&temp; -%} - -%typemap(freearg) - char *, char[ANY], char[] -%{ free($1); %} - -%typemap(freearg) char *& -%{ free(temp$argnum); %} - -%typemap(out,fragment="AllocateString") - char *, char *&, char[ANY], char[] -%{ $result = Swig_AllocateString((char*)$1, $1 ? strlen((char*)$1) : 0); %} - -%typemap(goout,fragment="CopyString") - char *, char *&, char[ANY], char[] -%{ $result = swigCopyString($1) %} - -%typemap(directorin,fragment="AllocateString") - char *, char *&, char[ANY], char[] -%{ - $input = Swig_AllocateString((char*)$1, $1 ? strlen((char*)$1) : 0); -%} - -%typemap(godirectorin,fragment="CopyString") - char *, char *&, char[ANY], char[] -%{ - $result = swigCopyString($input) -%} - -%typemap(godirectorout) - char *, char *&, char[ANY], char[] -%{ - { - p := Swig_malloc(len($input) + 1) - s := (*[1<<30]byte)(unsafe.Pointer(p))[:len($input) + 1] - copy(s, $input) - s[len($input)] = 0 - $result = *(*string)(unsafe.Pointer(&s)) - } -%} - -%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) - char *, char *&, char[ANY], char[] -%{ $result = ($1_ltype)$input.p; %} - -/* String & length */ - -%typemap(gotype) (char *STRING, size_t LENGTH) "string" - -%typemap(in) (char *STRING, size_t LENGTH) -%{ - $1 = ($1_ltype)$input.p; - $2 = ($2_ltype)$input.n; -%} - -%typemap(out,fragment="AllocateString") (char *STRING, size_t LENGTH) -%{ $result = Swig_AllocateString((char*)$1, (size_t)$2); %} - -%typemap(goout,fragment="CopyString") (char *STRING, size_t LENGTH) -%{ $result = swigCopyString($1) %} - -%typemap(directorin,fragment="AllocateString") (char *STRING, size_t LENGTH) -%{ $input = Swig_AllocateString((char*)$1, $2); %} - -%typemap(godirectorin,fragment="CopyString") (char *STRING, size_t LENGTH) -%{ $result = swigCopyString($input) %} - -%typemap(directorout) (char *STRING, size_t LENGTH) -%{ - $1 = ($1_ltype)$input.p; - $2 = ($2_ltype)$input.n; -%} - -/* The int & type needs to convert to intgo. */ - -%typemap(gotype) int & "*int" - -%typemap(in) int & (int e) -%{ - e = (int)*$input; - $1 = &e; -%} - -%typemap(out) int & -%{ $result = new intgo(*$1); %} - -%typemap(argout) int & -%{ *$input = (intgo)e$argnum; %} - -%typemap(goout) int & "" - -%typemap(directorin) int & (intgo e) -%{ - e = (intgo)$1; - $input = &e; -%} - -%typemap(godirectorin) int & "" - -%typemap(directorout) int & -%{ - $*1_ltype f = ($*1_ltype)*$input; - $result = ($1_ltype)&f; -%} - -%typemap(directorargout) int & -%{ $1 = (int)*$input; %} - -%typemap(argout) const int & "" -%typemap(directorargout) const int & "" - -/* Enums. We can't do the right thing for enums in typemap(gotype) so - we deliberately don't define them. The right thing would be to - capitalize the name. This is instead done in go.cxx. */ - -%typemap(gotype) enum SWIGTYPE -%{$gotypename%} - -%typemap(in) enum SWIGTYPE -%{ $1 = ($1_ltype)$input; %} - -%typemap(out) enum SWIGTYPE -%{ $result = (intgo)$1; %} - -%typemap(goout) enum SWIGTYPE "" - -%typemap(directorin) enum SWIGTYPE -%{ $input = (intgo)$1; %} - -%typemap(godirectorin) enum SWIGTYPE "" - -%typemap(directorout) enum SWIGTYPE -%{ $result = ($1_ltype)$input; %} - -%typemap(directorin) enum SWIGTYPE & (intgo e) -%{ - e = (intgo)$1; - $input = ($1_ltype)&e; -%} - -%typemap(godirectorin) enum SWIGTYPE & "" - -%typemap(directorout) enum SWIGTYPE & -%{ $result = $input; %} - -/* Arbitrary type. This is a type passed by value in the C/C++ code. - We convert it to a pointer for the Go code. Note that all basic - types are explicitly handled above. */ - -%typemap(gotype) SWIGTYPE -%{$gotypename%} - -%typemap(in) SWIGTYPE ($&1_type argp) -%{ - argp = ($&1_ltype)$input; - if (argp == NULL) { - _swig_gopanic("Attempt to dereference null $1_type"); - } - $1 = ($1_ltype)*argp; -%} - -%typemap(out) SWIGTYPE -#ifdef __cplusplus -%{ *($&1_ltype*)&$result = new $1_ltype($1); %} -#else -{ - $&1_ltype $1ptr = ($&1_ltype)malloc(sizeof($1_ltype)); - memmove($1ptr, &$1, sizeof($1_type)); - *($&1_ltype*)&$result = $1ptr; -} -#endif - -%typemap(goout) SWIGTYPE "" - -%typemap(directorin) SWIGTYPE -%{ $input = new $1_ltype(SWIG_STD_MOVE($1)); %} - -%typemap(godirectorin) SWIGTYPE "" - -%typemap(directorout) SWIGTYPE -%{ $result = *($&1_ltype)$input; %} - -/* Exception handling */ - -%typemap(throws) char * -%{ _swig_gopanic($1); %} - -%typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE *, SWIGTYPE [], SWIGTYPE [ANY] -%{ - (void)$1; - _swig_gopanic("C++ $1_type exception thrown"); -%} - -/* Typecheck typemaps. The purpose of these is merely to issue a - warning for overloaded C++ functions that cannot be overloaded in - Go as more than one C++ type maps to a single Go type. */ - -%typecheck(SWIG_TYPECHECK_BOOL) /* Go bool */ - bool, - const bool & - "" - -%typecheck(SWIG_TYPECHECK_CHAR) /* Go byte */ - char, - const char &, - unsigned char, - const unsigned char & - "" - -%typecheck(SWIG_TYPECHECK_INT8) /* Go int8 */ - signed char, - const signed char & - "" - -%typecheck(SWIG_TYPECHECK_INT16) /* Go int16 */ - short, - const short & - "" - -%typecheck(SWIG_TYPECHECK_INT16) /* Go uint16 */ - unsigned short, - const unsigned short & - "" - -%typecheck(SWIG_TYPECHECK_INT32) /* Go int */ - int, - const int & - "" - -%typecheck(SWIG_TYPECHECK_INT32) /* Go uint */ - unsigned int, - const unsigned int & - "" - -%typecheck(SWIG_TYPECHECK_INT64) /* Go int64 */ - long, - const long &, - long long, - const long long & - "" - -%typecheck(SWIG_TYPECHECK_INT64) /* Go uint64 */ - unsigned long, - const unsigned long &, - unsigned long long, - const unsigned long long & - "" - -%typecheck(SWIG_TYPECHECK_FLOAT) /* Go float32 */ - float, - const float & - "" - -%typecheck(SWIG_TYPECHECK_DOUBLE) /* Go float64 */ - double, - const double & - "" - -%typecheck(SWIG_TYPECHECK_STRING) /* Go string */ - char *, - char *&, - char[ANY], - char [], - signed char *, - signed char *&, - signed char[ANY], - signed char [], - unsigned char *, - unsigned char *&, - unsigned char[ANY], - unsigned char [] - "" - -%typecheck(SWIG_TYPECHECK_POINTER) - SWIGTYPE, - SWIGTYPE *, - SWIGTYPE &, - SWIGTYPE &&, - SWIGTYPE *const&, - SWIGTYPE [], - SWIGTYPE (CLASS::*) - "" - -%apply SWIGTYPE * { SWIGTYPE *const } -%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } -%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } - -/* Go keywords. */ -%include <gokw.swg> - -%include <goruntime.swg> diff --git a/contrib/tools/swig/Lib/go/gokw.swg b/contrib/tools/swig/Lib/go/gokw.swg deleted file mode 100644 index 35428300246..00000000000 --- a/contrib/tools/swig/Lib/go/gokw.swg +++ /dev/null @@ -1,33 +0,0 @@ -/* Rename keywords. */ - -#define GOKW(x) %keywordwarn("'" `x` "' is a Go keyword",rename="X%s") `x` -#define GOBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in Go") "::"`x` - -GOKW(break); -GOKW(case); -GOKW(chan); -GOKW(const); -GOKW(continue); -GOKW(default); -GOKW(defer); -GOKW(else); -GOKW(fallthrough); -GOKW(for); -GOKW(func); -GOKW(go); -GOKW(goto); -GOKW(if); -GOKW(import); -GOKW(interface); -GOKW(package); -GOKW(range); -GOKW(return); -GOKW(select); -GOKW(struct); -GOKW(switch); -GOKW(type); -GOKW(var); - -GOBN(map); - -#undef GOKW diff --git a/contrib/tools/swig/Lib/go/goruntime.swg b/contrib/tools/swig/Lib/go/goruntime.swg deleted file mode 100644 index 7bf083bd3da..00000000000 --- a/contrib/tools/swig/Lib/go/goruntime.swg +++ /dev/null @@ -1,217 +0,0 @@ -/* ------------------------------------------------------------ - * goruntime.swg - * - * Go runtime code for the various generated files. - * ------------------------------------------------------------ */ - -%inline %{ -static void Swig_free(void* p) { - free(p); -} - -static void* Swig_malloc(int c) { - return malloc(c); -} -%} - -%insert(runtime) %{ -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> - -%} - -%insert(cgo_comment_typedefs) %{ -#include <stddef.h> -#include <stdint.h> -%} - -#if SWIGGO_INTGO_SIZE == 32 -%insert(runtime) %{ -typedef int intgo; -typedef unsigned int uintgo; -%} -%insert(cgo_comment_typedefs) %{ -typedef int intgo; -typedef unsigned int uintgo; -%} -#elif SWIGGO_INTGO_SIZE == 64 -%insert(runtime) %{ -typedef long long intgo; -typedef unsigned long long uintgo; -%} -%insert(cgo_comment_typedefs) %{ -typedef long long intgo; -typedef unsigned long long uintgo; -%} -#else -%insert(runtime) %{ -typedef ptrdiff_t intgo; -typedef size_t uintgo; -%} -%insert(cgo_comment_typedefs) %{ -typedef ptrdiff_t intgo; -typedef size_t uintgo; -%} -#endif - -#ifndef SWIGGO_GCCGO -// Set the host compiler struct attribute that will be -// used to match gc's struct layout. For example, on 386 Windows, -// gcc wants to 8-align int64s, but gc does not. -// Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86, -// and https://golang.org/issue/5603. -// See: https://github.com/golang/go/blob/fcbf04f9b93b4cd8addd05c2ed784118eb50a46c/src/cmd/cgo/out.go#L663 -%insert(runtime) %{ -# if !defined(__clang__) && (defined(__i386__) || defined(__x86_64__)) -# define SWIGSTRUCTPACKED __attribute__((__packed__, __gcc_struct__)) -# else -# define SWIGSTRUCTPACKED __attribute__((__packed__)) -# endif -%} -#else -# define SWIGSTRUCTPACKED -#endif - -%insert(runtime) %{ - -typedef struct { char *p; intgo n; } _gostring_; -typedef struct { void* array; intgo len; intgo cap; } _goslice_; - -%} - -%insert(cgo_comment_typedefs) %{ - -typedef struct { char *p; intgo n; } _gostring_; -typedef struct { void* array; intgo len; intgo cap; } _goslice_; - -%} - -#ifdef SWIGGO_GCCGO - -/* Boilerplate for C/C++ code when using gccgo. */ -%insert(runtime) %{ -#define SWIGGO_GCCGO - -#ifdef __cplusplus -extern "C" { -#endif -extern void *_cgo_allocate(size_t); -extern void _cgo_panic(const char *); -#ifdef __cplusplus -} -#endif - -#define _swig_goallocate _cgo_allocate -#define _swig_gopanic _cgo_panic -%} - -#endif - -#ifndef SWIGGO_GCCGO - -%go_import("unsafe", _ "runtime/cgo") - -#else - -%go_import("syscall", "unsafe") - -%insert(go_header) %{ - -type _ syscall.Sockaddr - -%} - -#endif - -%insert(go_header) %{ - -type _ unsafe.Pointer - -%} - -/* Swig_always_false is used to conditionally assign parameters to - Swig_escape_val so that the compiler thinks that they escape. We - only assign them if Swig_always_false is true, which it never is. - We export the variable so that the compiler doesn't realize that it - is never set. */ -%insert(go_header) %{ -var Swig_escape_always_false bool -var Swig_escape_val interface{} -%} - -/* Function pointers are translated by the code in go.cxx into - _swig_fnptr. Member pointers are translated to _swig_memberptr. */ - -%insert(go_header) %{ -type _swig_fnptr *byte -type _swig_memberptr *byte -%} - -/* Convert a Go interface value into a C++ pointer. */ - -%insert(go_header) %{ -func getSwigcptr(v interface { Swigcptr() uintptr }) uintptr { - if v == nil { - return 0 - } - return v.Swigcptr() -} -%} - -/* For directors we need C++ to track a Go pointer. Since we can't - pass a Go pointer into C++, we use a map to track the pointers on - the Go side. */ - -%go_import("sync") - -%insert(go_header) %{ -type _ sync.Mutex -%} - -%insert(go_director) %{ - -var swigDirectorTrack struct { - sync.Mutex - m map[int]interface{} - c int -} - -func swigDirectorAdd(v interface{}) int { - swigDirectorTrack.Lock() - defer swigDirectorTrack.Unlock() - if swigDirectorTrack.m == nil { - swigDirectorTrack.m = make(map[int]interface{}) - } - swigDirectorTrack.c++ - ret := swigDirectorTrack.c - swigDirectorTrack.m[ret] = v - return ret -} - -func swigDirectorLookup(c int) interface{} { - swigDirectorTrack.Lock() - defer swigDirectorTrack.Unlock() - ret := swigDirectorTrack.m[c] - if ret == nil { - panic("C++ director pointer not found (possible use-after-free)") - } - return ret -} - -func swigDirectorDelete(c int) { - swigDirectorTrack.Lock() - defer swigDirectorTrack.Unlock() - if swigDirectorTrack.m[c] == nil { - if c > swigDirectorTrack.c { - panic("C++ director pointer invalid (possible memory corruption") - } else { - panic("C++ director pointer not found (possible use-after-free)") - } - } - delete(swigDirectorTrack.m, c) -} - -%} diff --git a/contrib/tools/swig/Lib/go/gostring.swg b/contrib/tools/swig/Lib/go/gostring.swg deleted file mode 100644 index d9c47d28583..00000000000 --- a/contrib/tools/swig/Lib/go/gostring.swg +++ /dev/null @@ -1,29 +0,0 @@ -/* ------------------------------------------------------------ - * gostring.swg - * - * Support for returning strings from C to Go. - * ------------------------------------------------------------ */ - -// C/C++ code to convert a memory buffer into a Go string allocated in -// C/C++ memory. -%fragment("AllocateString", "runtime") %{ -static _gostring_ Swig_AllocateString(const char *p, size_t l) { - _gostring_ ret; - ret.p = (char*)malloc(l); - memcpy(ret.p, p, l); - ret.n = l; - return ret; -} -%} - -// Go code to convert a string allocated in C++ memory to one -// allocated in Go memory. -%fragment("CopyString", "go_runtime") %{ -type swig_gostring struct { p unsafe.Pointer; n int } -func swigCopyString(s string) string { - p := *(*swig_gostring)(unsafe.Pointer(&s)) - r := string((*[0x7fffffff]byte)(p.p)[:p.n]) - Swig_free(uintptr(p.p)) - return r -} -%} diff --git a/contrib/tools/swig/Lib/go/typemaps.i b/contrib/tools/swig/Lib/go/typemaps.i deleted file mode 100644 index d2e60d37c8b..00000000000 --- a/contrib/tools/swig/Lib/go/typemaps.i +++ /dev/null @@ -1,298 +0,0 @@ -/* ----------------------------------------------------------------------------- - * typemaps.i - * - * Pointer and reference handling typemap library - * - * These mappings provide support for input/output arguments and common - * uses for C/C++ pointers and C++ references. - * ----------------------------------------------------------------------------- */ - -/* -INPUT typemaps --------------- - -These typemaps remap a C pointer or C++ reference to be an "INPUT" value which is -passed by value instead of reference. - -The following typemaps can be applied to turn a pointer or reference into a simple -input value. That is, instead of passing a pointer or reference to an object, -you would use a real value instead. - - bool *INPUT, bool &INPUT - signed char *INPUT, signed char &INPUT - unsigned char *INPUT, unsigned char &INPUT - short *INPUT, short &INPUT - unsigned short *INPUT, unsigned short &INPUT - int *INPUT, int &INPUT - unsigned int *INPUT, unsigned int &INPUT - long *INPUT, long &INPUT - unsigned long *INPUT, unsigned long &INPUT - long long *INPUT, long long &INPUT - unsigned long long *INPUT, unsigned long long &INPUT - float *INPUT, float &INPUT - double *INPUT, double &INPUT - -To use these, suppose you had a C function like this : - - double fadd(double *a, double *b) { - return *a+*b; - } - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - double fadd(double *INPUT, double *INPUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *INPUT { double *a, double *b }; - double fadd(double *a, double *b); - -In Go you could then use it like this: - answer := modulename.Fadd(10.0, 20.0) - -There are no char *INPUT typemaps, however you can apply the signed -char * typemaps instead: - %include <typemaps.i> - %apply signed char *INPUT {char *input}; - void f(char *input); -*/ - -%define INPUT_TYPEMAP(TYPE, GOTYPE) -%typemap(gotype) TYPE *INPUT, TYPE &INPUT "GOTYPE" - - %typemap(in) TYPE *INPUT, TYPE &INPUT -%{ $1 = ($1_ltype)&$input; %} - -%typemap(out) TYPE *INPUT, TYPE &INPUT "" - -%typemap(goout) TYPE *INPUT, TYPE &INPUT "" - -%typemap(freearg) TYPE *INPUT, TYPE &INPUT "" - -%typemap(argout) TYPE *INPUT, TYPE &INPUT "" - -// %typemap(typecheck) TYPE *INPUT = TYPE; -// %typemap(typecheck) TYPE &INPUT = TYPE; -%enddef - -INPUT_TYPEMAP(bool, bool); -INPUT_TYPEMAP(signed char, int8); -INPUT_TYPEMAP(char, byte); -INPUT_TYPEMAP(unsigned char, byte); -INPUT_TYPEMAP(short, int16); -INPUT_TYPEMAP(unsigned short, uint16); -INPUT_TYPEMAP(int, int); -INPUT_TYPEMAP(unsigned int, uint); -INPUT_TYPEMAP(long, int64); -INPUT_TYPEMAP(unsigned long, uint64); -INPUT_TYPEMAP(long long, int64); -INPUT_TYPEMAP(unsigned long long, uint64); -INPUT_TYPEMAP(float, float32); -INPUT_TYPEMAP(double, float64); - -#undef INPUT_TYPEMAP - -// OUTPUT typemaps. These typemaps are used for parameters that -// are output only. An array replaces the c pointer or reference parameter. -// The output value is returned in this array passed in. - -/* -OUTPUT typemaps ---------------- - -The following typemaps can be applied to turn a pointer or reference -into an "output" value. When calling a function, no input value would -be given for a parameter, but an output value would be returned. This -works by a Go slice being passed as a parameter where a c pointer or -reference is required. As with any Go function, the array is passed -by reference so that any modifications to the array will be picked up -in the calling function. Note that the array passed in MUST have at -least one element, but as the c function does not require any input, -the value can be set to anything. - - bool *OUTPUT, bool &OUTPUT - signed char *OUTPUT, signed char &OUTPUT - unsigned char *OUTPUT, unsigned char &OUTPUT - short *OUTPUT, short &OUTPUT - unsigned short *OUTPUT, unsigned short &OUTPUT - int *OUTPUT, int &OUTPUT - unsigned int *OUTPUT, unsigned int &OUTPUT - long *OUTPUT, long &OUTPUT - unsigned long *OUTPUT, unsigned long &OUTPUT - long long *OUTPUT, long long &OUTPUT - unsigned long long *OUTPUT, unsigned long long &OUTPUT - float *OUTPUT, float &OUTPUT - double *OUTPUT, double &OUTPUT - -For example, suppose you were trying to wrap the modf() function in the -C math library which splits x into integral and fractional parts (and -returns the integer part in one of its parameters): - - double modf(double x, double *ip); - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - double modf(double x, double *OUTPUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *OUTPUT { double *ip }; - double modf(double x, double *ip); - -The Go output of the function would be the function return value and the -value in the single element array. In Go you would use it like this: - - ptr := []float64{0.0} - fraction := modulename.Modf(5.0,ptr) - -There are no char *OUTPUT typemaps, however you can apply the signed -char * typemaps instead: - %include <typemaps.i> - %apply signed char *OUTPUT {char *output}; - void f(char *output); -*/ - -%define OUTPUT_TYPEMAP(TYPE, GOTYPE) -%typemap(gotype) TYPE *OUTPUT, TYPE &OUTPUT %{[]GOTYPE%} - -%typemap(in) TYPE *OUTPUT($*1_ltype temp), TYPE &OUTPUT($*1_ltype temp) -{ - if ($input.len == 0) { - _swig_gopanic("array must contain at least 1 element"); - } - $1 = &temp; -} - -%typemap(out) TYPE *OUTPUT, TYPE &OUTPUT "" - -%typemap(goout) TYPE *INPUT, TYPE &INPUT "" - -%typemap(freearg) TYPE *OUTPUT, TYPE &OUTPUT "" - -%typemap(argout) TYPE *OUTPUT, TYPE &OUTPUT -{ - TYPE* a = (TYPE *) $input.array; - a[0] = temp$argnum; -} - -%enddef - -OUTPUT_TYPEMAP(bool, bool); -OUTPUT_TYPEMAP(signed char, int8); -OUTPUT_TYPEMAP(char, byte); -OUTPUT_TYPEMAP(unsigned char, byte); -OUTPUT_TYPEMAP(short, int16); -OUTPUT_TYPEMAP(unsigned short, uint16); -OUTPUT_TYPEMAP(int, int); -OUTPUT_TYPEMAP(unsigned int, uint); -OUTPUT_TYPEMAP(long, int64); -OUTPUT_TYPEMAP(unsigned long, uint64); -OUTPUT_TYPEMAP(long long, int64); -OUTPUT_TYPEMAP(unsigned long long, uint64); -OUTPUT_TYPEMAP(float, float32); -OUTPUT_TYPEMAP(double, float64); - -#undef OUTPUT_TYPEMAP - -/* -INOUT typemaps --------------- - -Mappings for a parameter that is both an input and an output parameter - -The following typemaps can be applied to make a function parameter both -an input and output value. This combines the behavior of both the -"INPUT" and "OUTPUT" typemaps described earlier. Output values are -returned as an element in a Go slice. - - bool *INOUT, bool &INOUT - signed char *INOUT, signed char &INOUT - unsigned char *INOUT, unsigned char &INOUT - short *INOUT, short &INOUT - unsigned short *INOUT, unsigned short &INOUT - int *INOUT, int &INOUT - unsigned int *INOUT, unsigned int &INOUT - long *INOUT, long &INOUT - unsigned long *INOUT, unsigned long &INOUT - long long *INOUT, long long &INOUT - unsigned long long *INOUT, unsigned long long &INOUT - float *INOUT, float &INOUT - double *INOUT, double &INOUT - -For example, suppose you were trying to wrap the following function : - - void neg(double *x) { - *x = -(*x); - } - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - void neg(double *INOUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *INOUT { double *x }; - void neg(double *x); - -This works similarly to C in that the mapping directly modifies the -input value - the input must be an array with a minimum of one element. -The element in the array is the input and the output is the element in -the array. - - x := []float64{5.0} - Neg(x); - -The implementation of the OUTPUT and INOUT typemaps is different to -other languages in that other languages will return the output value -as part of the function return value. This difference is due to Go -being a typed language. - -There are no char *INOUT typemaps, however you can apply the signed -char * typemaps instead: - %include <typemaps.i> - %apply signed char *INOUT {char *inout}; - void f(char *inout); -*/ - -%define INOUT_TYPEMAP(TYPE, GOTYPE) -%typemap(gotype) TYPE *INOUT, TYPE &INOUT %{[]GOTYPE%} - -%typemap(in) TYPE *INOUT, TYPE &INOUT { - if ($input.len == 0) { - _swig_gopanic("array must contain at least 1 element"); - } - $1 = ($1_ltype) $input.array; -} - -%typemap(out) TYPE *INOUT, TYPE &INOUT "" - -%typemap(goout) TYPE *INOUT, TYPE &INOUT "" - -%typemap(freearg) TYPE *INOUT, TYPE &INOUT "" - -%typemap(argout) TYPE *INOUT, TYPE &INOUT "" - -%enddef - -INOUT_TYPEMAP(bool, bool); -INOUT_TYPEMAP(signed char, int8); -INOUT_TYPEMAP(char, byte); -INOUT_TYPEMAP(unsigned char, byte); -INOUT_TYPEMAP(short, int16); -INOUT_TYPEMAP(unsigned short, uint16); -INOUT_TYPEMAP(int, int); -INOUT_TYPEMAP(unsigned int, uint); -INOUT_TYPEMAP(long, int64); -INOUT_TYPEMAP(unsigned long, uint64); -INOUT_TYPEMAP(long long, int64); -INOUT_TYPEMAP(unsigned long long, uint64); -INOUT_TYPEMAP(float, float32); -INOUT_TYPEMAP(double, float64); - -#undef INOUT_TYPEMAP diff --git a/contrib/tools/swig/Lib/java/enumtypesafe.swg b/contrib/tools/swig/Lib/java/enumtypesafe.swg deleted file mode 100644 index c2012f568b6..00000000000 --- a/contrib/tools/swig/Lib/java/enumtypesafe.swg +++ /dev/null @@ -1,117 +0,0 @@ -/* ----------------------------------------------------------------------------- - * enumtypesafe.swg - * - * Include this file in order for C/C++ enums to be wrapped by the so called - * typesafe enum pattern. Each enum has an equivalent Java class named after the - * enum and each enum item is a static instance of this class. - * ----------------------------------------------------------------------------- */ - -// const enum SWIGTYPE & typemaps -%typemap(jni) const enum SWIGTYPE & "jint" -%typemap(jtype) const enum SWIGTYPE & "int" -%typemap(jstype) const enum SWIGTYPE & "$*javaclassname" - -%typemap(in) const enum SWIGTYPE & ($*1_ltype temp) -%{ temp = ($*1_ltype)$input; - $1 = &temp; %} -%typemap(out) const enum SWIGTYPE & %{ $result = (jint)*$1; %} - -%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const enum SWIGTYPE & -%{ static $*1_ltype temp = ($*1_ltype)$input; - $result = &temp; %} -%typemap(directorin, descriptor="L$packagepath/$*javaclassname;") const enum SWIGTYPE & "$input = (jint)$1;" -%typemap(javadirectorin) const enum SWIGTYPE & "$*javaclassname.swigToEnum($jniinput)" -%typemap(javadirectorout) const enum SWIGTYPE & "($javacall).swigValue()" - -%typecheck(SWIG_TYPECHECK_POINTER) const enum SWIGTYPE & "" - -%typemap(throws) const enum SWIGTYPE & -%{ (void)$1; - SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "C++ $1_type exception thrown"); %} - -%typemap(javain) const enum SWIGTYPE & "$javainput.swigValue()" -%typemap(javaout) const enum SWIGTYPE & { - return $*javaclassname.swigToEnum($jnicall); - } - -// enum SWIGTYPE typemaps -%typemap(jni) enum SWIGTYPE "jint" -%typemap(jtype) enum SWIGTYPE "int" -%typemap(jstype) enum SWIGTYPE "$javaclassname" - -%typemap(in) enum SWIGTYPE %{ $1 = ($1_ltype)$input; %} -%typemap(out) enum SWIGTYPE %{ $result = (jint)$1; %} - -%typemap(directorout) enum SWIGTYPE %{ $result = ($1_ltype)$input; %} -%typemap(directorin, descriptor="L$packagepath/$javaclassname;") enum SWIGTYPE "$input = (jint) $1;" -%typemap(javadirectorin) enum SWIGTYPE "$javaclassname.swigToEnum($jniinput)" -%typemap(javadirectorout) enum SWIGTYPE "($javacall).swigValue()" - -%typecheck(SWIG_TYPECHECK_POINTER) enum SWIGTYPE "" - -%typemap(throws) enum SWIGTYPE -%{ (void)$1; - SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "C++ $1_type exception thrown"); %} - -%typemap(javain) enum SWIGTYPE "$javainput.swigValue()" -%typemap(javaout) enum SWIGTYPE { - return $javaclassname.swigToEnum($jnicall); - } - -// '$static' will be replaced with either 'static' or nothing depending on whether the enum is an inner Java class or not -%typemap(javaclassmodifiers) enum SWIGTYPE "public final $static class" -%typemap(javabase) enum SWIGTYPE "" -%typemap(javacode) enum SWIGTYPE "" -%typemap(javaimports) enum SWIGTYPE "" -%typemap(javainterfaces) enum SWIGTYPE "" - -/* - * The swigToEnum method is used to find the Java enum from a C++ enum integer value. The default one here takes - * advantage of the fact that most enums do not have initial values specified, so the lookup is fast. If initial - * values are specified then a lengthy linear search through all possible enums might occur. Specific typemaps could be - * written to possibly optimise this lookup by taking advantage of characteristics peculiar to the targeted enum. - * The special variable, $enumvalues, is replaced with a comma separated list of all the enum values. - */ -%typemap(javabody) enum SWIGTYPE %{ - public final int swigValue() { - return swigValue; - } - - public String toString() { - return swigName; - } - - public static $javaclassname swigToEnum(int swigValue) { - if (swigValue < swigValues.length && swigValue >= 0 && swigValues[swigValue].swigValue == swigValue) - return swigValues[swigValue]; - for (int i = 0; i < swigValues.length; i++) - if (swigValues[i].swigValue == swigValue) - return swigValues[i]; - throw new IllegalArgumentException("No enum " + $javaclassname.class + " with value " + swigValue); - } - - private $javaclassname(String swigName) { - this.swigName = swigName; - this.swigValue = swigNext++; - } - - private $javaclassname(String swigName, int swigValue) { - this.swigName = swigName; - this.swigValue = swigValue; - swigNext = swigValue+1; - } - - private $javaclassname(String swigName, $javaclassname swigEnum) { - this.swigName = swigName; - this.swigValue = swigEnum.swigValue; - swigNext = this.swigValue+1; - } - - private static $javaclassname[] swigValues = { $enumvalues }; - private static int swigNext = 0; - private final int swigValue; - private final String swigName; -%} - -%javaenum(typesafe); - diff --git a/contrib/tools/swig/Lib/java/java.swg b/contrib/tools/swig/Lib/java/java.swg deleted file mode 100644 index 8719818bb8d..00000000000 --- a/contrib/tools/swig/Lib/java/java.swg +++ /dev/null @@ -1,1458 +0,0 @@ -/* ----------------------------------------------------------------------------- - * java.swg - * - * Java typemaps - * ----------------------------------------------------------------------------- */ - -%include <javahead.swg> - -/* The jni, jtype and jstype typemaps work together and so there should be one of each. - * The jni typemap contains the JNI type used in the JNI (C/C++) code. - * The jtype typemap contains the Java type used in the JNI intermediary class. - * The jstype typemap contains the Java type used in the Java proxy classes, type wrapper classes and module class. */ - -/* Fragments */ -%fragment("SWIG_PackData", "header") { -/* Pack binary data into a string */ -SWIGINTERN char * SWIG_PackData(char *c, void *ptr, size_t sz) { - static const char hex[17] = "0123456789abcdef"; - const unsigned char *u = (unsigned char *) ptr; - const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - unsigned char uu = *u; - *(c++) = hex[(uu & 0xf0) >> 4]; - *(c++) = hex[uu & 0xf]; - } - return c; -} -} - -%fragment("SWIG_UnPackData", "header") { -/* Unpack binary data from a string */ -SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) { - unsigned char *u = (unsigned char *) ptr; - const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - char d = *(c++); - unsigned char uu; - if ((d >= '0') && (d <= '9')) - uu = ((d - '0') << 4); - else if ((d >= 'a') && (d <= 'f')) - uu = ((d - ('a'-10)) << 4); - else - return (char *) 0; - d = *(c++); - if ((d >= '0') && (d <= '9')) - uu |= (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - uu |= (d - ('a'-10)); - else - return (char *) 0; - *u = uu; - } - return c; -} -} - -%fragment("SWIG_JavaIntFromSize_t", "header") { -/* Check for overflow converting to Java int (always signed 32-bit) from (unsigned variable-bit) size_t */ -SWIGINTERN jint SWIG_JavaIntFromSize_t(size_t size) { - static const jint JINT_MAX = 0x7FFFFFFF; - return (size > (size_t)JINT_MAX) ? -1 : (jint)size; -} -} - -/* Primitive types */ -%typemap(jni) bool, const bool & "jboolean" -%typemap(jni) char, const char & "jchar" -%typemap(jni) signed char, const signed char & "jbyte" -%typemap(jni) unsigned char, const unsigned char & "jshort" -%typemap(jni) short, const short & "jshort" -%typemap(jni) unsigned short, const unsigned short & "jint" -%typemap(jni) int, const int & "jint" -%typemap(jni) unsigned int, const unsigned int & "jlong" -%typemap(jni) long, const long & "jint" -%typemap(jni) unsigned long, const unsigned long & "jlong" -%typemap(jni) long long, const long long & "jlong" -%typemap(jni) unsigned long long, const unsigned long long & "jobject" -%typemap(jni) float, const float & "jfloat" -%typemap(jni) double, const double & "jdouble" -%typemap(jni) void "void" - -%typemap(jtype) bool, const bool & "boolean" -%typemap(jtype) char, const char & "char" -%typemap(jtype) signed char, const signed char & "byte" -%typemap(jtype) unsigned char, const unsigned char & "short" -%typemap(jtype) short, const short & "short" -%typemap(jtype) unsigned short, const unsigned short & "int" -%typemap(jtype) int, const int & "int" -%typemap(jtype) unsigned int, const unsigned int & "long" -%typemap(jtype) long, const long & "int" -%typemap(jtype) unsigned long, const unsigned long & "long" -%typemap(jtype) long long, const long long & "long" -%typemap(jtype) unsigned long long, const unsigned long long & "java.math.BigInteger" -%typemap(jtype) float, const float & "float" -%typemap(jtype) double, const double & "double" -%typemap(jtype) void "void" - -%typemap(jstype) bool, const bool & "boolean" -%typemap(jstype) char, const char & "char" -%typemap(jstype) signed char, const signed char & "byte" -%typemap(jstype) unsigned char, const unsigned char & "short" -%typemap(jstype) short, const short & "short" -%typemap(jstype) unsigned short, const unsigned short & "int" -%typemap(jstype) int, const int & "int" -%typemap(jstype) unsigned int, const unsigned int & "long" -%typemap(jstype) long, const long & "int" -%typemap(jstype) unsigned long, const unsigned long & "long" -%typemap(jstype) long long, const long long & "long" -%typemap(jstype) unsigned long long, const unsigned long long & "java.math.BigInteger" -%typemap(jstype) float, const float & "float" -%typemap(jstype) double, const double & "double" -%typemap(jstype) void "void" - -%typemap(jboxtype) bool, const bool & "Boolean" -%typemap(jboxtype) char, const char & "Character" -%typemap(jboxtype) signed char, const signed char & "Byte" -%typemap(jboxtype) unsigned char, const unsigned char & "Short" -%typemap(jboxtype) short, const short & "Short" -%typemap(jboxtype) unsigned short, const unsigned short & "Integer" -%typemap(jboxtype) int, const int & "Integer" -%typemap(jboxtype) unsigned int, const unsigned int & "Long" -%typemap(jboxtype) long, const long & "Integer" -%typemap(jboxtype) unsigned long, const unsigned long & "Long" -%typemap(jboxtype) long long, const long long & "Long" -%typemap(jboxtype) unsigned long long, const unsigned long long & "java.math.BigInteger" -%typemap(jboxtype) float, const float & "Float" -%typemap(jboxtype) double, const double & "Double" - -%typemap(jni) char *, char *&, char[ANY], char[] "jstring" -%typemap(jtype) char *, char *&, char[ANY], char[] "String" -%typemap(jstype) char *, char *&, char[ANY], char[] "String" - -/* JNI types */ -%typemap(jni) jboolean "jboolean" -%typemap(jni) jchar "jchar" -%typemap(jni) jbyte "jbyte" -%typemap(jni) jshort "jshort" -%typemap(jni) jint "jint" -%typemap(jni) jlong "jlong" -%typemap(jni) jfloat "jfloat" -%typemap(jni) jdouble "jdouble" -%typemap(jni) jstring "jstring" -%typemap(jni) jobject "jobject" -%typemap(jni) jbooleanArray "jbooleanArray" -%typemap(jni) jcharArray "jcharArray" -%typemap(jni) jbyteArray "jbyteArray" -%typemap(jni) jshortArray "jshortArray" -%typemap(jni) jintArray "jintArray" -%typemap(jni) jlongArray "jlongArray" -%typemap(jni) jfloatArray "jfloatArray" -%typemap(jni) jdoubleArray "jdoubleArray" -%typemap(jni) jobjectArray "jobjectArray" - -%typemap(jtype) jboolean "boolean" -%typemap(jtype) jchar "char" -%typemap(jtype) jbyte "byte" -%typemap(jtype) jshort "short" -%typemap(jtype) jint "int" -%typemap(jtype) jlong "long" -%typemap(jtype) jfloat "float" -%typemap(jtype) jdouble "double" -%typemap(jtype) jstring "String" -%typemap(jtype) jobject "java.lang.Object" -%typemap(jtype) jbooleanArray "boolean[]" -%typemap(jtype) jcharArray "char[]" -%typemap(jtype) jbyteArray "byte[]" -%typemap(jtype) jshortArray "short[]" -%typemap(jtype) jintArray "int[]" -%typemap(jtype) jlongArray "long[]" -%typemap(jtype) jfloatArray "float[]" -%typemap(jtype) jdoubleArray "double[]" -%typemap(jtype) jobjectArray "java.lang.Object[]" - -%typemap(jstype) jboolean "boolean" -%typemap(jstype) jchar "char" -%typemap(jstype) jbyte "byte" -%typemap(jstype) jshort "short" -%typemap(jstype) jint "int" -%typemap(jstype) jlong "long" -%typemap(jstype) jfloat "float" -%typemap(jstype) jdouble "double" -%typemap(jstype) jstring "String" -%typemap(jstype) jobject "java.lang.Object" -%typemap(jstype) jbooleanArray "boolean[]" -%typemap(jstype) jcharArray "char[]" -%typemap(jstype) jbyteArray "byte[]" -%typemap(jstype) jshortArray "short[]" -%typemap(jstype) jintArray "int[]" -%typemap(jstype) jlongArray "long[]" -%typemap(jstype) jfloatArray "float[]" -%typemap(jstype) jdoubleArray "double[]" -%typemap(jstype) jobjectArray "java.lang.Object[]" - -/* Non primitive types */ -%typemap(jni) SWIGTYPE "jlong" -%typemap(jtype) SWIGTYPE "long" -%typemap(jstype) SWIGTYPE "$&javaclassname" -%typemap(jboxtype) SWIGTYPE "$typemap(jstype, $1_type)" - -%typemap(jni) SWIGTYPE [] "jlong" -%typemap(jtype) SWIGTYPE [] "long" -%typemap(jstype) SWIGTYPE [] "$javaclassname" - -%typemap(jni) SWIGTYPE * "jlong" -%typemap(jtype) SWIGTYPE * "long" -%typemap(jstype) SWIGTYPE * "$javaclassname" - -%typemap(jni) SWIGTYPE & "jlong" -%typemap(jtype) SWIGTYPE & "long" -%typemap(jstype) SWIGTYPE & "$javaclassname" - -%typemap(jni) SWIGTYPE && "jlong" -%typemap(jtype) SWIGTYPE && "long" -%typemap(jstype) SWIGTYPE && "$javaclassname" - -/* pointer to a class member */ -%typemap(jni) SWIGTYPE (CLASS::*) "jstring" -%typemap(jtype) SWIGTYPE (CLASS::*) "String" -%typemap(jstype) SWIGTYPE (CLASS::*) "$javaclassname" - -/* The following are the in, out, freearg, argout typemaps. These are the JNI code generating typemaps for converting from Java to C and visa versa. */ - -/* primitive types */ -%typemap(in) bool -%{ $1 = $input ? true : false; %} - -%typemap(directorout) bool -%{ $result = $input ? true : false; %} - -%typemap(javadirectorin) bool "$jniinput" -%typemap(javadirectorout) bool "$javacall" - -%typemap(in) char, - signed char, - unsigned char, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - float, - double -%{ $1 = ($1_ltype)$input; %} - -%typemap(directorout) char, - signed char, - unsigned char, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - float, - double -%{ $result = ($1_ltype)$input; %} - -%typemap(directorin, descriptor="Z") bool "$input = (jboolean) $1;" -%typemap(directorin, descriptor="C") char "$input = (jint) $1;" -%typemap(directorin, descriptor="B") signed char "$input = (jbyte) $1;" -%typemap(directorin, descriptor="S") unsigned char "$input = (jshort) $1;" -%typemap(directorin, descriptor="S") short "$input = (jshort) $1;" -%typemap(directorin, descriptor="I") unsigned short "$input = (jint) $1;" -%typemap(directorin, descriptor="I") int "$input = (jint) $1;" -%typemap(directorin, descriptor="J") unsigned int "$input = (jlong) $1;" -%typemap(directorin, descriptor="I") long "$input = (jint) $1;" -%typemap(directorin, descriptor="J") unsigned long "$input = (jlong) $1;" -%typemap(directorin, descriptor="J") long long "$input = (jlong) $1;" -%typemap(directorin, descriptor="F") float "$input = (jfloat) $1;" -%typemap(directorin, descriptor="D") double "$input = (jdouble) $1;" - -%typemap(javadirectorin) char, - signed char, - unsigned char, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - float, - double - "$jniinput" - -%typemap(javadirectorout) char, - signed char, - unsigned char, - short, - unsigned short, - int, - unsigned int, - long, - unsigned long, - long long, - float, - double - "$javacall" - -%typemap(out) bool %{ $result = (jboolean)$1; %} -%typemap(out) char %{ $result = (jchar)$1; %} -%typemap(out) signed char %{ $result = (jbyte)$1; %} -%typemap(out) unsigned char %{ $result = (jshort)$1; %} -%typemap(out) short %{ $result = (jshort)$1; %} -%typemap(out) unsigned short %{ $result = (jint)$1; %} -%typemap(out) int %{ $result = (jint)$1; %} -%typemap(out) unsigned int %{ $result = (jlong)$1; %} -%typemap(out) long %{ $result = (jint)$1; %} -%typemap(out) unsigned long %{ $result = (jlong)$1; %} -%typemap(out) long long %{ $result = (jlong)$1; %} -%typemap(out) float %{ $result = (jfloat)$1; %} -%typemap(out) double %{ $result = (jdouble)$1; %} - -/* unsigned long long */ -/* Convert from BigInteger using the toByteArray member function */ -%typemap(in) unsigned long long { - jclass clazz; - jmethodID mid; - jbyteArray ba; - jbyte* bae; - jsize sz; - int i; - - if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); - return $null; - } - clazz = JCALL1(GetObjectClass, jenv, $input); - mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); - ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid); - bae = JCALL2(GetByteArrayElements, jenv, ba, 0); - sz = JCALL1(GetArrayLength, jenv, ba); - $1 = 0; - if (sz > 0) { - $1 = ($1_type)(signed char)bae[0]; - for(i=1; i<sz; i++) { - $1 = ($1 << 8) | ($1_type)(unsigned char)bae[i]; - } - } - JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); -} - -%typemap(directorout) unsigned long long { - jclass clazz; - jmethodID mid; - jbyteArray ba; - jbyte* bae; - jsize sz; - int i; - - if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); - return $null; - } - clazz = JCALL1(GetObjectClass, jenv, $input); - mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); - ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid); - bae = JCALL2(GetByteArrayElements, jenv, ba, 0); - sz = JCALL1(GetArrayLength, jenv, ba); - $result = 0; - if (sz > 0) { - $result = ($1_type)(signed char)bae[0]; - for(i=1; i<sz; i++) { - $result = ($result << 8) | ($1_type)(unsigned char)bae[i]; - } - } - JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); -} - - -/* Convert to BigInteger - byte array holds number in 2's complement big endian format */ -%typemap(out) unsigned long long { - jbyteArray ba = JCALL1(NewByteArray, jenv, 9); - jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0); - jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger"); - jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "<init>", "([B)V"); - jobject bigint; - int i; - - bae[0] = 0; - for(i=1; i<9; i++ ) { - bae[i] = (jbyte)($1>>8*(8-i)); - } - - JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); - bigint = JCALL3(NewObject, jenv, clazz, mid, ba); - JCALL1(DeleteLocalRef, jenv, ba); - $result = bigint; -} - -/* Convert to BigInteger (see out typemap) */ -%typemap(directorin, descriptor="Ljava/math/BigInteger;", noblock=1) unsigned long long, const unsigned long long & { -{ - jbyteArray ba = JCALL1(NewByteArray, jenv, 9); - jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0); - jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger"); - jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "<init>", "([B)V"); - jobject bigint; - int swig_i; - - bae[0] = 0; - for(swig_i=1; swig_i<9; swig_i++ ) { - bae[swig_i] = (jbyte)($1>>8*(8-swig_i)); - } - - JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); - bigint = JCALL3(NewObject, jenv, clazz, mid, ba); - JCALL1(DeleteLocalRef, jenv, ba); - $input = bigint; -} -Swig::LocalRefGuard $1_refguard(jenv, $input); } - -%typemap(javadirectorin) unsigned long long "$jniinput" -%typemap(javadirectorout) unsigned long long "$javacall" - -/* char * - treat as String */ -%typemap(in, noblock=1) char * { - $1 = 0; - if ($input) { - $1 = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0); - if (!$1) return $null; - } -} - -%typemap(directorout, noblock=1, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) char * { - $1 = 0; - if ($input) { - $result = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0); - if (!$result) return $null; - } -} - -%typemap(directorin, descriptor="Ljava/lang/String;", noblock=1) char * { - $input = 0; - if ($1) { - $input = JCALL1(NewStringUTF, jenv, (const char *)$1); - if (!$input) return $null; - } - Swig::LocalRefGuard $1_refguard(jenv, $input); -} - -%typemap(freearg, noblock=1) char * { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, (const char *)$1); } -%typemap(out, noblock=1) char * { if ($1) $result = JCALL1(NewStringUTF, jenv, (const char *)$1); } -%typemap(javadirectorin) char * "$jniinput" -%typemap(javadirectorout) char * "$javacall" - -/* char *& - treat as String */ -%typemap(in, noblock=1) char *& ($*1_ltype temp = 0) { - $1 = 0; - if ($input) { - temp = ($*1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0); - if (!temp) return $null; - } - $1 = &temp; -} -%typemap(freearg, noblock=1) char *& { if ($1 && *$1) JCALL2(ReleaseStringUTFChars, jenv, $input, (const char *)*$1); } -%typemap(out, noblock=1) char *& { if (*$1) $result = JCALL1(NewStringUTF, jenv, (const char *)*$1); } - -%typemap(out) void "" -%typemap(javadirectorin) void "$jniinput" -%typemap(javadirectorout) void "$javacall" -%typemap(directorin, descriptor="V") void "" - -/* primitive types by reference */ -%typemap(in) const bool & ($*1_ltype temp) -%{ temp = $input ? true : false; - $1 = &temp; %} - -%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const bool & -%{ static $*1_ltype temp; - temp = $input ? true : false; - $result = &temp; %} - -%typemap(javadirectorin) const bool & "$jniinput" -%typemap(javadirectorout) const bool & "$javacall" - -%typemap(in) const char & ($*1_ltype temp), - const signed char & ($*1_ltype temp), - const unsigned char & ($*1_ltype temp), - const short & ($*1_ltype temp), - const unsigned short & ($*1_ltype temp), - const int & ($*1_ltype temp), - const unsigned int & ($*1_ltype temp), - const long & ($*1_ltype temp), - const unsigned long & ($*1_ltype temp), - const long long & ($*1_ltype temp), - const float & ($*1_ltype temp), - const double & ($*1_ltype temp) -%{ temp = ($*1_ltype)$input; - $1 = &temp; %} - -%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const char &, - const signed char &, - const unsigned char &, - const short &, - const unsigned short &, - const int &, - const unsigned int &, - const long &, - const unsigned long &, - const long long &, - const float &, - const double & -%{ static $*1_ltype temp; - temp = ($*1_ltype)$input; - $result = &temp; %} - -%typemap(directorin, descriptor="Z") const bool & "$input = (jboolean)$1;" -%typemap(directorin, descriptor="C") const char & "$input = (jchar)$1;" -%typemap(directorin, descriptor="B") const signed char & "$input = (jbyte)$1;" -%typemap(directorin, descriptor="S") const unsigned char & "$input = (jshort)$1;" -%typemap(directorin, descriptor="S") const short & "$input = (jshort)$1;" -%typemap(directorin, descriptor="I") const unsigned short & "$input = (jint)$1;" -%typemap(directorin, descriptor="I") const int & "$input = (jint)$1;" -%typemap(directorin, descriptor="J") const unsigned int & "$input = (jlong)$1;" -%typemap(directorin, descriptor="I") const long & "$input = (jint)$1;" -%typemap(directorin, descriptor="J") const unsigned long & "$input = (jlong)$1;" -%typemap(directorin, descriptor="J") const long long & "$input = (jlong)$1;" -%typemap(directorin, descriptor="F") const float & "$input = (jfloat)$1;" -%typemap(directorin, descriptor="D") const double & "$input = (jdouble)$1;" - -%typemap(javadirectorin) const char & ($*1_ltype temp), - const signed char & ($*1_ltype temp), - const unsigned char & ($*1_ltype temp), - const short & ($*1_ltype temp), - const unsigned short & ($*1_ltype temp), - const int & ($*1_ltype temp), - const unsigned int & ($*1_ltype temp), - const long & ($*1_ltype temp), - const unsigned long & ($*1_ltype temp), - const long long & ($*1_ltype temp), - const float & ($*1_ltype temp), - const double & ($*1_ltype temp) - "$jniinput" - -%typemap(javadirectorout) const char & ($*1_ltype temp), - const signed char & ($*1_ltype temp), - const unsigned char & ($*1_ltype temp), - const short & ($*1_ltype temp), - const unsigned short & ($*1_ltype temp), - const int & ($*1_ltype temp), - const unsigned int & ($*1_ltype temp), - const long & ($*1_ltype temp), - const unsigned long & ($*1_ltype temp), - const long long & ($*1_ltype temp), - const float & ($*1_ltype temp), - const double & ($*1_ltype temp) - "$javacall" - - -%typemap(out) const bool & %{ $result = (jboolean)*$1; %} -%typemap(out) const char & %{ $result = (jchar)*$1; %} -%typemap(out) const signed char & %{ $result = (jbyte)*$1; %} -%typemap(out) const unsigned char & %{ $result = (jshort)*$1; %} -%typemap(out) const short & %{ $result = (jshort)*$1; %} -%typemap(out) const unsigned short & %{ $result = (jint)*$1; %} -%typemap(out) const int & %{ $result = (jint)*$1; %} -%typemap(out) const unsigned int & %{ $result = (jlong)*$1; %} -%typemap(out) const long & %{ $result = (jint)*$1; %} -%typemap(out) const unsigned long & %{ $result = (jlong)*$1; %} -%typemap(out) const long long & %{ $result = (jlong)*$1; %} -%typemap(out) const float & %{ $result = (jfloat)*$1; %} -%typemap(out) const double & %{ $result = (jdouble)*$1; %} - -/* const unsigned long long & */ -/* Similar to unsigned long long */ -%typemap(in) const unsigned long long & ($*1_ltype temp) { - jclass clazz; - jmethodID mid; - jbyteArray ba; - jbyte* bae; - jsize sz; - int i; - - if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); - return $null; - } - clazz = JCALL1(GetObjectClass, jenv, $input); - mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); - ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid); - bae = JCALL2(GetByteArrayElements, jenv, ba, 0); - sz = JCALL1(GetArrayLength, jenv, ba); - $1 = &temp; - temp = 0; - if (sz > 0) { - temp = ($*1_ltype)(signed char)bae[0]; - for(i=1; i<sz; i++) { - temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i]; - } - } - JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); -} - -%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const unsigned long long & { - static $*1_ltype temp; - jclass clazz; - jmethodID mid; - jbyteArray ba; - jbyte* bae; - jsize sz; - int i; - - if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); - return $null; - } - clazz = JCALL1(GetObjectClass, jenv, $input); - mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); - ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid); - bae = JCALL2(GetByteArrayElements, jenv, ba, 0); - sz = JCALL1(GetArrayLength, jenv, ba); - $result = &temp; - temp = 0; - if (sz > 0) { - temp = ($*1_ltype)(signed char)bae[0]; - for(i=1; i<sz; i++) { - temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i]; - } - } - JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); -} - -%typemap(out) const unsigned long long & { - jbyteArray ba = JCALL1(NewByteArray, jenv, 9); - jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0); - jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger"); - jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "<init>", "([B)V"); - jobject bigint; - int i; - - bae[0] = 0; - for(i=1; i<9; i++ ) { - bae[i] = (jbyte)(*$1>>8*(8-i)); - } - - JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); - bigint = JCALL3(NewObject, jenv, clazz, mid, ba); - JCALL1(DeleteLocalRef, jenv, ba); - $result = bigint; -} - -%typemap(javadirectorin) const unsigned long long & "$jniinput" -%typemap(javadirectorout) const unsigned long long & "$javacall" - -/* Default handling. Object passed by value. Convert to a pointer */ -%typemap(in) SWIGTYPE ($&1_type argp) -%{ argp = *($&1_ltype*)&$input; - if (!argp) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null $1_type"); - return $null; - } - $1 = *argp; %} - -%typemap(directorout) SWIGTYPE ($&1_type argp) -%{ argp = *($&1_ltype*)&$input; - if (!argp) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Unexpected null return for type $1_type"); - return $null; - } - $result = *argp; %} - -%typemap(out) SWIGTYPE -#ifdef __cplusplus -%{ *($&1_ltype*)&$result = new $1_ltype($1); %} -#else -{ - $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype)); - memmove($1ptr, &$1, sizeof($1_type)); - *($&1_ltype*)&$result = $1ptr; -} -#endif - -%typemap(directorin,descriptor="L$packagepath/$&javaclassname;") SWIGTYPE -%{ $input = 0; - *(($&1_ltype*)&$input) = new $1_ltype(SWIG_STD_MOVE($1)); %} -%typemap(javadirectorin) SWIGTYPE "new $&javaclassname($jniinput, true)" -%typemap(javadirectorout) SWIGTYPE "$&javaclassname.getCPtr($javacall)" - -/* Generic pointers and references */ -%typemap(in) SWIGTYPE * %{ $1 = *($&1_ltype)&$input; %} -%typemap(in, fragment="SWIG_UnPackData") SWIGTYPE (CLASS::*) { - const char *temp = 0; - if ($input) { - temp = JCALL2(GetStringUTFChars, jenv, $input, 0); - if (!temp) return $null; - } - SWIG_UnpackData(temp, (void *)&$1, sizeof($1)); -} -%typemap(in) SWIGTYPE & %{ $1 = *($&1_ltype)&$input; - if (!$1) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type is null"); - return $null; - } %} -%typemap(in, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = *($&1_ltype)&$input; - if (!$1) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type is null"); - return $null; - } - rvrdeleter.reset($1); %} -%typemap(out) SWIGTYPE * -%{ *($&1_ltype)&$result = $1; %} -%typemap(out, fragment="SWIG_PackData", noblock=1) SWIGTYPE (CLASS::*) { - char buf[128]; - char *data = SWIG_PackData(buf, (void *)&$1, sizeof($1)); - *data = '\0'; - $result = JCALL1(NewStringUTF, jenv, buf); -} -%typemap(out) SWIGTYPE & -%{ *($&1_ltype)&$result = $1; %} -%typemap(out) SWIGTYPE && -%{ *($&1_ltype)&$result = $1; %} - -%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE * -%{ $result = *($&1_ltype)&$input; %} -%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE (CLASS::*) -%{ $result = *($&1_ltype)&$input; %} - -%typemap(directorin,descriptor="L$packagepath/$javaclassname;") SWIGTYPE * -%{ *(($&1_ltype)&$input) = ($1_ltype) $1; %} -%typemap(directorin,descriptor="L$packagepath/$javaclassname;") SWIGTYPE (CLASS::*) -%{ *(($&1_ltype)&$input) = ($1_ltype) $1; %} - -%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE & -%{ if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Unexpected null return for type $1_type"); - return $null; - } - $result = *($&1_ltype)&$input; %} -%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE && -%{ if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Unexpected null return for type $1_type"); - return $null; - } - $result = *($&1_ltype)&$input; %} -%typemap(directorin,descriptor="L$packagepath/$javaclassname;") SWIGTYPE & -%{ *($&1_ltype)&$input = ($1_ltype) &$1; %} -%typemap(directorin,descriptor="L$packagepath/$javaclassname;") SWIGTYPE && -%{ *($&1_ltype)&$input = ($1_ltype) &$1; %} - -%typemap(javadirectorin) SWIGTYPE *, SWIGTYPE (CLASS::*) "($jniinput == 0) ? null : new $javaclassname($jniinput, false)" -%typemap(javadirectorin) SWIGTYPE & "new $javaclassname($jniinput, false)" -%typemap(javadirectorin) SWIGTYPE && "new $javaclassname($jniinput, false)" -%typemap(javadirectorout) SWIGTYPE *, SWIGTYPE (CLASS::*), SWIGTYPE &, SWIGTYPE && "$javaclassname.getCPtr($javacall)" - -/* Default array handling */ -%typemap(in) SWIGTYPE [] %{ $1 = *($&1_ltype)&$input; %} -%typemap(out) SWIGTYPE [] %{ *($&1_ltype)&$result = $1; %} -%typemap(freearg) SWIGTYPE [ANY], SWIGTYPE [] "" - -/* char arrays - treat as String */ -%typemap(in, noblock=1) char[ANY], char[] { - $1 = 0; - if ($input) { - $1 = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0); - if (!$1) return $null; - } -} - -%typemap(directorout, noblock=1) char[ANY], char[] { - $1 = 0; - if ($input) { - $result = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0); - if (!$result) return $null; - } -} - -%typemap(directorin, descriptor="Ljava/lang/String;", noblock=1) char[ANY], char[] { - $input = 0; - if ($1) { - $input = JCALL1(NewStringUTF, jenv, (const char *)$1); - if (!$input) return $null; - } - Swig::LocalRefGuard $1_refguard(jenv, $input); -} - -%typemap(argout) char[ANY], char[] "" -%typemap(freearg, noblock=1) char[ANY], char[] { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, (const char *)$1); } -%typemap(out, noblock=1) char[ANY], char[] { if ($1) $result = JCALL1(NewStringUTF, jenv, (const char *)$1); } -%typemap(javadirectorin) char[ANY], char[] "$jniinput" -%typemap(javadirectorout) char[ANY], char[] "$javacall" - -/* JNI types */ -%typemap(in) jboolean, - jchar, - jbyte, - jshort, - jint, - jlong, - jfloat, - jdouble, - jstring, - jobject, - jbooleanArray, - jcharArray, - jbyteArray, - jshortArray, - jintArray, - jlongArray, - jfloatArray, - jdoubleArray, - jobjectArray -%{ $1 = $input; %} - -%typemap(directorout) jboolean, - jchar, - jbyte, - jshort, - jint, - jlong, - jfloat, - jdouble, - jstring, - jobject, - jbooleanArray, - jcharArray, - jbyteArray, - jshortArray, - jintArray, - jlongArray, - jfloatArray, - jdoubleArray, - jobjectArray -%{ $result = $input; %} - -%typemap(out) jboolean, - jchar, - jbyte, - jshort, - jint, - jlong, - jfloat, - jdouble, - jstring, - jobject, - jbooleanArray, - jcharArray, - jbyteArray, - jshortArray, - jintArray, - jlongArray, - jfloatArray, - jdoubleArray, - jobjectArray -%{ $result = $1; %} - -%typemap(directorin,descriptor="Z") jboolean "$input = $1;" -%typemap(directorin,descriptor="C") jchar "$input = $1;" -%typemap(directorin,descriptor="B") jbyte "$input = $1;" -%typemap(directorin,descriptor="S") jshort "$input = $1;" -%typemap(directorin,descriptor="I") jint "$input = $1;" -%typemap(directorin,descriptor="J") jlong "$input = $1;" -%typemap(directorin,descriptor="F") jfloat "$input = $1;" -%typemap(directorin,descriptor="D") jdouble "$input = $1;" -%typemap(directorin,descriptor="Ljava/lang/String;") jstring "$input = $1;" -%typemap(directorin,descriptor="Ljava/lang/Object;",nouse="1") jobject "$input = $1;" -%typemap(directorin,descriptor="[Z") jbooleanArray "$input = $1;" -%typemap(directorin,descriptor="[C") jcharArray "$input = $1;" -%typemap(directorin,descriptor="[B") jbyteArray "$input = $1;" -%typemap(directorin,descriptor="[S") jshortArray "$input = $1;" -%typemap(directorin,descriptor="[I") jintArray "$input = $1;" -%typemap(directorin,descriptor="[J") jlongArray "$input = $1;" -%typemap(directorin,descriptor="[F") jfloatArray "$input = $1;" -%typemap(directorin,descriptor="[D") jdoubleArray "$input = $1;" -%typemap(directorin,descriptor="[Ljava/lang/Object;",nouse="1") jobjectArray "$input = $1;" - -%typemap(javadirectorin) jboolean, - jchar, - jbyte, - jshort, - jint, - jlong, - jfloat, - jdouble, - jstring, - jobject, - jbooleanArray, - jcharArray, - jbyteArray, - jshortArray, - jintArray, - jlongArray, - jfloatArray, - jdoubleArray, - jobjectArray - "$jniinput" - -%typemap(javadirectorout) jboolean, - jchar, - jbyte, - jshort, - jint, - jlong, - jfloat, - jdouble, - jstring, - jobject, - jbooleanArray, - jcharArray, - jbyteArray, - jshortArray, - jintArray, - jlongArray, - jfloatArray, - jdoubleArray, - jobjectArray - "$javacall" - -/* Typecheck typemaps - The purpose of these is merely to issue a warning for overloaded C++ functions - * that cannot be overloaded in Java as more than one C++ type maps to a single Java type */ - -%typecheck(SWIG_TYPECHECK_BOOL) /* Java boolean */ - jboolean, - bool, - const bool & - "" - -%typecheck(SWIG_TYPECHECK_CHAR) /* Java char */ - jchar, - char, - const char & - "" - -%typecheck(SWIG_TYPECHECK_INT8) /* Java byte */ - jbyte, - signed char, - const signed char & - "" - -%typecheck(SWIG_TYPECHECK_INT16) /* Java short */ - jshort, - unsigned char, - short, - const unsigned char &, - const short & - "" - -%typecheck(SWIG_TYPECHECK_INT32) /* Java int */ - jint, - unsigned short, - int, - long, - const unsigned short &, - const int &, - const long & - "" - -%typecheck(SWIG_TYPECHECK_INT64) /* Java long */ - jlong, - unsigned int, - unsigned long, - long long, - const unsigned int &, - const unsigned long &, - const long long & - "" - -%typecheck(SWIG_TYPECHECK_INT128) /* Java BigInteger */ - unsigned long long, - const unsigned long long & - "" - -%typecheck(SWIG_TYPECHECK_FLOAT) /* Java float */ - jfloat, - float, - const float & - "" - -%typecheck(SWIG_TYPECHECK_DOUBLE) /* Java double */ - jdouble, - double, - const double & - "" - -%typecheck(SWIG_TYPECHECK_STRING) /* Java String */ - jstring, - char *, - char *&, - char[ANY], - char [] - "" - -%typecheck(SWIG_TYPECHECK_BOOL_ARRAY) /* Java boolean[] */ - jbooleanArray - "" - -%typecheck(SWIG_TYPECHECK_CHAR_ARRAY) /* Java char[] */ - jcharArray - "" - -%typecheck(SWIG_TYPECHECK_INT8_ARRAY) /* Java byte[] */ - jbyteArray - "" - -%typecheck(SWIG_TYPECHECK_INT16_ARRAY) /* Java short[] */ - jshortArray - "" - -%typecheck(SWIG_TYPECHECK_INT32_ARRAY) /* Java int[] */ - jintArray - "" - -%typecheck(SWIG_TYPECHECK_INT64_ARRAY) /* Java long[] */ - jlongArray - "" - -%typecheck(SWIG_TYPECHECK_FLOAT_ARRAY) /* Java float[] */ - jfloatArray - "" - -%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY) /* Java double[] */ - jdoubleArray - "" - -%typecheck(SWIG_TYPECHECK_OBJECT_ARRAY) /* Java jobject[] */ - jobjectArray - "" - -%typecheck(SWIG_TYPECHECK_POINTER) /* Default */ - SWIGTYPE, - SWIGTYPE *, - SWIGTYPE &, - SWIGTYPE &&, - SWIGTYPE *const&, - SWIGTYPE [], - SWIGTYPE (CLASS::*) - "" - - -/* Exception handling */ - -%typemap(throws) int, - long, - short, - unsigned int, - unsigned long, - unsigned short -%{ char error_msg[256]; - sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1); - SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, error_msg); - return $null; %} - -%typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE *, SWIGTYPE [], SWIGTYPE [ANY] -%{ (void)$1; - SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "C++ $1_type exception thrown"); - return $null; %} - -%typemap(throws) char * -%{ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1); - return $null; %} - -/* For methods to raise/throw the original Java exception thrown in a director method */ -%typemap(throws) Swig::DirectorException -%{ $1.throwException(jenv); - return $null; %} - -/* Java to C++ DirectorException should already be handled. Suppress warning and do nothing in the - event a user specifies a global: %catches(Swig::DirectorException); */ -%typemap(directorthrows) Swig::DirectorException "" - -/* Typemaps for code generation in proxy classes and Java type wrapper classes */ - -/* The javain typemap is used for converting function parameter types from the type - * used in the proxy, module or type wrapper class to the type used in the JNI class. */ -%typemap(javain) bool, const bool &, - char, const char &, - signed char, const signed char &, - unsigned char, const unsigned char &, - short, const short &, - unsigned short, const unsigned short &, - int, const int &, - unsigned int, const unsigned int &, - long, const long &, - unsigned long, const unsigned long &, - long long, const long long &, - unsigned long long, const unsigned long long &, - float, const float &, - double, const double & - "$javainput" -%typemap(javain) char *, char *&, char[ANY], char[] "$javainput" -%typemap(javain) jboolean, - jchar, - jbyte, - jshort, - jint, - jlong, - jfloat, - jdouble, - jstring, - jobject, - jbooleanArray, - jcharArray, - jbyteArray, - jshortArray, - jintArray, - jlongArray, - jfloatArray, - jdoubleArray, - jobjectArray - "$javainput" -%typemap(javain) SWIGTYPE "$&javaclassname.getCPtr($javainput)" -%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$javaclassname.getCPtr($javainput)" -%typemap(javain) SWIGTYPE && "$javaclassname.swigRelease($javainput)" -%typemap(javain) SWIGTYPE (CLASS::*) "$javaclassname.getCMemberPtr($javainput)" - -/* The javaout typemap is used for converting function return types from the return type - * used in the JNI class to the type returned by the proxy, module or type wrapper class. */ -%typemap(javaout) bool, const bool &, - char, const char &, - signed char, const signed char &, - unsigned char, const unsigned char &, - short, const short &, - unsigned short, const unsigned short &, - int, const int &, - unsigned int, const unsigned int &, - long, const long &, - unsigned long, const unsigned long &, - long long, const long long &, - unsigned long long, const unsigned long long &, - float, const float &, - double, const double & { - return $jnicall; - } -%typemap(javaout) char *, char *&, char[ANY], char[] { - return $jnicall; - } -%typemap(javaout) jboolean, - jchar, - jbyte, - jshort, - jint, - jlong, - jfloat, - jdouble, - jstring, - jobject, - jbooleanArray, - jcharArray, - jbyteArray, - jshortArray, - jintArray, - jlongArray, - jfloatArray, - jdoubleArray, - jobjectArray { - return $jnicall; - } -%typemap(javaout) void { - $jnicall; - } -%typemap(javaout) SWIGTYPE { - return new $&javaclassname($jnicall, true); - } -%typemap(javaout) SWIGTYPE & { - return new $javaclassname($jnicall, $owner); - } -%typemap(javaout) SWIGTYPE && { - return new $javaclassname($jnicall, $owner); - } -%typemap(javaout) SWIGTYPE *, SWIGTYPE [] { - long cPtr = $jnicall; - return (cPtr == 0) ? null : new $javaclassname(cPtr, $owner); - } -%typemap(javaout) SWIGTYPE (CLASS::*) { - String cMemberPtr = $jnicall; - return (cMemberPtr == null) ? null : new $javaclassname(cMemberPtr, $owner); - } - -/* Pointer reference typemaps */ -%typemap(jni) SWIGTYPE *const& "jlong" -%typemap(jtype) SWIGTYPE *const& "long" -%typemap(jstype) SWIGTYPE *const& "$*javaclassname" -%typemap(javain) SWIGTYPE *const& "$*javaclassname.getCPtr($javainput)" -%typemap(javaout) SWIGTYPE *const& { - long cPtr = $jnicall; - return (cPtr == 0) ? null : new $*javaclassname(cPtr, $owner); - } -%typemap(in) SWIGTYPE *const& ($*1_ltype temp = 0) -%{ temp = *($1_ltype)&$input; - $1 = ($1_ltype)&temp; %} -%typemap(out) SWIGTYPE *const& -%{ *($1_ltype)&$result = *$1; %} -%typemap(directorin,descriptor="L$packagepath/$*javaclassname;") SWIGTYPE *const& -%{ *(($1_ltype)&$input) = ($*1_ltype) $1; %} -%typemap(directorout, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) SWIGTYPE *const& -%{ static $*1_ltype swig_temp; - swig_temp = *($1_ltype)&$input; - $result = &swig_temp; %} -%typemap(javadirectorin) SWIGTYPE *const& "($jniinput == 0) ? null : new $*javaclassname($jniinput, false)" -%typemap(javadirectorout) SWIGTYPE *const& "$*javaclassname.getCPtr($javacall)" - -/* Typemaps used for the generation of proxy and type wrapper class code */ -%typemap(javabase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "" -%typemap(javaclassmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "public class" -%typemap(javacode) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "" -%typemap(javaimports) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "" -%typemap(javainterfaces) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "" -%typemap(javainterfacemodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "public interface" - -/* javabody typemaps */ - -%define SWIG_JAVABODY_METHODS(PTRCTOR_VISIBILITY, CPTR_VISIBILITY, TYPE...) SWIG_JAVABODY_PROXY(PTRCTOR_VISIBILITY, CPTR_VISIBILITY, TYPE) %enddef // legacy name - -%define SWIG_JAVABODY_PROXY(PTRCTOR_VISIBILITY, CPTR_VISIBILITY, TYPE...) -// Base proxy classes -%typemap(javabody) TYPE %{ - private transient long swigCPtr; - protected transient boolean swigCMemOwn; - - PTRCTOR_VISIBILITY $javaclassname(long cPtr, boolean cMemoryOwn) { - swigCMemOwn = cMemoryOwn; - swigCPtr = cPtr; - } - - CPTR_VISIBILITY static long getCPtr($javaclassname obj) { - return (obj == null) ? 0 : obj.swigCPtr; - } - - CPTR_VISIBILITY static long swigRelease($javaclassname obj) { - long ptr = 0; - if (obj != null) { - if (!obj.swigCMemOwn) - throw new RuntimeException("Cannot release ownership as memory is not owned"); - ptr = obj.swigCPtr; - obj.swigCMemOwn = false; - obj.delete(); - } - return ptr; - } -%} - -// Derived proxy classes -%typemap(javabody_derived) TYPE %{ - private transient long swigCPtr; - - PTRCTOR_VISIBILITY $javaclassname(long cPtr, boolean cMemoryOwn) { - super($imclassname.$javaclazznameSWIGUpcast(cPtr), cMemoryOwn); - swigCPtr = cPtr; - } - - CPTR_VISIBILITY static long getCPtr($javaclassname obj) { - return (obj == null) ? 0 : obj.swigCPtr; - } - - CPTR_VISIBILITY static long swigRelease($javaclassname obj) { - long ptr = 0; - if (obj != null) { - if (!obj.swigCMemOwn) - throw new RuntimeException("Cannot release ownership as memory is not owned"); - ptr = obj.swigCPtr; - obj.swigCMemOwn = false; - obj.delete(); - } - return ptr; - } -%} -%enddef - -%define SWIG_JAVABODY_TYPEWRAPPER(PTRCTOR_VISIBILITY, DEFAULTCTOR_VISIBILITY, CPTR_VISIBILITY, TYPE...) -// Typewrapper classes -%typemap(javabody) TYPE *, TYPE &, TYPE &&, TYPE [] %{ - private transient long swigCPtr; - - PTRCTOR_VISIBILITY $javaclassname(long cPtr, @SuppressWarnings("unused") boolean futureUse) { - swigCPtr = cPtr; - } - - DEFAULTCTOR_VISIBILITY $javaclassname() { - swigCPtr = 0; - } - - CPTR_VISIBILITY static long getCPtr($javaclassname obj) { - return (obj == null) ? 0 : obj.swigCPtr; - } - - CPTR_VISIBILITY static long swigRelease($javaclassname obj) { - return (obj == null) ? 0 : obj.swigCPtr; - } -%} - -%typemap(javabody) TYPE (CLASS::*) %{ - private transient String swigCMemberPtr; - - PTRCTOR_VISIBILITY $javaclassname(String cMemberPtr, @SuppressWarnings("unused") boolean futureUse) { - swigCMemberPtr = cMemberPtr; - } - - DEFAULTCTOR_VISIBILITY $javaclassname() { - swigCMemberPtr = null; - } - - CPTR_VISIBILITY static String getCMemberPtr($javaclassname obj) { - return obj.swigCMemberPtr; - } -%} -%enddef - -/* Set the default javabody typemaps to use protected visibility. - Use the macros to change to public if using multiple modules. */ -SWIG_JAVABODY_PROXY(protected, protected, SWIGTYPE) -SWIG_JAVABODY_TYPEWRAPPER(protected, protected, protected, SWIGTYPE) - -%typemap(javafinalize) SWIGTYPE %{ - @SuppressWarnings("deprecation") - protected void finalize() { - delete(); - } -%} - -/* - * Java constructor typemaps: - * - * The javaconstruct typemap is inserted when a proxy class's constructor is generated. - * This typemap allows control over what code is executed in the constructor as - * well as specifying who owns the underlying C/C++ object. Normally, Java has - * ownership and the underlying C/C++ object is deallocated when the Java object - * is finalized (swigCMemOwn is true.) If swigCMemOwn is false, C/C++ is - * ultimately responsible for deallocating the underlying object's memory. - * - * The SWIG_PROXY_CONSTRUCTOR macro defines the javaconstruct typemap for a proxy - * class for a particular TYPENAME. OWNERSHIP is passed as the value of - * swigCMemOwn to the pointer constructor method. WEAKREF determines which kind - * of Java object reference will be used by the C++ director class (WeakGlobalRef - * vs. GlobalRef.) - * - * The SWIG_DIRECTOR_OWNED macro sets the ownership of director-based proxy - * classes and the weak reference flag to false, meaning that the underlying C++ - * object will be reclaimed by C++. - */ - -%define SWIG_PROXY_CONSTRUCTOR(OWNERSHIP, WEAKREF, TYPENAME...) -%typemap(javaconstruct,directorconnect="\n $imclassname.$javaclazznamedirector_connect(this, swigCPtr, OWNERSHIP, WEAKREF);") TYPENAME { - this($imcall, OWNERSHIP);$directorconnect - } -%enddef - -%define SWIG_DIRECTOR_OWNED(TYPENAME...) -SWIG_PROXY_CONSTRUCTOR(true, false, TYPENAME) -%enddef - -// Set the default for SWIGTYPE: Java owns the C/C++ object. -SWIG_PROXY_CONSTRUCTOR(true, true, SWIGTYPE) - -%typemap(javadestruct, methodname="delete", methodmodifiers="public synchronized", parameters="") SWIGTYPE { - if (swigCPtr != 0) { - if (swigCMemOwn) { - swigCMemOwn = false; - $jnicall; - } - swigCPtr = 0; - } - } - -%typemap(javadestruct_derived, methodname="delete", methodmodifiers="public synchronized", parameters="") SWIGTYPE { - if (swigCPtr != 0) { - if (swigCMemOwn) { - swigCMemOwn = false; - $jnicall; - } - swigCPtr = 0; - } - super.delete(); - } - -%typemap(directordisconnect, methodname="swigDirectorDisconnect") SWIGTYPE %{ - protected void $methodname() { - swigCMemOwn = false; - $jnicall; - } -%} - -%typemap(directorowner_release, methodname="swigReleaseOwnership") SWIGTYPE %{ - public void $methodname() { - swigCMemOwn = false; - $jnicall; - } -%} - -%typemap(directorowner_take, methodname="swigTakeOwnership") SWIGTYPE %{ - public void $methodname() { - swigCMemOwn = true; - $jnicall; - } -%} - -/* Java specific directives */ -#define %javaconst(flag) %feature("java:const","flag") -#define %javaconstvalue(value) %feature("java:constvalue",value) -#define %javaenum(wrapapproach) %feature("java:enum","wrapapproach") -#define %javamethodmodifiers %feature("java:methodmodifiers") -#define %javaexception(exceptionclasses) %feature("except",throws=exceptionclasses) -#define %nojavaexception %feature("except","0",throws="") -#define %clearjavaexception %feature("except","",throws="") -#define %proxycode %insert("proxycode") - -%pragma(java) jniclassclassmodifiers="public class" -%pragma(java) moduleclassmodifiers="public class" - -/* Some ANSI C typemaps */ - -%apply unsigned long { size_t }; -%apply const unsigned long & { const size_t & }; - -/* Array reference typemaps */ -%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) } -%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) } - -/* const pointers */ -%apply SWIGTYPE * { SWIGTYPE *const } -%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } -%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } - -/* String & length */ -%typemap(jni) (const char *STRING, size_t LENGTH) "jbyteArray" -%typemap(jtype) (const char *STRING, size_t LENGTH) "byte[]" -%typemap(jstype) (const char *STRING, size_t LENGTH) "byte[]" -%typemap(javain) (const char *STRING, size_t LENGTH) "$javainput" -%typemap(freearg) (const char *STRING, size_t LENGTH) "" -%typemap(in) (const char *STRING, size_t LENGTH) { - if ($input) { - $1 = ($1_ltype) JCALL2(GetByteArrayElements, jenv, $input, 0); - $2 = ($2_type) JCALL1(GetArrayLength, jenv, $input); - } else { - $1 = 0; - $2 = 0; - } -} -%typemap(argout) (const char *STRING, size_t LENGTH) { - if ($input) JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *)$1, JNI_ABORT); -} -%typemap(directorin, descriptor="[B", noblock=1) (const char *STRING, size_t LENGTH) { - $input = 0; - if ($1) { - $input = JCALL1(NewByteArray, jenv, (jsize)$2); - if (!$input) return $null; - JCALL4(SetByteArrayRegion, jenv, $input, 0, (jsize)$2, (jbyte *)$1); - } - Swig::LocalRefGuard $1_refguard(jenv, $input); -} -%typemap(javadirectorin, descriptor="[B") (const char *STRING, size_t LENGTH) "$jniinput" -%apply (const char *STRING, size_t LENGTH) { (char *STRING, size_t LENGTH) } -/* Enable write-back for non-const version */ -%typemap(argout) (char *STRING, size_t LENGTH) { - if ($input) JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *)$1, 0); -} -%typemap(directorargout, noblock=1) (char *STRING, size_t LENGTH) -{ if ($input && $1) JCALL4(GetByteArrayRegion, jenv, $input, 0, (jsize)$2, (jbyte *)$1); } -%apply (char *STRING, size_t LENGTH) { (char *STRING, int LENGTH) } - -/* java keywords */ -%include <javakw.swg> - -// Default enum handling -%include <enumtypesafe.swg> - diff --git a/contrib/tools/swig/Lib/java/javahead.swg b/contrib/tools/swig/Lib/java/javahead.swg deleted file mode 100644 index 758a037d171..00000000000 --- a/contrib/tools/swig/Lib/java/javahead.swg +++ /dev/null @@ -1,91 +0,0 @@ -/* ----------------------------------------------------------------------------- - * javahead.swg - * - * Java support code - * ----------------------------------------------------------------------------- */ - - -/* JNI function calls require different calling conventions for C and C++. These JCALL macros are used so - * that the same typemaps can be used for generating code for both C and C++. The SWIG preprocessor can expand - * the macros thereby generating the correct calling convention. It is thus essential that all typemaps that - * use the macros are not within %{ %} brackets as they won't be run through the SWIG preprocessor. */ -#ifdef __cplusplus -# define JCALL0(func, jenv) jenv->func() -# define JCALL1(func, jenv, ar1) jenv->func(ar1) -# define JCALL2(func, jenv, ar1, ar2) jenv->func(ar1, ar2) -# define JCALL3(func, jenv, ar1, ar2, ar3) jenv->func(ar1, ar2, ar3) -# define JCALL4(func, jenv, ar1, ar2, ar3, ar4) jenv->func(ar1, ar2, ar3, ar4) -# define JCALL5(func, jenv, ar1, ar2, ar3, ar4, ar5) jenv->func(ar1, ar2, ar3, ar4, ar5) -# define JCALL6(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6) jenv->func(ar1, ar2, ar3, ar4, ar5, ar6) -# define JCALL7(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7) jenv->func(ar1, ar2, ar3, ar4, ar5, ar6, ar7) -#else -# define JCALL0(func, jenv) (*jenv)->func(jenv) -# define JCALL1(func, jenv, ar1) (*jenv)->func(jenv, ar1) -# define JCALL2(func, jenv, ar1, ar2) (*jenv)->func(jenv, ar1, ar2) -# define JCALL3(func, jenv, ar1, ar2, ar3) (*jenv)->func(jenv, ar1, ar2, ar3) -# define JCALL4(func, jenv, ar1, ar2, ar3, ar4) (*jenv)->func(jenv, ar1, ar2, ar3, ar4) -# define JCALL5(func, jenv, ar1, ar2, ar3, ar4, ar5) (*jenv)->func(jenv, ar1, ar2, ar3, ar4, ar5) -# define JCALL6(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6) (*jenv)->func(jenv, ar1, ar2, ar3, ar4, ar5, ar6) -# define JCALL7(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7) (*jenv)->func(jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7) -#endif - -%insert(runtime) %{ -#include <jni.h> -#include <stdlib.h> -#include <string.h> -%} - -%insert(runtime) %{ -/* Support for throwing Java exceptions */ -typedef enum { - SWIG_JavaOutOfMemoryError = 1, - SWIG_JavaIOException, - SWIG_JavaRuntimeException, - SWIG_JavaIndexOutOfBoundsException, - SWIG_JavaArithmeticException, - SWIG_JavaIllegalArgumentException, - SWIG_JavaNullPointerException, - SWIG_JavaDirectorPureVirtual, - SWIG_JavaUnknownError, - SWIG_JavaIllegalStateException, -} SWIG_JavaExceptionCodes; - -typedef struct { - SWIG_JavaExceptionCodes code; - const char *java_exception; -} SWIG_JavaExceptions_t; -%} - -%insert(runtime) { -static void SWIGUNUSED SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) { - jclass excep; - static const SWIG_JavaExceptions_t java_exceptions[] = { - { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" }, - { SWIG_JavaIOException, "java/io/IOException" }, - { SWIG_JavaRuntimeException, "java/lang/RuntimeException" }, - { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" }, - { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" }, - { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" }, - { SWIG_JavaNullPointerException, "java/lang/NullPointerException" }, - { SWIG_JavaDirectorPureVirtual, "java/lang/RuntimeException" }, - { SWIG_JavaUnknownError, "java/lang/UnknownError" }, - { SWIG_JavaIllegalStateException, "java/lang/IllegalStateException" }, - { (SWIG_JavaExceptionCodes)0, "java/lang/UnknownError" } - }; - const SWIG_JavaExceptions_t *except_ptr = java_exceptions; - - while (except_ptr->code != code && except_ptr->code) - except_ptr++; - - JCALL0(ExceptionClear, jenv); - excep = JCALL1(FindClass, jenv, except_ptr->java_exception); - if (excep) - JCALL2(ThrowNew, jenv, excep, msg); -} -} - -%insert(runtime) %{ -/* Contract support */ - -#define SWIG_contract_assert(nullreturn, expr, msg) do { if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } } while (0) -%} diff --git a/contrib/tools/swig/Lib/java/javakw.swg b/contrib/tools/swig/Lib/java/javakw.swg deleted file mode 100644 index 8a5b76eef2c..00000000000 --- a/contrib/tools/swig/Lib/java/javakw.swg +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef JAVA_JAVAKW_SWG_ -#define JAVA_JAVAKW_SWG_ - -/* Warnings for Java keywords */ -#define JAVAKW(x) %keywordwarn("'" `x` "' is a java keyword",rename="_%s") `x` - -/* - from - http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html -*/ - -JAVAKW(abstract); -JAVAKW(double); -JAVAKW(int); -JAVAKW(strictfp); -JAVAKW(boolean); -JAVAKW(else); -JAVAKW(interface); -JAVAKW(super); -JAVAKW(break); -JAVAKW(extends); -JAVAKW(long); -JAVAKW(switch); -JAVAKW(byte); -JAVAKW(final); -JAVAKW(native); -JAVAKW(synchronized); -JAVAKW(case); -JAVAKW(finally); -JAVAKW(new); -JAVAKW(this); -JAVAKW(catch); -JAVAKW(float); -JAVAKW(package); -JAVAKW(throw); -JAVAKW(char); -JAVAKW(for); -JAVAKW(private); -JAVAKW(throws); -JAVAKW(class); -JAVAKW(goto); -JAVAKW(protected); -JAVAKW(transient); -JAVAKW(const); -JAVAKW(if); -JAVAKW(public); -JAVAKW(try); -JAVAKW(continue); -JAVAKW(implements); -JAVAKW(return); -JAVAKW(void); -JAVAKW(default); -JAVAKW(import); -JAVAKW(short); -JAVAKW(volatile); -JAVAKW(do); -JAVAKW(instanceof); -JAVAKW(static); -JAVAKW(while); - - -/* others bad names */ - -/* Note here that only *::clone() is bad, and *::clone(int) is ok */ -%namewarn("321:clone() is a java bad method name") *::clone(); - - -#undef JAVAKW - -#endif //JAVA_JAVAKW_SWG_ diff --git a/contrib/tools/swig/Lib/java/typemaps.i b/contrib/tools/swig/Lib/java/typemaps.i deleted file mode 100644 index e130c1930bb..00000000000 --- a/contrib/tools/swig/Lib/java/typemaps.i +++ /dev/null @@ -1,529 +0,0 @@ -/* ----------------------------------------------------------------------------- - * typemaps.i - * - * Pointer and reference handling typemap library - * - * These mappings provide support for input/output arguments and common - * uses for C/C++ pointers and C++ references. - * ----------------------------------------------------------------------------- */ - -/* -INPUT typemaps --------------- - -These typemaps remap a C pointer or C++ reference to be an "INPUT" value which is -passed by value instead of reference. - -The following typemaps can be applied to turn a pointer or reference into a simple -input value. That is, instead of passing a pointer or reference to an object, -you would use a real value instead. - - bool *INPUT, bool &INPUT - signed char *INPUT, signed char &INPUT - unsigned char *INPUT, unsigned char &INPUT - short *INPUT, short &INPUT - unsigned short *INPUT, unsigned short &INPUT - int *INPUT, int &INPUT - unsigned int *INPUT, unsigned int &INPUT - long *INPUT, long &INPUT - unsigned long *INPUT, unsigned long &INPUT - long long *INPUT, long long &INPUT - unsigned long long *INPUT, unsigned long long &INPUT - float *INPUT, float &INPUT - double *INPUT, double &INPUT - -To use these, suppose you had a C function like this : - - double fadd(double *a, double *b) { - return *a+*b; - } - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - double fadd(double *INPUT, double *INPUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *INPUT { double *a, double *b }; - double fadd(double *a, double *b); - -In Java you could then use it like this: - double answer = modulename.fadd(10.0, 20.0); - -There are no char *INPUT typemaps, however you can apply the signed char * typemaps instead: - %include <typemaps.i> - %apply signed char *INPUT {char *input}; - void f(char *input); -*/ - -%define INPUT_TYPEMAP(TYPE, JNITYPE, JTYPE, JNIDESC) -%typemap(jni) TYPE *INPUT, TYPE &INPUT "JNITYPE" -%typemap(jtype) TYPE *INPUT, TYPE &INPUT "JTYPE" -%typemap(jstype) TYPE *INPUT, TYPE &INPUT "JTYPE" -%typemap(javain) TYPE *INPUT, TYPE &INPUT "$javainput" - -%typemap(in) TYPE *INPUT, TYPE &INPUT -%{ $1 = ($1_ltype)&$input; %} - -%typemap(freearg) TYPE *INPUT, TYPE &INPUT "" - -%typemap(typecheck) TYPE *INPUT = TYPE; -%typemap(typecheck) TYPE &INPUT = TYPE; -%enddef - -INPUT_TYPEMAP(bool, jboolean, boolean, "Z"); -INPUT_TYPEMAP(signed char, jbyte, byte, "B"); -INPUT_TYPEMAP(unsigned char, jshort, short, "S"); -INPUT_TYPEMAP(short, jshort, short, "S"); -INPUT_TYPEMAP(unsigned short, jint, int, "I"); -INPUT_TYPEMAP(int, jint, int, "I"); -INPUT_TYPEMAP(unsigned int, jlong, long, "J"); -INPUT_TYPEMAP(long, jint, int, "I"); -INPUT_TYPEMAP(unsigned long, jlong, long, "J"); -INPUT_TYPEMAP(long long, jlong, long, "J"); -INPUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, "Ljava/math/BigInteger;"); -INPUT_TYPEMAP(float, jfloat, float, "F"); -INPUT_TYPEMAP(double, jdouble, double, "D"); - -#undef INPUT_TYPEMAP - -/* Convert from BigInteger using the toByteArray member function */ -/* Overrides the typemap in the INPUT_TYPEMAP macro */ -%typemap(in) unsigned long long *INPUT($*1_ltype temp), unsigned long long &INPUT($*1_ltype temp) { - jclass clazz; - jmethodID mid; - jbyteArray ba; - jbyte* bae; - jsize sz; - int i; - - if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); - return $null; - } - clazz = JCALL1(GetObjectClass, jenv, $input); - mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); - ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid); - bae = JCALL2(GetByteArrayElements, jenv, ba, 0); - sz = JCALL1(GetArrayLength, jenv, ba); - temp = 0; - if (sz > 0) { - temp = ($*1_ltype)(signed char)bae[0]; - for(i=1; i<sz; i++) { - temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i]; - } - } - JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); - $1 = &temp; -} - -// OUTPUT typemaps. These typemaps are used for parameters that -// are output only. An array replaces the c pointer or reference parameter. -// The output value is returned in this array passed in. - -/* -OUTPUT typemaps ---------------- - -The following typemaps can be applied to turn a pointer or reference into an "output" -value. When calling a function, no input value would be given for -a parameter, but an output value would be returned. This works by a -Java array being passed as a parameter where a c pointer or reference is required. -As with any Java function, the array is passed by reference so that -any modifications to the array will be picked up in the calling function. -Note that the array passed in MUST have at least one element, but as the -c function does not require any input, the value can be set to anything. - - bool *OUTPUT, bool &OUTPUT - signed char *OUTPUT, signed char &OUTPUT - unsigned char *OUTPUT, unsigned char &OUTPUT - short *OUTPUT, short &OUTPUT - unsigned short *OUTPUT, unsigned short &OUTPUT - int *OUTPUT, int &OUTPUT - unsigned int *OUTPUT, unsigned int &OUTPUT - long *OUTPUT, long &OUTPUT - unsigned long *OUTPUT, unsigned long &OUTPUT - long long *OUTPUT, long long &OUTPUT - unsigned long long *OUTPUT, unsigned long long &OUTPUT - float *OUTPUT, float &OUTPUT - double *OUTPUT, double &OUTPUT - -For example, suppose you were trying to wrap the modf() function in the -C math library which splits x into integral and fractional parts (and -returns the integer part in one of its parameters): - - double modf(double x, double *ip); - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - double modf(double x, double *OUTPUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *OUTPUT { double *ip }; - double modf(double x, double *ip); - -The Java output of the function would be the function return value and the -value in the single element array. In Java you would use it like this: - - double[] ptr = {0.0}; - double fraction = modulename.modf(5.0,ptr); - -There are no char *OUTPUT typemaps, however you can apply the signed char * typemaps instead: - %include <typemaps.i> - %apply signed char *OUTPUT {char *output}; - void f(char *output); -*/ - -/* Java BigInteger[] */ -%typecheck(SWIG_TYPECHECK_INT128_ARRAY) SWIGBIGINTEGERARRAY "" - -%define OUTPUT_TYPEMAP(TYPE, JNITYPE, JTYPE, JAVATYPE, JNIDESC, TYPECHECKTYPE) -%typemap(jni) TYPE *OUTPUT, TYPE &OUTPUT %{JNITYPE##Array%} -%typemap(jtype) TYPE *OUTPUT, TYPE &OUTPUT "JTYPE[]" -%typemap(jstype) TYPE *OUTPUT, TYPE &OUTPUT "JTYPE[]" -%typemap(javain) TYPE *OUTPUT, TYPE &OUTPUT "$javainput" -%typemap(javadirectorin) TYPE *OUTPUT, TYPE &OUTPUT "$jniinput" -%typemap(javadirectorout) TYPE *OUTPUT, TYPE &OUTPUT "$javacall" - -%typemap(in) TYPE *OUTPUT($*1_ltype temp), TYPE &OUTPUT($*1_ltype temp) -{ - if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); - return $null; - } - if (JCALL1(GetArrayLength, jenv, $input) == 0) { - SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); - return $null; - } - temp = ($*1_ltype)0; - $1 = &temp; -} - -%typemap(freearg) TYPE *OUTPUT, TYPE &OUTPUT "" - -%typemap(argout) TYPE *OUTPUT, TYPE &OUTPUT -{ - JNITYPE jvalue = (JNITYPE)temp$argnum; - JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &jvalue); -} - -%typemap(directorin,descriptor=JNIDESC) TYPE &OUTPUT %{ - $input = JCALL1(New##JAVATYPE##Array, jenv, 1); - if (!$input) return $null; - Swig::LocalRefGuard $1_refguard(jenv, $input); %} - -%typemap(directorin,descriptor=JNIDESC) TYPE *OUTPUT %{ - if ($1) { - $input = JCALL1(New##JAVATYPE##Array, jenv, 1); - if (!$input) return $null; - } - Swig::LocalRefGuard $1_refguard(jenv, $input); %} - -%typemap(directorargout, noblock=1) TYPE &OUTPUT -{ - JNITYPE $1_jvalue; - JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue); - $result = ($*1_ltype)$1_jvalue; -} - -%typemap(directorargout, noblock=1) TYPE *OUTPUT -{ - if ($result) { - JNITYPE $1_jvalue; - JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue); - *$result = ($*1_ltype)$1_jvalue; - } -} - -%typemap(typecheck) TYPE *OUTPUT = TYPECHECKTYPE; -%typemap(typecheck) TYPE &OUTPUT = TYPECHECKTYPE; -%enddef - -OUTPUT_TYPEMAP(bool, jboolean, boolean, Boolean, "[Z", jbooleanArray); -OUTPUT_TYPEMAP(signed char, jbyte, byte, Byte, "[B", jbyteArray); -OUTPUT_TYPEMAP(unsigned char, jshort, short, Short, "[S", jshortArray); -OUTPUT_TYPEMAP(short, jshort, short, Short, "[S", jshortArray); -OUTPUT_TYPEMAP(unsigned short, jint, int, Int, "[I", jintArray); -OUTPUT_TYPEMAP(int, jint, int, Int, "[I", jintArray); -OUTPUT_TYPEMAP(unsigned int, jlong, long, Long, "[J", jlongArray); -OUTPUT_TYPEMAP(long, jint, int, Int, "[I", jintArray); -OUTPUT_TYPEMAP(unsigned long, jlong, long, Long, "[J", jlongArray); -OUTPUT_TYPEMAP(long long, jlong, long, Long, "[J", jlongArray); -OUTPUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, Object, "[Ljava/math/BigInteger;", jobjectArray); -OUTPUT_TYPEMAP(float, jfloat, float, Float, "[F", jfloatArray); -OUTPUT_TYPEMAP(double, jdouble, double, Double, "[D", jdoubleArray); - -#undef OUTPUT_TYPEMAP - -%typemap(in) bool *OUTPUT($*1_ltype temp), bool &OUTPUT($*1_ltype temp) -{ - if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); - return $null; - } - if (JCALL1(GetArrayLength, jenv, $input) == 0) { - SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); - return $null; - } - temp = false; - $1 = &temp; -} - -%typemap(directorargout, noblock=1) bool &OUTPUT -{ - jboolean $1_jvalue; - JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue); - $result = $1_jvalue ? true : false; -} - -%typemap(directorargout, noblock=1) bool *OUTPUT -{ - if ($result) { - jboolean $1_jvalue; - JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue); - *$result = $1_jvalue ? true : false; - } -} - - -/* Convert to BigInteger - byte array holds number in 2's complement big endian format */ -/* Use first element in BigInteger array for output */ -/* Overrides the typemap in the OUTPUT_TYPEMAP macro */ -%typemap(argout) unsigned long long *OUTPUT, unsigned long long &OUTPUT { - jbyteArray ba = JCALL1(NewByteArray, jenv, 9); - jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0); - jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger"); - jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "<init>", "([B)V"); - jobject bigint; - int i; - - bae[0] = 0; - for(i=1; i<9; i++ ) { - bae[i] = (jbyte)(temp$argnum>>8*(8-i)); - } - - JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); - bigint = JCALL3(NewObject, jenv, clazz, mid, ba); - JCALL1(DeleteLocalRef, jenv, ba); - JCALL3(SetObjectArrayElement, jenv, $input, 0, bigint); -} - -/* -INOUT typemaps --------------- - -Mappings for a parameter that is both an input and an output parameter - -The following typemaps can be applied to make a function parameter both -an input and output value. This combines the behavior of both the -"INPUT" and "OUTPUT" typemaps described earlier. Output values are -returned as an element in a Java array. - - bool *INOUT, bool &INOUT - signed char *INOUT, signed char &INOUT - unsigned char *INOUT, unsigned char &INOUT - short *INOUT, short &INOUT - unsigned short *INOUT, unsigned short &INOUT - int *INOUT, int &INOUT - unsigned int *INOUT, unsigned int &INOUT - long *INOUT, long &INOUT - unsigned long *INOUT, unsigned long &INOUT - long long *INOUT, long long &INOUT - unsigned long long *INOUT, unsigned long long &INOUT - float *INOUT, float &INOUT - double *INOUT, double &INOUT - -For example, suppose you were trying to wrap the following function : - - void neg(double *x) { - *x = -(*x); - } - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - void neg(double *INOUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *INOUT { double *x }; - void neg(double *x); - -This works similarly to C in that the mapping directly modifies the -input value - the input must be an array with a minimum of one element. -The element in the array is the input and the output is the element in -the array. - - double x[] = {5.0}; - neg(x); - -The implementation of the OUTPUT and INOUT typemaps is different to other -languages in that other languages will return the output value as part -of the function return value. This difference is due to Java being a typed language. - -There are no char *INOUT typemaps, however you can apply the signed char * typemaps instead: - %include <typemaps.i> - %apply signed char *INOUT {char *inout}; - void f(char *inout); -*/ - -%define INOUT_TYPEMAP(TYPE, JNITYPE, JTYPE, JAVATYPE, JNIDESC, TYPECHECKTYPE) -%typemap(jni) TYPE *INOUT, TYPE &INOUT %{JNITYPE##Array%} -%typemap(jtype) TYPE *INOUT, TYPE &INOUT "JTYPE[]" -%typemap(jstype) TYPE *INOUT, TYPE &INOUT "JTYPE[]" -%typemap(javain) TYPE *INOUT, TYPE &INOUT "$javainput" -%typemap(javadirectorin) TYPE *INOUT, TYPE &INOUT "$jniinput" -%typemap(javadirectorout) TYPE *INOUT, TYPE &INOUT "$javacall" - -%typemap(in) TYPE *INOUT, TYPE &INOUT { - if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); - return $null; - } - if (JCALL1(GetArrayLength, jenv, $input) == 0) { - SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); - return $null; - } - $1 = ($1_ltype) JCALL2(Get##JAVATYPE##ArrayElements, jenv, $input, 0); -} - -%typemap(freearg) TYPE *INOUT, TYPE &INOUT "" - -%typemap(argout) TYPE *INOUT, TYPE &INOUT -{ JCALL3(Release##JAVATYPE##ArrayElements, jenv, $input, (JNITYPE *)$1, 0); } - -%typemap(directorin,descriptor=JNIDESC) TYPE &INOUT %{ - $input = JCALL1(New##JAVATYPE##Array, jenv, 1); - if (!$input) return $null; - JNITYPE $1_jvalue = (JNITYPE)$1; - JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue); - Swig::LocalRefGuard $1_refguard(jenv, $input); %} - -%typemap(directorin,descriptor=JNIDESC) TYPE *INOUT %{ - if ($1) { - $input = JCALL1(New##JAVATYPE##Array, jenv, 1); - if (!$input) return $null; - JNITYPE $1_jvalue = (JNITYPE)*$1; - JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue); - } - Swig::LocalRefGuard $1_refguard(jenv, $input); %} - -%typemap(directorargout, noblock=1) TYPE &INOUT -{ - JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue); - $result = ($*1_ltype)$1_jvalue; -} - -%typemap(directorargout, noblock=1) TYPE *INOUT -{ - if ($result) { - JNITYPE $1_jvalue; - JCALL4(Get##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &$1_jvalue); - *$result = ($*1_ltype)$1_jvalue; - } -} - -%typemap(typecheck) TYPE *INOUT = TYPECHECKTYPE; -%typemap(typecheck) TYPE &INOUT = TYPECHECKTYPE; -%enddef - -INOUT_TYPEMAP(bool, jboolean, boolean, Boolean, "[Z", jbooleanArray); -INOUT_TYPEMAP(signed char, jbyte, byte, Byte, "[B", jbyteArray); -INOUT_TYPEMAP(unsigned char, jshort, short, Short, "[S", jshortArray); -INOUT_TYPEMAP(short, jshort, short, Short, "[S", jshortArray); -INOUT_TYPEMAP(unsigned short, jint, int, Int, "[I", jintArray); -INOUT_TYPEMAP(int, jint, int, Int, "[I", jintArray); -INOUT_TYPEMAP(unsigned int, jlong, long, Long, "[J", jlongArray); -INOUT_TYPEMAP(long, jint, int, Int, "[I", jintArray); -INOUT_TYPEMAP(unsigned long, jlong, long, Long, "[J", jlongArray); -INOUT_TYPEMAP(long long, jlong, long, Long, "[J", jlongArray); -INOUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, Object, "[java/math/BigInteger;", jobjectArray); -INOUT_TYPEMAP(float, jfloat, float, Float, "[F", jfloatArray); -INOUT_TYPEMAP(double, jdouble, double, Double, "[D", jdoubleArray); - -#undef INOUT_TYPEMAP - -/* Override typemaps in the INOUT_TYPEMAP macro for booleans to fix casts - as a jboolean isn't always the same size as a bool */ -%typemap(in) bool *INOUT (bool btemp, jboolean *jbtemp), bool &INOUT (bool btemp, jboolean *jbtemp) { - if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); - return $null; - } - if (JCALL1(GetArrayLength, jenv, $input) == 0) { - SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); - return $null; - } - jbtemp = JCALL2(GetBooleanArrayElements, jenv, $input, 0); - btemp = (*jbtemp) ? true : false; - $1 = &btemp; -} - -%typemap(argout) bool *INOUT, bool &INOUT { - *jbtemp$argnum = btemp$argnum ? (jboolean)1 : (jboolean)0; - JCALL3(ReleaseBooleanArrayElements, jenv, $input , (jboolean *)jbtemp$argnum, 0); -} - -%typemap(directorargout, noblock=1) bool &INOUT -{ - JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue); - $result = $1_jvalue ? true : false; -} - -%typemap(directorargout, noblock=1) bool *INOUT -{ - if ($result) { - jboolean $1_jvalue; - JCALL4(GetBooleanArrayRegion, jenv, $input, 0, 1, &$1_jvalue); - *$result = $1_jvalue ? true : false; - } -} - - -/* Override the typemap in the INOUT_TYPEMAP macro for unsigned long long */ -%typemap(in) unsigned long long *INOUT ($*1_ltype temp), unsigned long long &INOUT ($*1_ltype temp) { - jobject bigint; - jclass clazz; - jmethodID mid; - jbyteArray ba; - jbyte* bae; - jsize sz; - int i; - - if (!$input) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); - return $null; - } - if (JCALL1(GetArrayLength, jenv, $input) == 0) { - SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); - return $null; - } - bigint = JCALL2(GetObjectArrayElement, jenv, $input, 0); - if (!bigint) { - SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array element null"); - return $null; - } - clazz = JCALL1(GetObjectClass, jenv, bigint); - mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); - ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, bigint, mid); - bae = JCALL2(GetByteArrayElements, jenv, ba, 0); - sz = JCALL1(GetArrayLength, jenv, ba); - temp = 0; - if (sz > 0) { - temp = ($*1_ltype)(signed char)bae[0]; - for(i=1; i<sz; i++) { - temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i]; - } - } - JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); - $1 = &temp; -} - -%typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; -%typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; diff --git a/contrib/tools/swig/Lib/perl5/extra-install.list b/contrib/tools/swig/Lib/perl5/extra-install.list deleted file mode 100644 index db93830aabf..00000000000 --- a/contrib/tools/swig/Lib/perl5/extra-install.list +++ /dev/null @@ -1,2 +0,0 @@ -# see top-level Makefile.in -Makefile.pl noembed.h diff --git a/contrib/tools/swig/Lib/perl5/perl5.swg b/contrib/tools/swig/Lib/perl5/perl5.swg deleted file mode 100644 index 693c2b9457c..00000000000 --- a/contrib/tools/swig/Lib/perl5/perl5.swg +++ /dev/null @@ -1,42 +0,0 @@ -/* ------------------------------------------------------------ - * perl.swg - * - * Perl configuration module. - * ------------------------------------------------------------ */ - -/* ------------------------------------------------------------ - * Inner macros - * ------------------------------------------------------------ */ -%include <perlmacros.swg> - -/* ------------------------------------------------------------ - * The runtime part - * ------------------------------------------------------------ */ -%include <perlruntime.swg> - -/* ------------------------------------------------------------ - * Special user directives - * ------------------------------------------------------------ */ -%include <perluserdir.swg> - -/* ------------------------------------------------------------ - * Typemap specializations - * ------------------------------------------------------------ */ -%include <perltypemaps.swg> - -/* ------------------------------------------------------------ - * Overloaded operator support - * ------------------------------------------------------------ */ -%include <perlopers.swg> - -/* ------------------------------------------------------------ - * Warnings for Perl keywords - * ------------------------------------------------------------ */ -%include <perlkw.swg> - -/* ------------------------------------------------------------ - * The Perl initialization function - * ------------------------------------------------------------ */ -%include <perlinit.swg> - - diff --git a/contrib/tools/swig/Lib/perl5/perlfragments.swg b/contrib/tools/swig/Lib/perl5/perlfragments.swg deleted file mode 100644 index 45d25d1f6c3..00000000000 --- a/contrib/tools/swig/Lib/perl5/perlfragments.swg +++ /dev/null @@ -1,23 +0,0 @@ -/* - - Create a file with this name, 'perlfragments.swg', in your working - directory and add all the %fragments you want to take precedence - over the ones defined by default by swig. - - For example, if you add: - - %fragment(SWIG_AsVal_frag(int),"header") { - SWIGINTERNINLINE int - SWIG_AsVal(int)(PyObject *obj, int *val) - { - <your code here>; - } - } - - this will replace the code used to retrieve an integer value for all - the typemaps that need it, including: - - int, std::vector<int>, std::list<std::pair<int,int> >, etc. - - -*/ diff --git a/contrib/tools/swig/Lib/perl5/perlinit.swg b/contrib/tools/swig/Lib/perl5/perlinit.swg deleted file mode 100644 index c26b93fadb9..00000000000 --- a/contrib/tools/swig/Lib/perl5/perlinit.swg +++ /dev/null @@ -1,78 +0,0 @@ - -/* Export the SWIG initialization function */ -%header %{ -#ifdef __cplusplus -extern "C" -#endif -#ifndef MULTIPLICITY -SWIGEXPORT void SWIG_init (CV* cv); -#else -SWIGEXPORT void SWIG_init (pTHXo_ CV* cv); -#endif -%} - -/* Module initialization function */ - -%insert(init) "swiginit.swg" - -%init %{ - -#if defined(__cplusplus) && ! defined(XSPROTO) -extern "C" -#endif - -XS(SWIG_init) { - dXSARGS; - int i; - (void)items; - - SWIG_InitializeModule(0); - - /* Install commands */ - for (i = 0; swig_commands[i].name; i++) { - /* Casts only needed for Perl < 5.10. */ -#ifdef __cplusplus - newXS(const_cast<char*>(swig_commands[i].name), swig_commands[i].wrapper, const_cast<char*>(__FILE__)); -#else - newXS((char*)swig_commands[i].name, swig_commands[i].wrapper, (char*)__FILE__); -#endif - } - - /* Install variables */ - for (i = 0; swig_variables[i].name; i++) { - SV *sv; - sv = get_sv(swig_variables[i].name, TRUE | 0x2 | GV_ADDMULTI); - if (swig_variables[i].type) { - SWIG_MakePtr(sv,(void *)1, *swig_variables[i].type,0); - } else { - sv_setiv(sv,(IV) 0); - } - swig_create_magic(sv, swig_variables[i].name, swig_variables[i].set, swig_variables[i].get); - } - - /* Install constant */ - for (i = 0; swig_constants[i].type; i++) { - SV *sv; - sv = get_sv(swig_constants[i].name, TRUE | 0x2 | GV_ADDMULTI); - switch(swig_constants[i].type) { - case SWIG_INT: - sv_setiv(sv, (IV) swig_constants[i].lvalue); - break; - case SWIG_FLOAT: - sv_setnv(sv, (double) swig_constants[i].dvalue); - break; - case SWIG_STRING: - sv_setpv(sv, (const char *) swig_constants[i].pvalue); - break; - case SWIG_POINTER: - SWIG_MakePtr(sv, swig_constants[i].pvalue, *(swig_constants[i].ptype),0); - break; - case SWIG_BINARY: - SWIG_MakePackedObj(sv, swig_constants[i].pvalue, swig_constants[i].lvalue, *(swig_constants[i].ptype)); - break; - default: - break; - } - SvREADONLY_on(sv); - } -%} diff --git a/contrib/tools/swig/Lib/perl5/perlkw.swg b/contrib/tools/swig/Lib/perl5/perlkw.swg deleted file mode 100644 index 00648e0bf38..00000000000 --- a/contrib/tools/swig/Lib/perl5/perlkw.swg +++ /dev/null @@ -1,251 +0,0 @@ -/* Warnings for Perl keywords */ -#define PERLKW(x) %keywordwarn("'" `x` "' is a perl keyword") `x` -#define PERLBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in perl") "::" `x` - - -/* - - From http://www.rocketaware.com/perl/perlfunc/ - -*/ - -/* Functions for SCALARs or strings*/ -PERLBN(chomp); -PERLBN(chop); -PERLBN(chr); -PERLBN(crypt); -PERLBN(hex); -PERLBN(index); -PERLBN(lc); -PERLBN(lcfirst); -PERLBN(length); -PERLBN(oct); -PERLBN(ord); -PERLBN(pack); -PERLBN(reverse); -PERLBN(rindex); -PERLBN(sprintf); -PERLBN(substr); -PERLBN(uc); -PERLBN(ucfirst); - -/* Regular expressions and pattern matching */ -PERLBN(m); -PERLBN(pos); -PERLBN(quotemeta); -PERLBN(split); -PERLBN(study); - -/* Numeric functions */ -PERLBN(abs); -PERLBN(atan2); -PERLBN(cos); -PERLBN(exp); -PERLBN(hex); -PERLBN(int); -PERLBN(log); -PERLBN(oct); -PERLBN(rand); -PERLBN(sin); -PERLBN(sqrt); -PERLBN(srand); - - -/* Functions for real @ARRAYs*/ -PERLBN(pop); -PERLBN(push); -PERLBN(shift); -PERLBN(splice); -PERLBN(unshift); - -/* Functions for list data*/ -PERLBN(grep); -PERLBN(join); -PERLBN(map); -PERLBN(qw); -PERLBN(reverse); -PERLBN(sort); -PERLBN(unpack); - - -/* Functions for real %HASHes*/ -PERLBN(delete); -PERLBN(each); -PERLBN(exists); -PERLBN(keys); -PERLBN(values); - - -/* Input and output functions*/ - -PERLBN(binmode); -PERLBN(close); -PERLBN(closedir); -PERLBN(dbmclose); -PERLBN(dbmopen); -PERLBN(die); -PERLBN(eof); -PERLBN(fileno); -PERLBN(flock); -PERLBN(format); -PERLBN(getc); -PERLBN(print); -PERLBN(printf); -PERLBN(read); -PERLBN(readdir); -PERLBN(rewinddir); -PERLBN(seek); -PERLBN(seekdir); -PERLBN(select); -PERLBN(syscall); -PERLBN(sysread); -PERLBN(sysseek); -PERLBN(syswrite); -PERLBN(tell); -PERLBN(telldir); -PERLBN(truncate); -PERLBN(warn); -PERLBN(write); - - -/* Functions for fixed length data or records*/ -PERLBN(pack); -PERLBN(read); -PERLBN(syscall); -PERLBN(sysread); -PERLBN(syswrite); -PERLBN(unpack); -PERLBN(vec); - - -/* Functions for filehandles, files, or directories */ -PERLBN(chdir); -PERLBN(chmod); -PERLBN(chown); -PERLBN(chroot); -PERLBN(fcntl); -PERLBN(glob); -PERLBN(ioctl); -PERLBN(link); -PERLBN(lstat); -PERLBN(mkdir); -PERLBN(open); -PERLBN(opendir); -PERLBN(readlink); -PERLBN(rename); -PERLBN(rmdir); -PERLBN(stat); -PERLBN(symlink); -PERLBN(umask); -PERLBN(unlink); -PERLBN(utime); - - -/* Keywords related to the control flow of your perl program */ -PERLKW(caller); -PERLKW(continue); -PERLKW(die); -PERLKW(do); -PERLKW(dump); -PERLKW(eval); -PERLKW(exit); -PERLKW(goto); -PERLKW(last); -PERLKW(next); -PERLKW(redo); -PERLKW(return); -PERLKW(sub); -PERLKW(wantarray); - - -/* Keywords related to scoping */ -PERLKW(caller); -PERLKW(import); -PERLKW(local); -PERLKW(my); -PERLKW(package); -PERLKW(use); - - -/* Miscellaneous functions */ -PERLBN("defined"); -PERLBN(dump); -PERLBN(eval); -PERLBN(formline); -PERLBN(local); -PERLBN(my); -PERLBN(reset); -PERLBN(scalar); -PERLBN(undef); -PERLBN(wantarray); - - -/* Functions for processes and process groups */ -PERLBN(alarm); -PERLBN(exec); -PERLBN(fork); -PERLBN(getpgrp); -PERLBN(getppid); -PERLBN(getpriority); -PERLBN(kill); -PERLBN(pipe); -PERLBN(setpgrp); -PERLBN(setpriority); -PERLBN(sleep); -PERLBN(system); -PERLBN(times); -PERLBN(wait); -PERLBN(waitpid); - - -/* Keywords related to perl modules */ -PERLKW(do); -PERLKW(import); -PERLKW(no); -PERLKW(package); -PERLKW(require); -PERLKW(use); - - -/* Keywords related to classes and object-orientedness */ -PERLKW(bless); -PERLKW(dbmclose); -PERLKW(dbmopen); -PERLKW(package); -PERLKW(ref); -PERLKW(tie); -PERLKW(tied); -PERLKW(untie); -PERLKW(use); - -/* Functions new in perl5 */ -PERLBN(abs); -PERLBN(bless); -PERLBN(chomp); -PERLBN(chr); -PERLBN(exists); -PERLBN(formline); -PERLBN(glob); -PERLBN(import); -PERLBN(lc); -PERLBN(lcfirst); -PERLBN(map); -PERLBN(my); -PERLBN(no); -PERLBN(prototype); -PERLBN(qx); -PERLBN(qw); -PERLBN(readline); -PERLBN(readpipe); -PERLBN(ref); -PERLBN(sub); -PERLBN(sysopen); -PERLBN(tie); -PERLBN(tied); -PERLBN(uc); -PERLBN(ucfirst); -PERLBN(untie); -PERLBN(use); - -#undef PERLKW -#undef PERLBN diff --git a/contrib/tools/swig/Lib/perl5/perlmacros.swg b/contrib/tools/swig/Lib/perl5/perlmacros.swg deleted file mode 100644 index 4917f6efc59..00000000000 --- a/contrib/tools/swig/Lib/perl5/perlmacros.swg +++ /dev/null @@ -1,2 +0,0 @@ -%include <typemaps/swigmacros.swg> - diff --git a/contrib/tools/swig/Lib/perl5/perlopers.swg b/contrib/tools/swig/Lib/perl5/perlopers.swg deleted file mode 100644 index e7d13b678ad..00000000000 --- a/contrib/tools/swig/Lib/perl5/perlopers.swg +++ /dev/null @@ -1,54 +0,0 @@ -/* ------------------------------------------------------------ - * Overloaded operator support - * ------------------------------------------------------------ */ - -#ifdef __cplusplus - -// These are auto-supported by the Perl-module -%rename(__plusplus__) *::operator++; -%rename(__minmin__) *::operator--; -%rename(__add__) *::operator+; -%rename(__sub__) *::operator-; -%rename(__neg__) *::operator-(); -%rename(__neg__) *::operator-() const; -%rename(__mul__) *::operator*; -%rename(__div__) *::operator/; -%rename(__eq__) *::operator==; -%rename(__ne__) *::operator!=; -%rename(__mod__) *::operator%; -%rename(__gt__) *::operator>; -%rename(__lt__) *::operator<; -%rename(__not__) *::operator!; -%rename(__le__) *::operator<=; -%rename(__ge__) *::operator>=; -%rename(__and__) *::operator&; -%rename(__or__) *::operator|; -%rename(__iadd__) *::operator+=; -%rename(__isub__) *::operator-=; - -// These are renamed, but no test exists in operator_overload_runme.pl -%ignoreoperator(EQ) operator=; - -// These are renamed, but no 'use overload...' is added -%rename(__lshift__) *::operator<<; -%rename(__rshift__) *::operator>>; -%rename(__xor__) *::operator^; -%rename(__invert__) *::operator~; -%rename(__call__) *::operator(); - -/* Ignored operators */ -%ignoreoperator(LAND) operator&&; -%ignoreoperator(LOR) operator||; -%ignoreoperator(MULEQ) operator*=; -%ignoreoperator(DIVEQ) operator/=; -%ignoreoperator(MODEQ) operator%=; -%ignoreoperator(LSHIFTEQ) operator<<=; -%ignoreoperator(RSHIFTEQ) operator>>=; -%ignoreoperator(ANDEQ) operator&=; -%ignoreoperator(OREQ) operator|=; -%ignoreoperator(XOREQ) operator^=; -%ignoreoperator(ARROWSTAR) operator->*; -%ignoreoperator(INDEX) operator[]; - - -#endif /* __cplusplus */ diff --git a/contrib/tools/swig/Lib/perl5/perlprimtypes.swg b/contrib/tools/swig/Lib/perl5/perlprimtypes.swg deleted file mode 100644 index 4cb675671c1..00000000000 --- a/contrib/tools/swig/Lib/perl5/perlprimtypes.swg +++ /dev/null @@ -1,364 +0,0 @@ -/* ------------------------------------------------------------ - * Primitive Types - * ------------------------------------------------------------ */ - -/* bool */ - -%fragment(SWIG_From_frag(bool),"header") { -SWIGINTERNINLINE SV * -SWIG_From_dec(bool)(bool value) -{ - return boolSV(value); -} -} - -%fragment(SWIG_AsVal_frag(bool),"header") { -SWIGINTERN int -SWIG_AsVal_dec(bool)(SV *obj, bool* val) -{ - if (obj == &PL_sv_yes) { - if (val) *val = true; - return SWIG_OK; - } else if (obj == &PL_sv_no) { - if (val) *val = false; - return SWIG_OK; - } else { - if (val) *val = SvTRUE(obj) ? true : false; - return SWIG_AddCast(SWIG_OK); - } -} -} - - -/* long */ - -%fragment(SWIG_From_frag(long),"header") { -SWIGINTERNINLINE SV * -SWIG_From_dec(long)(long value) -{ - SV *sv; - if (IVSIZE >= sizeof(value) || (value >= IV_MIN && value <= IV_MAX)) - sv = newSViv(value); - else - sv = newSVpvf("%ld", value); - return sv_2mortal(sv); -} -} - -%fragment(SWIG_AsVal_frag(long),"header", - fragment="<limits.h>", - fragment="<stdlib.h>", - fragment="SWIG_CanCastAsInteger") { -SWIGINTERN int -SWIG_AsVal_dec(long)(SV *obj, long* val) -{ - if (SvUOK(obj)) { - UV v = SvUV(obj); - if (UVSIZE < sizeof(*val) || v <= LONG_MAX) { - if (val) *val = v; - return SWIG_OK; - } - return SWIG_OverflowError; - } else if (SvIOK(obj)) { - IV v = SvIV(obj); - if (IVSIZE <= sizeof(*val) || (v >= LONG_MIN && v <= LONG_MAX)) { - if(val) *val = v; - return SWIG_OK; - } - return SWIG_OverflowError; - } else { - int dispatch = 0; - const char *nptr = SvPV_nolen(obj); - if (nptr) { - char *endptr; - long v; - errno = 0; - v = strtol(nptr, &endptr,0); - if (errno == ERANGE) { - errno = 0; - return SWIG_OverflowError; - } else { - if (*endptr == '\0') { - if (val) *val = v; - return SWIG_Str2NumCast(SWIG_OK); - } - } - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { - if (val) *val = (long)(d); - return res; - } - } - } - return SWIG_TypeError; -} -} - -/* unsigned long */ - -%fragment(SWIG_From_frag(unsigned long),"header") { -SWIGINTERNINLINE SV * -SWIG_From_dec(unsigned long)(unsigned long value) -{ - SV *sv; - if (UVSIZE >= sizeof(value) || value <= UV_MAX) - sv = newSVuv(value); - else - sv = newSVpvf("%lu", value); - return sv_2mortal(sv); -} -} - -%fragment(SWIG_AsVal_frag(unsigned long),"header", - fragment="<limits.h>", - fragment="<stdlib.h>", - fragment="SWIG_CanCastAsInteger") { -SWIGINTERN int -SWIG_AsVal_dec(unsigned long)(SV *obj, unsigned long *val) -{ - if (SvUOK(obj)) { - UV v = SvUV(obj); - if (UVSIZE <= sizeof(*val) || v <= ULONG_MAX) { - if (val) *val = v; - return SWIG_OK; - } - return SWIG_OverflowError; - } else if (SvIOK(obj)) { - IV v = SvIV(obj); - if (v >= 0 && (IVSIZE <= sizeof(*val) || v <= ULONG_MAX)) { - if (val) *val = v; - return SWIG_OK; - } - return SWIG_OverflowError; - } else { - int dispatch = 0; - const char *nptr = SvPV_nolen(obj); - if (nptr) { - char *endptr; - unsigned long v; - errno = 0; - v = strtoul(nptr, &endptr,0); - if (errno == ERANGE) { - errno = 0; - return SWIG_OverflowError; - } else { - if (*endptr == '\0') { - if (val) *val = v; - return SWIG_Str2NumCast(SWIG_OK); - } - } - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) { - if (val) *val = (unsigned long)(d); - return res; - } - } - } - return SWIG_TypeError; -} -} - -/* long long */ - -%fragment(SWIG_From_frag(long long),"header", - fragment="SWIG_LongLongAvailable", - fragment="<stdio.h>") { -%#ifdef SWIG_LONG_LONG_AVAILABLE -SWIGINTERNINLINE SV * -SWIG_From_dec(long long)(long long value) -{ - SV *sv; - if (IVSIZE >= sizeof(value) || (value >= IV_MIN && value <= IV_MAX)) - sv = newSViv((IV)(value)); - else { - //sv = newSVpvf("%lld", value); doesn't work in non 64bit Perl - char temp[256]; - sprintf(temp, "%lld", value); - sv = newSVpv(temp, 0); - } - return sv_2mortal(sv); -} -%#endif -} - -%fragment(SWIG_AsVal_frag(long long),"header", - fragment="SWIG_LongLongAvailable", - fragment="<stdlib.h>", - fragment="SWIG_CanCastAsInteger") { -%#ifdef SWIG_LONG_LONG_AVAILABLE -SWIGINTERN int -SWIG_AsVal_dec(long long)(SV *obj, long long *val) -{ - if (SvUOK(obj)) { - UV v = SvUV(obj); - /* pretty sure this could allow v == LLONG MAX */ - if (UVSIZE < sizeof(*val) || v < LLONG_MAX) { - if (val) *val = v; - return SWIG_OK; - } - return SWIG_OverflowError; - } else if (SvIOK(obj)) { - IV v = SvIV(obj); - if (IVSIZE <= sizeof(*val) || (v >= LLONG_MIN && v <= LLONG_MAX)) { - if (val) *val = v; - return SWIG_OK; - } - return SWIG_OverflowError; - } else { - int dispatch = 0; - const char *nptr = SvPV_nolen(obj); - if (nptr) { - char *endptr; - long long v; - errno = 0; - v = strtoll(nptr, &endptr,0); - if (errno == ERANGE) { - errno = 0; - return SWIG_OverflowError; - } else { - if (*endptr == '\0') { - if (val) *val = v; - return SWIG_Str2NumCast(SWIG_OK); - } - } - } - if (!dispatch) { - const double mant_max = 1LL << DBL_MANT_DIG; - const double mant_min = -mant_max; - double d; - int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, mant_min, mant_max)) { - if (val) *val = (long long)(d); - return res; - } - } - } - return SWIG_TypeError; -} -%#endif -} - -/* unsigned long long */ - -%fragment(SWIG_From_frag(unsigned long long),"header", - fragment="SWIG_LongLongAvailable", - fragment="<stdio.h>") { -%#ifdef SWIG_LONG_LONG_AVAILABLE -SWIGINTERNINLINE SV * -SWIG_From_dec(unsigned long long)(unsigned long long value) -{ - SV *sv; - if (UVSIZE >= sizeof(value) || value <= UV_MAX) - sv = newSVuv((UV)(value)); - else { - //sv = newSVpvf("%llu", value); doesn't work in non 64bit Perl - char temp[256]; - sprintf(temp, "%llu", value); - sv = newSVpv(temp, 0); - } - return sv_2mortal(sv); -} -%#endif -} - -%fragment(SWIG_AsVal_frag(unsigned long long),"header", - fragment="SWIG_LongLongAvailable", - fragment="<stdlib.h>", - fragment="SWIG_CanCastAsInteger") { -%#ifdef SWIG_LONG_LONG_AVAILABLE -SWIGINTERN int -SWIG_AsVal_dec(unsigned long long)(SV *obj, unsigned long long *val) -{ - if (SvUOK(obj)) { - /* pretty sure this should be conditional on - * (UVSIZE <= sizeof(*val) || v <= ULLONG_MAX) */ - if (val) *val = SvUV(obj); - return SWIG_OK; - } else if (SvIOK(obj)) { - IV v = SvIV(obj); - if (v >= 0 && (IVSIZE <= sizeof(*val) || v <= ULLONG_MAX)) { - if (val) *val = v; - return SWIG_OK; - } else { - return SWIG_OverflowError; - } - } else { - int dispatch = 0; - const char *nptr = SvPV_nolen(obj); - if (nptr) { - char *endptr; - unsigned long long v; - errno = 0; - v = strtoull(nptr, &endptr,0); - if (errno == ERANGE) { - errno = 0; - return SWIG_OverflowError; - } else { - if (*endptr == '\0') { - if (val) *val = v; - return SWIG_Str2NumCast(SWIG_OK); - } - } - } - if (!dispatch) { - const double mant_max = 1LL << DBL_MANT_DIG; - double d; - int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, mant_max)) { - if (val) *val = (unsigned long long)(d); - return res; - } - } - } - return SWIG_TypeError; -} -%#endif -} - -/* double */ - -%fragment(SWIG_From_frag(double),"header") { -SWIGINTERNINLINE SV * -SWIG_From_dec(double)(double value) -{ - return sv_2mortal(newSVnv(value)); -} -} - -%fragment(SWIG_AsVal_frag(double),"header") { -SWIGINTERN int -SWIG_AsVal_dec(double)(SV *obj, double *val) -{ - if (SvNIOK(obj)) { - if (val) *val = SvNV(obj); - return SWIG_OK; - } else if (SvIOK(obj)) { - if (val) *val = (double) SvIV(obj); - return SWIG_AddCast(SWIG_OK); - } else { - const char *nptr = SvPV_nolen(obj); - if (nptr) { - char *endptr; - double v; - errno = 0; - v = strtod(nptr, &endptr); - if (errno == ERANGE) { - errno = 0; - return SWIG_OverflowError; - } else { - if (*endptr == '\0') { - if (val) *val = v; - return SWIG_Str2NumCast(SWIG_OK); - } - } - } - } - return SWIG_TypeError; -} -} diff --git a/contrib/tools/swig/Lib/perl5/perlruntime.swg b/contrib/tools/swig/Lib/perl5/perlruntime.swg deleted file mode 100644 index f948023de7a..00000000000 --- a/contrib/tools/swig/Lib/perl5/perlruntime.swg +++ /dev/null @@ -1,8 +0,0 @@ - -%runtime "swigrun.swg" // Common C API type-checking code -%runtime "swigerrors.swg" // SWIG errors -%runtime "perlhead.swg" // Perl includes and fixes -%runtime "perlerrors.swg" // Perl errors -%runtime "perlrun.swg" // Perl runtime functions -%runtime "noembed.h" // undefine Perl5 macros - diff --git a/contrib/tools/swig/Lib/perl5/perlstrings.swg b/contrib/tools/swig/Lib/perl5/perlstrings.swg deleted file mode 100644 index 242a9c96734..00000000000 --- a/contrib/tools/swig/Lib/perl5/perlstrings.swg +++ /dev/null @@ -1,59 +0,0 @@ -/* ------------------------------------------------------------ - * utility methods for char strings - * ------------------------------------------------------------ */ - -%fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { -SWIGINTERN int -SWIG_AsCharPtrAndSize(SV *obj, char** cptr, size_t* psize, int *alloc) -{ - if (SvMAGICAL(obj)) { - SV *tmp = sv_newmortal(); - SvSetSV(tmp, obj); - obj = tmp; - } - if (SvPOK(obj)) { - STRLEN len = 0; - char *cstr = SvPV(obj, len); - size_t size = len + 1; - if (cptr) { - if (alloc) { - if (*alloc == SWIG_NEWOBJ) { - *cptr = %new_copy_array(cstr, size, char); - } else { - *cptr = cstr; - *alloc = SWIG_OLDOBJ; - } - } - } - if (psize) *psize = size; - return SWIG_OK; - } else { - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - if (pchar_descriptor) { - char* vptr = 0; - if (SWIG_ConvertPtr(obj, (void**)&vptr, pchar_descriptor, 0) == SWIG_OK) { - if (cptr) *cptr = vptr; - if (psize) *psize = vptr ? (strlen(vptr) + 1) : 0; - if (alloc) *alloc = SWIG_OLDOBJ; - return SWIG_OK; - } - } - } - return SWIG_TypeError; -} -} - -%fragment("SWIG_FromCharPtrAndSize","header") { -SWIGINTERNINLINE SV * -SWIG_FromCharPtrAndSize(const char* carray, size_t size) -{ - SV *obj = sv_newmortal(); - if (carray) { - sv_setpvn(obj, carray, size); - } else { - sv_setsv(obj, &PL_sv_undef); - } - return obj; -} -} - diff --git a/contrib/tools/swig/Lib/perl5/perltypemaps.swg b/contrib/tools/swig/Lib/perl5/perltypemaps.swg deleted file mode 100644 index 42f8887befd..00000000000 --- a/contrib/tools/swig/Lib/perl5/perltypemaps.swg +++ /dev/null @@ -1,104 +0,0 @@ -/* ------------------------------------------------------------ - * Typemap specializations for Perl - * ------------------------------------------------------------ */ - -/* ------------------------------------------------------------ - * Fragment section - * ------------------------------------------------------------ */ - -/* - in Perl we need to pass the CPerlObj value, sometimes, so, we define - the decl/call macros as needed. -*/ - -#define SWIG_AS_DECL_ARGS SWIG_PERL_DECL_ARGS_2 -#define SWIG_AS_CALL_ARGS SWIG_PERL_CALL_ARGS_2 - -#define SWIG_FROM_DECL_ARGS SWIG_PERL_DECL_ARGS_1 -#define SWIG_FROM_CALL_ARGS SWIG_PERL_CALL_ARGS_1 - - -/* Include fundamental fragment definitions */ -%include <typemaps/fragments.swg> - -/* Look for user fragments file. */ -%include <perlfragments.swg> - -/* Perl fragments for primitive types */ -%include <perlprimtypes.swg> - -/* Perl fragments for char* strings */ -%include <perlstrings.swg> - - -/* ------------------------------------------------------------ - * Unified typemap section - * ------------------------------------------------------------ */ - -/* director support in Perl is experimental */ -#ifndef SWIG_DIRECTOR_TYPEMAPS -#define SWIG_DIRECTOR_TYPEMAPS -#endif - - -/* Perl types */ -#define SWIG_Object SV * -#define VOID_Object &PL_sv_undef - -/* Perl $shadow flag */ -#define %newpointer_flags $shadow -#define %newinstance_flags $shadow - - -/* Complete overload of the output/constant/exception macros */ - -/* output */ -%define %set_output(obj) $result = obj; argvi++ %enddef - -/* append output */ -%define %append_output(obj) -if (argvi >= items) EXTEND(sp, argvi+1); -%set_output(obj) %enddef - -/* variable output */ -%define %set_varoutput(obj) sv_setsv($result,obj) %enddef - -/* constant */ -%define %set_constant(name, obj) %begin_block - SV *sv = get_sv((char*) SWIG_prefix name, TRUE | 0x2 | GV_ADDMULTI); - sv_setsv(sv, obj); - SvREADONLY_on(sv); -%end_block %enddef - -/* raise exception */ -%define %raise(obj, type, desc) sv_setsv(get_sv("@", GV_ADD), obj); SWIG_fail %enddef - -/* For directors to raise/throw the original exception */ -%typemap(throws) Swig::DirectorException -%{ sv_setsv(ERRSV, $1.getNative()); SWIG_fail; %} - -/* Include the unified typemap library */ -%include <typemaps/swigtypemaps.swg> - -/* ------------------------------------------------------------ - * Perl extra typemaps / typemap overrides - * ------------------------------------------------------------ */ - -%typemap(varout,type="$1_descriptor") SWIGTYPE *, SWIGTYPE [] - "sv_setiv(SvRV($result),PTR2IV($1));"; - -%typemap(varout,type="$1_descriptor") SWIGTYPE & - "sv_setiv(SvRV($result),PTR2IV(&$1));"; - -%typemap(varout,type="$1_descriptor") SWIGTYPE && - "sv_setiv(SvRV($result),PTR2IV(&$1));"; - -%typemap(varout,type="$&1_descriptor") SWIGTYPE - "sv_setiv(SvRV($result), PTR2IV(&$1));"; - -%typemap(varout,type="$1_descriptor") SWIGTYPE (CLASS::*) { - SWIG_MakePackedObj($result, (void *) &$1, sizeof($1), $1_descriptor); -} - -%typemap(varout) SWIGTYPE *const = SWIGTYPE *; - diff --git a/contrib/tools/swig/Lib/perl5/perluserdir.swg b/contrib/tools/swig/Lib/perl5/perluserdir.swg deleted file mode 100644 index 718440e8372..00000000000 --- a/contrib/tools/swig/Lib/perl5/perluserdir.swg +++ /dev/null @@ -1,2 +0,0 @@ -#define %perlcode %insert("perl") - diff --git a/contrib/tools/swig/Lib/perl5/reference.i b/contrib/tools/swig/Lib/perl5/reference.i deleted file mode 100644 index b424c533b1b..00000000000 --- a/contrib/tools/swig/Lib/perl5/reference.i +++ /dev/null @@ -1,261 +0,0 @@ -/* ----------------------------------------------------------------------------- - * reference.i - * - * Accept Perl references as pointers - * ----------------------------------------------------------------------------- */ - -/* -The following methods make Perl references work like simple C -pointers. References can only be used for simple input/output -values, not C arrays however. It should also be noted that -REFERENCES are specific to Perl and not supported in other -scripting languages at this time. - - int *REFERENCE - short *REFERENCE - long *REFERENCE - unsigned int *REFERENCE - unsigned short *REFERENCE - unsigned long *REFERENCE - unsigned char *REFERENCE - float *REFERENCE - double *REFERENCE - -For example, suppose you were trying to wrap the following function : - - void neg(double *x) { - *x = -(*x); - } - -You could wrap it with SWIG as follows : - - %include reference.i - void neg(double *REFERENCE); - -or you can use the %apply directive : - - %include reference.i - %apply double *REFERENCE { double *x }; - void neg(double *x); - -Unlike the INOUT mapping described in typemaps.i, this approach directly -modifies the value of a Perl reference. Thus, you could use it -as follows : - - $x = 3; - neg(\$x); - print "$x\n"; # Should print out -3. - -*/ - -%typemap(in) double *REFERENCE (double dvalue), double &REFERENCE(double dvalue) -{ - SV *tempsv; - if (!SvROK($input)) { - SWIG_croak("expected a reference"); - } - tempsv = SvRV($input); - if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { - printf("Received %d\n", SvTYPE(tempsv)); - SWIG_croak("Expected a double reference."); - } - dvalue = SvNV(tempsv); - $1 = &dvalue; -} - -%typemap(in) float *REFERENCE (float dvalue), float &REFERENCE(float dvalue) -{ - SV *tempsv; - if (!SvROK($input)) { - SWIG_croak("expected a reference"); - } - tempsv = SvRV($input); - if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { - SWIG_croak("expected a double reference"); - } - dvalue = (float) SvNV(tempsv); - $1 = &dvalue; -} - -%typemap(in) int *REFERENCE (int dvalue), int &REFERENCE (int dvalue) -{ - SV *tempsv; - if (!SvROK($input)) { - SWIG_croak("expected a reference"); - } - tempsv = SvRV($input); - if (!SvIOK(tempsv)) { - SWIG_croak("expected an integer reference"); - } - dvalue = SvIV(tempsv); - $1 = &dvalue; -} - -%typemap(in) short *REFERENCE (short dvalue), short &REFERENCE(short dvalue) -{ - SV *tempsv; - if (!SvROK($input)) { - SWIG_croak("expected a reference"); - } - tempsv = SvRV($input); - if (!SvIOK(tempsv)) { - SWIG_croak("expected an integer reference"); - } - dvalue = (short) SvIV(tempsv); - $1 = &dvalue; -} -%typemap(in) long *REFERENCE (long dvalue), long &REFERENCE(long dvalue) -{ - SV *tempsv; - if (!SvROK($input)) { - SWIG_croak("expected a reference"); - } - tempsv = SvRV($input); - if (!SvIOK(tempsv)) { - SWIG_croak("expected an integer reference"); - } - dvalue = (long) SvIV(tempsv); - $1 = &dvalue; -} -%typemap(in) unsigned int *REFERENCE (unsigned int dvalue), unsigned int &REFERENCE(unsigned int dvalue) -{ - SV *tempsv; - if (!SvROK($input)) { - SWIG_croak("expected a reference"); - } - tempsv = SvRV($input); - if (!SvIOK(tempsv)) { - SWIG_croak("expected an integer reference"); - } - dvalue = (unsigned int) SvUV(tempsv); - $1 = &dvalue; -} -%typemap(in) unsigned short *REFERENCE (unsigned short dvalue), unsigned short &REFERENCE(unsigned short dvalue) -{ - SV *tempsv; - if (!SvROK($input)) { - SWIG_croak("expected a reference"); - } - tempsv = SvRV($input); - if (!SvIOK(tempsv)) { - SWIG_croak("expected an integer reference"); - } - dvalue = (unsigned short) SvUV(tempsv); - $1 = &dvalue; -} -%typemap(in) unsigned long *REFERENCE (unsigned long dvalue), unsigned long &REFERENCE(unsigned long dvalue) -{ - SV *tempsv; - if (!SvROK($input)) { - SWIG_croak("expected a reference"); - } - tempsv = SvRV($input); - if (!SvIOK(tempsv)) { - SWIG_croak("expected an integer reference"); - } - dvalue = (unsigned long) SvUV(tempsv); - $1 = &dvalue; -} - -%typemap(in) unsigned char *REFERENCE (unsigned char dvalue), unsigned char &REFERENCE(unsigned char dvalue) -{ - SV *tempsv; - if (!SvROK($input)) { - SWIG_croak("expected a reference"); - } - tempsv = SvRV($input); - if (!SvIOK(tempsv)) { - SWIG_croak("expected an integer reference"); - } - dvalue = (unsigned char) SvUV(tempsv); - $1 = &dvalue; -} - -%typemap(in) signed char *REFERENCE (signed char dvalue), signed char &REFERENCE(signed char dvalue) -{ - SV *tempsv; - if (!SvROK($input)) { - SWIG_croak("expected a reference"); - } - tempsv = SvRV($input); - if (!SvIOK(tempsv)) { - SWIG_croak("expected an integer reference"); - } - dvalue = (signed char) SvIV(tempsv); - $1 = &dvalue; -} - -%typemap(in) bool *REFERENCE (bool dvalue), bool &REFERENCE(bool dvalue) -{ - SV *tempsv; - if (!SvROK($input)) { - SWIG_croak("expected a reference"); - } - tempsv = SvRV($input); - if (!SvIOK(tempsv)) { - SWIG_croak("expected an integer reference"); - } - dvalue = SvIV(tempsv) ? true : false; - $1 = &dvalue; -} - -%typemap(typecheck) int *REFERENCE, int &REFERENCE, - short *REFERENCE, short &REFERENCE, - long *REFERENCE, long &REFERENCE, - signed char *REFERENCE, signed char &REFERENCE, - bool *REFERENCE, bool &REFERENCE -{ - $1 = SvROK($input) && SvIOK(SvRV($input)); -} -%typemap(typecheck) double *REFERENCE, double &REFERENCE, - float *REFERENCE, float &REFERENCE -{ - $1 = SvROK($input); - if($1) { - SV *tmpsv = SvRV($input); - $1 = SvNOK(tmpsv) || SvIOK(tmpsv); - } -} -%typemap(typecheck) unsigned int *REFERENCE, unsigned int &REFERENCE, - unsigned short *REFERENCE, unsigned short &REFERENCE, - unsigned long *REFERENCE, unsigned long &REFERENCE, - unsigned char *REFERENCE, unsigned char &REFERENCE -{ - $1 = SvROK($input); - if($1) { - SV *tmpsv = SvRV($input); - $1 = SvUOK(tmpsv) || SvIOK(tmpsv); - } -} - -%typemap(argout) double *REFERENCE, double &REFERENCE, - float *REFERENCE, float &REFERENCE -{ - SV *tempsv; - tempsv = SvRV($arg); - if (!$1) SWIG_croak("expected a reference"); - sv_setnv(tempsv, (double) *$1); -} - -%typemap(argout) int *REFERENCE, int &REFERENCE, - short *REFERENCE, short &REFERENCE, - long *REFERENCE, long &REFERENCE, - signed char *REFERENCE, signed char &REFERENCE, - bool *REFERENCE, bool &REFERENCE -{ - SV *tempsv; - tempsv = SvRV($input); - if (!$1) SWIG_croak("expected a reference"); - sv_setiv(tempsv, (IV) *$1); -} - -%typemap(argout) unsigned int *REFERENCE, unsigned int &REFERENCE, - unsigned short *REFERENCE, unsigned short &REFERENCE, - unsigned long *REFERENCE, unsigned long &REFERENCE, - unsigned char *REFERENCE, unsigned char &REFERENCE -{ - SV *tempsv; - tempsv = SvRV($input); - if (!$1) SWIG_croak("expected a reference"); - sv_setuv(tempsv, (UV) *$1); -} diff --git a/contrib/tools/swig/Lib/perl5/typemaps.i b/contrib/tools/swig/Lib/perl5/typemaps.i deleted file mode 100644 index 3e1f60d9047..00000000000 --- a/contrib/tools/swig/Lib/perl5/typemaps.i +++ /dev/null @@ -1,371 +0,0 @@ -/* ----------------------------------------------------------------------------- - * typemaps.i - * - * The SWIG typemap library provides a language independent mechanism for - * supporting output arguments, input values, and other C function - * calling mechanisms. The primary use of the library is to provide a - * better interface to certain C function--especially those involving - * pointers. - * ----------------------------------------------------------------------------- */ - -#if !defined(SWIG_USE_OLD_TYPEMAPS) -%include <typemaps/typemaps.swg> -#else - - -// INPUT typemaps. -// These remap a C pointer to be an "INPUT" value which is passed by value -// instead of reference. - - -/* -The following methods can be applied to turn a pointer into a simple -"input" value. That is, instead of passing a pointer to an object, -you would use a real value instead. - - int *INPUT - short *INPUT - long *INPUT - long long *INPUT - unsigned int *INPUT - unsigned short *INPUT - unsigned long *INPUT - unsigned long long *INPUT - unsigned char *INPUT - bool *INPUT - float *INPUT - double *INPUT - -To use these, suppose you had a C function like this : - - double fadd(double *a, double *b) { - return *a+*b; - } - -You could wrap it with SWIG as follows : - - %include typemaps.i - double fadd(double *INPUT, double *INPUT); - -or you can use the %apply directive : - - %include typemaps.i - %apply double *INPUT { double *a, double *b }; - double fadd(double *a, double *b); - -*/ - -%define INPUT_TYPEMAP(type, converter) -%typemap(in) type *INPUT(type temp), type &INPUT(type temp) { - temp = (type) converter($input); - $1 = &temp; -} -%typemap(typecheck) type *INPUT = type; -%typemap(typecheck) type &INPUT = type; -%enddef - -INPUT_TYPEMAP(float, SvNV); -INPUT_TYPEMAP(double, SvNV); -INPUT_TYPEMAP(int, SvIV); -INPUT_TYPEMAP(long, SvIV); -INPUT_TYPEMAP(short, SvIV); -INPUT_TYPEMAP(signed char, SvIV); -INPUT_TYPEMAP(unsigned int, SvUV); -INPUT_TYPEMAP(unsigned long, SvUV); -INPUT_TYPEMAP(unsigned short, SvUV); -INPUT_TYPEMAP(unsigned char, SvUV); - -%typemap(in) bool *INPUT(bool temp), bool &INPUT(bool temp) { - temp = SvIV($input) ? true : false; - $1 = &temp; -} -%typemap(typecheck) bool *INPUT = bool; -%typemap(typecheck) bool &INPUT = bool; - -%typemap(in) long long *INPUT($*1_ltype temp), long long &INPUT($*1_ltype temp) { - temp = strtoll(SvPV_nolen($input), 0, 0); - $1 = &temp; -} -%typemap(typecheck) long long *INPUT = long long; -%typemap(typecheck) long long &INPUT = long long; - -%typemap(in) unsigned long long *INPUT($*1_ltype temp), unsigned long long &INPUT($*1_ltype temp) { - temp = strtoull(SvPV_nolen($input), 0, 0); - $1 = &temp; -} -%typemap(typecheck) unsigned long long *INPUT = unsigned long long; -%typemap(typecheck) unsigned long long &INPUT = unsigned long long; - - -#undef INPUT_TYPEMAP - -// OUTPUT typemaps. These typemaps are used for parameters that -// are output only. The output value is appended to the result as -// a list element. - -/* -The following methods can be applied to turn a pointer into an "output" -value. When calling a function, no input value would be given for -a parameter, but an output value would be returned. In the case of -multiple output values, functions will return a Perl array. - - int *OUTPUT - short *OUTPUT - long *OUTPUT - long long *OUTPUT - unsigned int *OUTPUT - unsigned short *OUTPUT - unsigned long *OUTPUT - unsigned long long *OUTPUT - unsigned char *OUTPUT - bool *OUTPUT - float *OUTPUT - double *OUTPUT - -For example, suppose you were trying to wrap the modf() function in the -C math library which splits x into integral and fractional parts (and -returns the integer part in one of its parameters).: - - double modf(double x, double *ip); - -You could wrap it with SWIG as follows : - - %include typemaps.i - double modf(double x, double *OUTPUT); - -or you can use the %apply directive : - - %include typemaps.i - %apply double *OUTPUT { double *ip }; - double modf(double x, double *ip); - -The Perl output of the function would be an array containing both -output values. - -*/ - -// Force the argument to be ignored. - -%typemap(in,numinputs=0) int *OUTPUT(int temp), int &OUTPUT(int temp), - short *OUTPUT(short temp), short &OUTPUT(short temp), - long *OUTPUT(long temp), long &OUTPUT(long temp), - unsigned int *OUTPUT(unsigned int temp), unsigned int &OUTPUT(unsigned int temp), - unsigned short *OUTPUT(unsigned short temp), unsigned short &OUTPUT(unsigned short temp), - unsigned long *OUTPUT(unsigned long temp), unsigned long &OUTPUT(unsigned long temp), - unsigned char *OUTPUT(unsigned char temp), unsigned char &OUTPUT(unsigned char temp), - signed char *OUTPUT(signed char temp), signed char &OUTPUT(signed char temp), - bool *OUTPUT(bool temp), bool &OUTPUT(bool temp), - float *OUTPUT(float temp), float &OUTPUT(float temp), - double *OUTPUT(double temp), double &OUTPUT(double temp), - long long *OUTPUT($*1_ltype temp), long long &OUTPUT($*1_ltype temp), - unsigned long long *OUTPUT($*1_ltype temp), unsigned long long &OUTPUT($*1_ltype temp) -"$1 = &temp;"; - -%typemap(argout) int *OUTPUT, int &OUTPUT, - short *OUTPUT, short &OUTPUT, - long *OUTPUT, long &OUTPUT, - signed char *OUTPUT, signed char &OUTPUT, - bool *OUTPUT, bool &OUTPUT -{ - if (argvi >= items) { - EXTEND(sp, argvi+1); - } - $result = sv_newmortal(); - sv_setiv($result,(IV) *($1)); - argvi++; -} - -%typemap(argout) unsigned int *OUTPUT, unsigned int &OUTPUT, - unsigned short *OUTPUT, unsigned short &OUTPUT, - unsigned long *OUTPUT, unsigned long &OUTPUT, - unsigned char *OUTPUT, unsigned char &OUTPUT -{ - if (argvi >= items) { - EXTEND(sp, argvi+1); - } - $result = sv_newmortal(); - sv_setuv($result,(UV) *($1)); - argvi++; -} - - - -%typemap(argout) float *OUTPUT, float &OUTPUT, - double *OUTPUT, double &OUTPUT -{ - if (argvi >= items) { - EXTEND(sp, argvi+1); - } - $result = sv_newmortal(); - sv_setnv($result,(double) *($1)); - argvi++; -} - -%typemap(argout) long long *OUTPUT, long long &OUTPUT { - char temp[256]; - if (argvi >= items) { - EXTEND(sp, argvi+1); - } - sprintf(temp,"%lld", (long long)*($1)); - $result = sv_newmortal(); - sv_setpv($result,temp); - argvi++; -} - -%typemap(argout) unsigned long long *OUTPUT, unsigned long long &OUTPUT { - char temp[256]; - if (argvi >= items) { - EXTEND(sp, argvi+1); - } - sprintf(temp,"%llu", (unsigned long long)*($1)); - $result = sv_newmortal(); - sv_setpv($result,temp); - argvi++; -} - -// INOUT -// Mappings for an argument that is both an input and output -// parameter - -/* -The following methods can be applied to make a function parameter both -an input and output value. This combines the behavior of both the -"INPUT" and "OUTPUT" methods described earlier. Output values are -returned in the form of a Perl array. - - int *INOUT - short *INOUT - long *INOUT - long long *INOUT - unsigned int *INOUT - unsigned short *INOUT - unsigned long *INOUT - unsigned long long *INOUT - unsigned char *INOUT - bool *INOUT - float *INOUT - double *INOUT - -For example, suppose you were trying to wrap the following function : - - void neg(double *x) { - *x = -(*x); - } - -You could wrap it with SWIG as follows : - - %include typemaps.i - void neg(double *INOUT); - -or you can use the %apply directive : - - %include typemaps.i - %apply double *INOUT { double *x }; - void neg(double *x); - -Unlike C, this mapping does not directly modify the input value. -Rather, the modified input value shows up as the return value of the -function. Thus, to apply this function to a Perl variable you might -do this : - - $x = neg($x); - -*/ - -%typemap(in) int *INOUT = int *INPUT; -%typemap(in) short *INOUT = short *INPUT; -%typemap(in) long *INOUT = long *INPUT; -%typemap(in) unsigned *INOUT = unsigned *INPUT; -%typemap(in) unsigned short *INOUT = unsigned short *INPUT; -%typemap(in) unsigned long *INOUT = unsigned long *INPUT; -%typemap(in) unsigned char *INOUT = unsigned char *INPUT; -%typemap(in) signed char *INOUT = signed char *INPUT; -%typemap(in) bool *INOUT = bool *INPUT; -%typemap(in) float *INOUT = float *INPUT; -%typemap(in) double *INOUT = double *INPUT; -%typemap(in) long long *INOUT = long long *INPUT; -%typemap(in) unsigned long long *INOUT = unsigned long long *INPUT; - -%typemap(in) int &INOUT = int &INPUT; -%typemap(in) short &INOUT = short &INPUT; -%typemap(in) long &INOUT = long &INPUT; -%typemap(in) unsigned &INOUT = unsigned &INPUT; -%typemap(in) unsigned short &INOUT = unsigned short &INPUT; -%typemap(in) unsigned long &INOUT = unsigned long &INPUT; -%typemap(in) unsigned char &INOUT = unsigned char &INPUT; -%typemap(in) signed char &INOUT = signed char &INPUT; -%typemap(in) bool &INOUT = bool &INPUT; -%typemap(in) float &INOUT = float &INPUT; -%typemap(in) double &INOUT = double &INPUT; -%typemap(in) long long &INOUT = long long &INPUT; -%typemap(in) unsigned long long &INOUT = unsigned long long &INPUT; - - -%typemap(argout) int *INOUT = int *OUTPUT; -%typemap(argout) short *INOUT = short *OUTPUT; -%typemap(argout) long *INOUT = long *OUTPUT; -%typemap(argout) unsigned *INOUT = unsigned *OUTPUT; -%typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; -%typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; -%typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; -%typemap(argout) signed char *INOUT = signed char *OUTPUT; -%typemap(argout) bool *INOUT = bool *OUTPUT; -%typemap(argout) float *INOUT = float *OUTPUT; -%typemap(argout) double *INOUT = double *OUTPUT; -%typemap(argout) long long *INOUT = long long *OUTPUT; -%typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; - - -%typemap(argout) int &INOUT = int &OUTPUT; -%typemap(argout) short &INOUT = short &OUTPUT; -%typemap(argout) long &INOUT = long &OUTPUT; -%typemap(argout) unsigned &INOUT = unsigned &OUTPUT; -%typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; -%typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; -%typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; -%typemap(argout) signed char &INOUT = signed char &OUTPUT; -%typemap(argout) bool &INOUT = bool &OUTPUT; -%typemap(argout) float &INOUT = float &OUTPUT; -%typemap(argout) double &INOUT = double &OUTPUT; -%typemap(argout) long long &INOUT = long long &OUTPUT; -%typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; - - -/* Overloading information */ - -%typemap(typecheck) double *INOUT = double; -%typemap(typecheck) bool *INOUT = bool; -%typemap(typecheck) signed char *INOUT = signed char; -%typemap(typecheck) unsigned char *INOUT = unsigned char; -%typemap(typecheck) unsigned long *INOUT = unsigned long; -%typemap(typecheck) unsigned short *INOUT = unsigned short; -%typemap(typecheck) unsigned int *INOUT = unsigned int; -%typemap(typecheck) long *INOUT = long; -%typemap(typecheck) short *INOUT = short; -%typemap(typecheck) int *INOUT = int; -%typemap(typecheck) float *INOUT = float; -%typemap(typecheck) long long *INOUT = long long; -%typemap(typecheck) unsigned long long *INOUT = unsigned long long; - -%typemap(typecheck) double &INOUT = double; -%typemap(typecheck) bool &INOUT = bool; -%typemap(typecheck) signed char &INOUT = signed char; -%typemap(typecheck) unsigned char &INOUT = unsigned char; -%typemap(typecheck) unsigned long &INOUT = unsigned long; -%typemap(typecheck) unsigned short &INOUT = unsigned short; -%typemap(typecheck) unsigned int &INOUT = unsigned int; -%typemap(typecheck) long &INOUT = long; -%typemap(typecheck) short &INOUT = short; -%typemap(typecheck) int &INOUT = int; -%typemap(typecheck) float &INOUT = float; -%typemap(typecheck) long long &INOUT = long long; -%typemap(typecheck) unsigned long long &INOUT = unsigned long long; - -#endif - -// -------------------------------------------------------------------- -// Special types -// -------------------------------------------------------------------- - - -%include <reference.i> diff --git a/contrib/tools/swig/Lib/python/README b/contrib/tools/swig/Lib/python/README deleted file mode 100644 index 70968e7dd58..00000000000 --- a/contrib/tools/swig/Lib/python/README +++ /dev/null @@ -1,103 +0,0 @@ -/* ----------------------------------------------------------------------------- - * - * User interfaces: include these ones as needed - * - * ----------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------------- - * Special types and user helpers - * ----------------------------------------------------------------------------- */ - -argcargv.i Handler for (int argc, char **argv) -attribute.i Convert a pair of set/get methods into a "native" python attribute -ccomplex.i C99 complex type -complex.i C99 or C++ complex type -cstring.i Various forms of C character string handling -cwstring.i Various forms of C wchar_t string handling -embed.i embedding the Python interpreter in something else -file.i FILE C type -implicit.i Allow the use of implicit C++ constructors -wchar.i wchar_t C type - -/* ----------------------------------------------------------------------------- - * C++ STD + STL - * ----------------------------------------------------------------------------- */ - -std_alloc.i allocator -std_basic_string.i basic string -std_char_traits.i char traits -std_complex.i complex -std_deque.i deque -std_except.i exceptions -std_ios.i ios -std_iostream.i istream/ostream -std_list.i list -std_map.i map -std_multimap.i multimap -std_multiset.i multiset -std_pair.i pair -std_set.i set -std_sstream.i string stream -std_streambuf.i streambuf -std_string.i string -std_vector.i vector -std_wios.i wios -std_wiostream.i wistream/wostream -std_wsstream.i wstring stream -std_wstreambuf.i wstreambuf -std_wstring.i wstring - - - -/* ----------------------------------------------------------------------------- -/* - * Implementation files: don't look at them unless you are really drunk - * - * ----------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------------- - * Basic files - * ----------------------------------------------------------------------------- */ - -python.swg Main language file, it just includes what is needed. -pyuserdir.swg User visible directives (%pythonnondynamic, etc) -pymacros.swg Internal macros used for typemaps -pyfragments.swg Allow the user to overload the default fragments -pyopers.swg Python operations (+=, *=, etc) -pythonkw.swg Python keywords and special names -pyinit.swg Python Init method - -/* ----------------------------------------------------------------------------- - * The runtime part - * ----------------------------------------------------------------------------- */ - -pyruntime.swg Main runtime file definition -pyapi.swg SWIG/Python API declarations -pyrun.swg Python run-time code - -/* ----------------------------------------------------------------------------- - * Internal typemap specializations - * ----------------------------------------------------------------------------- */ - -pyswigtype.swg SWIGTYPE -pystrings.swg Char strings (char *) -pywstrings.swg Wchar Strings (wchar_t *) -pyprimtypes.swg Primitive types (shot,int,double,etc) -pycomplex.swg PyComplex and helper for C/C++ complex types -pydocs.swg Typemaps documentation - -/* ----------------------------------------------------------------------------- - * C++ STD + STL - * ----------------------------------------------------------------------------- */ - -pycontainer.swg python container iterators -std_common.i general common code for the STD/STL implementation -std_container.i general common code for the STD/STL containers - - -/*----------------------------------------------------------------------------- - * Backward compatibility and deprecated - * ----------------------------------------------------------------------------- */ - -std_vectora.i vector + allocator (allocators are now supported in STD/STL) -typemaps.i old in/out typemaps (doesn't need to be included) diff --git a/contrib/tools/swig/Lib/python/builtin.swg b/contrib/tools/swig/Lib/python/builtin.swg deleted file mode 100644 index 5cff6835f8e..00000000000 --- a/contrib/tools/swig/Lib/python/builtin.swg +++ /dev/null @@ -1,764 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -SWIGINTERN Py_hash_t -SwigPyObject_hash(PyObject *obj) { - SwigPyObject *sobj = (SwigPyObject *)obj; - void *ptr = sobj->ptr; -#if PY_VERSION_HEX < 0x03020000 - return (Py_hash_t)(Py_ssize_t)ptr; -#else - return (Py_hash_t)ptr; -#endif -} - -SWIGINTERN Py_hash_t -SWIG_PyNumber_AsPyHash(PyObject *obj) { - Py_hash_t result = -1; -#if PY_VERSION_HEX < 0x03020000 - if (PyInt_Check(obj)) - result = PyInt_AsLong(obj); - else if (PyLong_Check(obj)) - result = PyLong_AsLong(obj); -#else - if (PyNumber_Check(obj)) - result = PyNumber_AsSsize_t(obj, NULL); -#endif - else - PyErr_Format(PyExc_TypeError, "Wrong type for hash function"); - return PyErr_Occurred() ? -1 : result; -} - -SWIGINTERN int -SwigPyBuiltin_BadInit(PyObject *self, PyObject *SWIGUNUSEDPARM(args), PyObject *SWIGUNUSEDPARM(kwds)) { - PyErr_Format(PyExc_TypeError, "Cannot create new instances of type '%.300s'", self->ob_type->tp_name); - return -1; -} - -SWIGINTERN void -SwigPyBuiltin_BadDealloc(PyObject *obj) { - SwigPyObject *sobj = (SwigPyObject *)obj; - if (sobj->own) { - PyErr_Format(PyExc_TypeError, "Swig detected a memory leak in type '%.300s': no callable destructor found.", obj->ob_type->tp_name); - } -} - -typedef struct { - PyCFunction get; - PyCFunction set; -} SwigPyGetSet; - -SWIGINTERN PyObject * -SwigPyBuiltin_GetterClosure (PyObject *obj, void *closure) { - SwigPyGetSet *getset; - PyObject *tuple, *result; - if (!closure) - return SWIG_Py_Void(); - getset = (SwigPyGetSet *)closure; - if (!getset->get) - return SWIG_Py_Void(); - tuple = PyTuple_New(0); - assert(tuple); - result = (*getset->get)(obj, tuple); - Py_DECREF(tuple); - return result; -} - -SWIGINTERN PyObject * -SwigPyBuiltin_FunpackGetterClosure (PyObject *obj, void *closure) { - SwigPyGetSet *getset; - PyObject *result; - if (!closure) - return SWIG_Py_Void(); - getset = (SwigPyGetSet *)closure; - if (!getset->get) - return SWIG_Py_Void(); - result = (*getset->get)(obj, NULL); - return result; -} - -SWIGINTERN int -SwigPyBuiltin_SetterClosure (PyObject *obj, PyObject *val, void *closure) { - SwigPyGetSet *getset; - PyObject *tuple, *result; - if (!closure) { - PyErr_Format(PyExc_TypeError, "Missing getset closure"); - return -1; - } - getset = (SwigPyGetSet *)closure; - if (!getset->set) { - PyErr_Format(PyExc_TypeError, "Illegal member variable assignment in type '%.300s'", obj->ob_type->tp_name); - return -1; - } - tuple = PyTuple_New(1); - assert(tuple); - Py_INCREF(val); - PyTuple_SET_ITEM(tuple, 0, val); - result = (*getset->set)(obj, tuple); - Py_DECREF(tuple); - Py_XDECREF(result); - return result ? 0 : -1; -} - -SWIGINTERN int -SwigPyBuiltin_FunpackSetterClosure (PyObject *obj, PyObject *val, void *closure) { - SwigPyGetSet *getset; - PyObject *result; - if (!closure) { - PyErr_Format(PyExc_TypeError, "Missing getset closure"); - return -1; - } - getset = (SwigPyGetSet *)closure; - if (!getset->set) { - PyErr_Format(PyExc_TypeError, "Illegal member variable assignment in type '%.300s'", obj->ob_type->tp_name); - return -1; - } - result = (*getset->set)(obj, val); - Py_XDECREF(result); - return result ? 0 : -1; -} - -SWIGINTERN void -SwigPyStaticVar_dealloc(PyDescrObject *descr) { - PyObject_GC_UnTrack(descr); - Py_XDECREF(PyDescr_TYPE(descr)); - Py_XDECREF(PyDescr_NAME(descr)); - PyObject_GC_Del(descr); -} - -SWIGINTERN PyObject * -SwigPyStaticVar_repr(PyGetSetDescrObject *descr) { -#if PY_VERSION_HEX >= 0x03000000 - - return PyUnicode_FromFormat("<class attribute '%S' of type '%s'>", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name); -#else - return PyString_FromFormat("<class attribute '%s' of type '%s'>", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name); -#endif -} - -SWIGINTERN int -SwigPyStaticVar_traverse(PyObject *self, visitproc visit, void *arg) { - PyDescrObject *descr; - descr = (PyDescrObject *)self; - Py_VISIT((PyObject*) PyDescr_TYPE(descr)); - return 0; -} - -SWIGINTERN PyObject * -SwigPyStaticVar_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *SWIGUNUSEDPARM(type)) { - if (descr->d_getset->get != NULL) - return descr->d_getset->get(obj, descr->d_getset->closure); -#if PY_VERSION_HEX >= 0x03000000 - PyErr_Format(PyExc_AttributeError, "attribute '%.300S' of '%.100s' objects is not readable", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name); -#else - PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not readable", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name); -#endif - return NULL; -} - -SWIGINTERN int -SwigPyStaticVar_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) { - if (descr->d_getset->set != NULL) - return descr->d_getset->set(obj, value, descr->d_getset->closure); -#if PY_VERSION_HEX >= 0x03000000 - PyErr_Format(PyExc_AttributeError, "attribute '%.300S' of '%.100s' objects is not writable", PyDescr_NAME(descr), PyDescr_TYPE(descr)->tp_name); -#else - PyErr_Format(PyExc_AttributeError, "attribute '%.300s' of '%.100s' objects is not writable", PyString_AsString(PyDescr_NAME(descr)), PyDescr_TYPE(descr)->tp_name); -#endif - return -1; -} - -SWIGINTERN int -SwigPyObjectType_setattro(PyObject *typeobject, PyObject *name, PyObject *value) { - PyObject *attribute; - PyTypeObject *type; - descrsetfunc local_set; - - assert(PyType_Check(typeobject)); - type = (PyTypeObject *)typeobject; - attribute = _PyType_Lookup(type, name); - if (attribute != NULL) { - /* Implement descriptor functionality, if any */ - local_set = attribute->ob_type->tp_descr_set; - if (local_set != NULL) - return local_set(attribute, (PyObject *)type, value); -#if PY_VERSION_HEX >= 0x03000000 - PyErr_Format(PyExc_AttributeError, "cannot modify read-only attribute '%.50s.%.400S'", type->tp_name, name); -#else - PyErr_Format(PyExc_AttributeError, "cannot modify read-only attribute '%.50s.%.400s'", type->tp_name, PyString_AS_STRING(name)); -#endif - } else { -#if PY_VERSION_HEX >= 0x03000000 - PyErr_Format(PyExc_AttributeError, "type '%.50s' has no attribute '%.400S'", type->tp_name, name); -#else - PyErr_Format(PyExc_AttributeError, "type '%.50s' has no attribute '%.400s'", type->tp_name, PyString_AS_STRING(name)); -#endif - } - - return -1; -} - -SWIGINTERN PyTypeObject* -SwigPyStaticVar_Type(void) { - static PyTypeObject staticvar_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp = { -#if PY_VERSION_HEX >= 0x03000000 - PyVarObject_HEAD_INIT(&PyType_Type, 0) -#else - PyObject_HEAD_INIT(&PyType_Type) - 0, /* ob_size */ -#endif - "swig_static_var_getset_descriptor", /* tp_name */ - sizeof(PyGetSetDescrObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)SwigPyStaticVar_dealloc, /* tp_dealloc */ -#if PY_VERSION_HEX < 0x030800b4 - (printfunc)0, /* tp_print */ -#else - (Py_ssize_t)0, /* tp_vectorcall_offset */ -#endif - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - (reprfunc)SwigPyStaticVar_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_HAVE_CLASS, /* tp_flags */ - 0, /* tp_doc */ - SwigPyStaticVar_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - (descrgetfunc)SwigPyStaticVar_get, /* tp_descr_get */ - (descrsetfunc)SwigPyStaticVar_set, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ -#if PY_VERSION_HEX >= 0x03040000 - 0, /* tp_finalize */ -#endif -#if PY_VERSION_HEX >= 0x03080000 - 0, /* tp_vectorcall */ -#endif -#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000) - 0, /* tp_print */ -#endif -#ifdef COUNT_ALLOCS - 0, /* tp_allocs */ - 0, /* tp_frees */ - 0, /* tp_maxalloc */ - 0, /* tp_prev */ - 0 /* tp_next */ -#endif - }; - staticvar_type = tmp; - type_init = 1; - if (PyType_Ready(&staticvar_type) < 0) - return NULL; - } - return &staticvar_type; -} - -SWIGINTERN PyTypeObject* -SwigPyObjectType(void) { - static char swigpyobjecttype_doc[] = "Metaclass for SWIG wrapped types"; - static PyTypeObject swigpyobjecttype_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp = { -#if PY_VERSION_HEX >= 0x03000000 - PyVarObject_HEAD_INIT(&PyType_Type, 0) -#else - PyObject_HEAD_INIT(&PyType_Type) - 0, /* ob_size */ -#endif - "SwigPyObjectType", /* tp_name */ - PyType_Type.tp_basicsize, /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ -#if PY_VERSION_HEX < 0x030800b4 - (printfunc)0, /* tp_print */ -#else - (Py_ssize_t)0, /* tp_vectorcall_offset */ -#endif - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - SwigPyObjectType_setattro, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_CLASS, /* tp_flags */ - swigpyobjecttype_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ -#if PY_VERSION_HEX >= 0x03040000 - 0, /* tp_finalize */ -#endif -#if PY_VERSION_HEX >= 0x03080000 - 0, /* tp_vectorcall */ -#endif -#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000) - 0, /* tp_print */ -#endif -#ifdef COUNT_ALLOCS - 0, /* tp_allocs */ - 0, /* tp_frees */ - 0, /* tp_maxalloc */ - 0, /* tp_prev */ - 0 /* tp_next */ -#endif - }; - swigpyobjecttype_type = tmp; - type_init = 1; - swigpyobjecttype_type.tp_base = &PyType_Type; - if (PyType_Ready(&swigpyobjecttype_type) < 0) - return NULL; - } - return &swigpyobjecttype_type; -} - -SWIGINTERN PyGetSetDescrObject * -SwigPyStaticVar_new_getset(PyTypeObject *type, PyGetSetDef *getset) { - - PyGetSetDescrObject *descr; - descr = (PyGetSetDescrObject *)PyType_GenericAlloc(SwigPyStaticVar_Type(), 0); - assert(descr); - Py_XINCREF(type); - PyDescr_TYPE(descr) = type; - PyDescr_NAME(descr) = PyString_InternFromString(getset->name); - descr->d_getset = getset; - if (PyDescr_NAME(descr) == NULL) { - Py_DECREF(descr); - descr = NULL; - } - return descr; -} - -SWIGINTERN void -SwigPyBuiltin_InitBases (PyTypeObject *type, PyTypeObject **bases) { - Py_ssize_t base_count = 0; - PyTypeObject **b; - PyObject *tuple; - Py_ssize_t i; - - if (!bases[0]) { - bases[0] = SwigPyObject_type(); - bases[1] = NULL; - } - type->tp_base = bases[0]; - Py_INCREF((PyObject *)bases[0]); - for (b = bases; *b != NULL; ++b) - ++base_count; - tuple = PyTuple_New(base_count); - for (i = 0; i < base_count; ++i) { - Py_INCREF((PyObject *)bases[i]); - PyTuple_SET_ITEM(tuple, i, (PyObject *)bases[i]); - } - type->tp_bases = tuple; -} - -SWIGINTERN PyObject * -SwigPyBuiltin_ThisClosure (PyObject *self, void *SWIGUNUSEDPARM(closure)) { - PyObject *result; - result = (PyObject *)SWIG_Python_GetSwigThis(self); - Py_XINCREF(result); - return result; -} - -SWIGINTERN void -SwigPyBuiltin_SetMetaType (PyTypeObject *type, PyTypeObject *metatype) -{ -#if PY_VERSION_HEX >= 0x030900a4 - Py_SET_TYPE(type, metatype); -#else - Py_TYPE(type) = metatype; -#endif -} - - -/* Start of callback function macros for use in PyTypeObject */ - -typedef PyObject *(*SwigPyWrapperFunction)(PyObject *, PyObject *); - -#define SWIGPY_UNARYFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_unaryfunc_closure(PyObject *a) { \ - return SwigPyBuiltin_unaryfunc_closure(wrapper, a); \ -} -SWIGINTERN PyObject * -SwigPyBuiltin_unaryfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { - return wrapper(a, NULL); -} - -#define SWIGPY_DESTRUCTOR_CLOSURE(wrapper) \ -SWIGINTERN void \ -wrapper##_destructor_closure(PyObject *a) { \ - SwigPyBuiltin_destructor_closure(wrapper, #wrapper, a); \ -} -SWIGINTERN void -SwigPyBuiltin_destructor_closure(SwigPyWrapperFunction wrapper, const char *wrappername, PyObject *a) { - SwigPyObject *sobj; - sobj = (SwigPyObject *)a; - Py_XDECREF(sobj->dict); - if (sobj->own) { - PyObject *o; - PyObject *type = 0, *value = 0, *traceback = 0; - PyErr_Fetch(&type, &value, &traceback); - o = wrapper(a, NULL); - if (!o) { - PyObject *deallocname = PyString_FromString(wrappername); - PyErr_WriteUnraisable(deallocname); - Py_DECREF(deallocname); - } - PyErr_Restore(type, value, traceback); - Py_XDECREF(o); - } - if (PyType_IS_GC(a->ob_type)) { - PyObject_GC_Del(a); - } else { - PyObject_Del(a); - } -} - -#define SWIGPY_INQUIRY_CLOSURE(wrapper) \ -SWIGINTERN int \ -wrapper##_inquiry_closure(PyObject *a) { \ - return SwigPyBuiltin_inquiry_closure(wrapper, a); \ -} -SWIGINTERN int -SwigPyBuiltin_inquiry_closure(SwigPyWrapperFunction wrapper, PyObject *a) { - PyObject *pyresult; - int result; - pyresult = wrapper(a, NULL); - result = pyresult && PyObject_IsTrue(pyresult) ? 1 : 0; - Py_XDECREF(pyresult); - return result; -} - -#define SWIGPY_GETITERFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_getiterfunc_closure(PyObject *a) { \ - return SwigPyBuiltin_getiterfunc_closure(wrapper, a); \ -} -SWIGINTERN PyObject * -SwigPyBuiltin_getiterfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { - return wrapper(a, NULL); -} - -#define SWIGPY_BINARYFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_binaryfunc_closure(PyObject *a, PyObject *b) { \ - return SwigPyBuiltin_binaryfunc_closure(wrapper, a, b); \ -} -SWIGINTERN PyObject * -SwigPyBuiltin_binaryfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b) { - PyObject *tuple, *result; - tuple = PyTuple_New(1); - assert(tuple); - Py_INCREF(b); - PyTuple_SET_ITEM(tuple, 0, b); - result = wrapper(a, tuple); - Py_DECREF(tuple); - return result; -} - -typedef ternaryfunc ternarycallfunc; - -#define SWIGPY_TERNARYFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_ternaryfunc_closure(PyObject *a, PyObject *b, PyObject *c) { \ - return SwigPyBuiltin_ternaryfunc_closure(wrapper, a, b, c); \ -} -SWIGINTERN PyObject * -SwigPyBuiltin_ternaryfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b, PyObject *c) { - PyObject *tuple, *result; - tuple = PyTuple_New(2); - assert(tuple); - Py_INCREF(b); - PyTuple_SET_ITEM(tuple, 0, b); - Py_INCREF(c); - PyTuple_SET_ITEM(tuple, 1, c); - result = wrapper(a, tuple); - Py_DECREF(tuple); - return result; -} - -#define SWIGPY_TERNARYCALLFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_ternarycallfunc_closure(PyObject *a, PyObject *b, PyObject *c) { \ - return SwigPyBuiltin_ternarycallfunc_closure(wrapper, a, b, c); \ -} -SWIGINTERN PyObject * -SwigPyBuiltin_ternarycallfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b, PyObject *c) { - (void) c; - return wrapper(a, b); -} - -#define SWIGPY_LENFUNC_CLOSURE(wrapper) \ -SWIGINTERN Py_ssize_t \ -wrapper##_lenfunc_closure(PyObject *a) { \ - return SwigPyBuiltin_lenfunc_closure(wrapper, a); \ -} -SWIGINTERN Py_ssize_t -SwigPyBuiltin_lenfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { - PyObject *resultobj; - Py_ssize_t result; - resultobj = wrapper(a, NULL); - result = PyNumber_AsSsize_t(resultobj, NULL); - Py_DECREF(resultobj); - return result; -} - -#define SWIGPY_SSIZESSIZEARGFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_ssizessizeargfunc_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c) { \ - return SwigPyBuiltin_ssizessizeargfunc_closure(wrapper, a, b, c); \ -} -SWIGINTERN PyObject * -SwigPyBuiltin_ssizessizeargfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b, Py_ssize_t c) { - PyObject *tuple, *result; - tuple = PyTuple_New(2); - assert(tuple); - PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); - PyTuple_SET_ITEM(tuple, 1, _PyLong_FromSsize_t(c)); - result = wrapper(a, tuple); - Py_DECREF(tuple); - return result; -} - -#define SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE(wrapper) \ -SWIGINTERN int \ -wrapper##_ssizessizeobjargproc_closure(PyObject *a, Py_ssize_t b, Py_ssize_t c, PyObject *d) { \ - return SwigPyBuiltin_ssizessizeobjargproc_closure(wrapper, a, b, c, d); \ -} -SWIGINTERN int -SwigPyBuiltin_ssizessizeobjargproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b, Py_ssize_t c, PyObject *d) { - PyObject *tuple, *resultobj; - int result; - tuple = PyTuple_New(d ? 3 : 2); - assert(tuple); - PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); - PyTuple_SET_ITEM(tuple, 1, _PyLong_FromSsize_t(c)); - if (d) { - Py_INCREF(d); - PyTuple_SET_ITEM(tuple, 2, d); - } - resultobj = wrapper(a, tuple); - result = resultobj ? 0 : -1; - Py_DECREF(tuple); - Py_XDECREF(resultobj); - return result; -} - -#define SWIGPY_SSIZEARGFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_ssizeargfunc_closure(PyObject *a, Py_ssize_t b) { \ - return SwigPyBuiltin_funpack_ssizeargfunc_closure(wrapper, a, b); \ -} -SWIGINTERN PyObject * -SwigPyBuiltin_funpack_ssizeargfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b) { - PyObject *tuple, *result; - tuple = PyTuple_New(1); - assert(tuple); - PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); - result = wrapper(a, tuple); - Py_DECREF(tuple); - return result; -} - -#define SWIGPY_FUNPACK_SSIZEARGFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_ssizeargfunc_closure(PyObject *a, Py_ssize_t b) { \ - return SwigPyBuiltin_ssizeargfunc_closure(wrapper, a, b); \ -} -SWIGINTERN PyObject * -SwigPyBuiltin_ssizeargfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b) { - PyObject *arg, *result; - arg = _PyLong_FromSsize_t(b); - result = wrapper(a, arg); - Py_DECREF(arg); - return result; -} - -#define SWIGPY_SSIZEOBJARGPROC_CLOSURE(wrapper) \ -SWIGINTERN int \ -wrapper##_ssizeobjargproc_closure(PyObject *a, Py_ssize_t b, PyObject *c) { \ - return SwigPyBuiltin_ssizeobjargproc_closure(wrapper, a, b, c); \ -} -SWIGINTERN int -SwigPyBuiltin_ssizeobjargproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, Py_ssize_t b, PyObject *c) { - PyObject *tuple, *resultobj; - int result; - tuple = PyTuple_New(2); - assert(tuple); - PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b)); - Py_INCREF(c); - PyTuple_SET_ITEM(tuple, 1, c); - resultobj = wrapper(a, tuple); - result = resultobj ? 0 : -1; - Py_XDECREF(resultobj); - Py_DECREF(tuple); - return result; -} - -#define SWIGPY_OBJOBJPROC_CLOSURE(wrapper) \ -SWIGINTERN int \ -wrapper##_objobjproc_closure(PyObject *a, PyObject *b) { \ - return SwigPyBuiltin_objobjproc_closure(wrapper, a, b); \ -} -SWIGINTERN int -SwigPyBuiltin_objobjproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b) { - int result; - PyObject *pyresult; - PyObject *tuple; - tuple = PyTuple_New(1); - assert(tuple); - Py_INCREF(b); - PyTuple_SET_ITEM(tuple, 0, b); - pyresult = wrapper(a, tuple); - result = pyresult ? (PyObject_IsTrue(pyresult) ? 1 : 0) : -1; - Py_XDECREF(pyresult); - Py_DECREF(tuple); - return result; -} - -#define SWIGPY_FUNPACK_OBJOBJPROC_CLOSURE(wrapper) \ -SWIGINTERN int \ -wrapper##_objobjproc_closure(PyObject *a, PyObject *b) { \ - return SwigPyBuiltin_funpack_objobjproc_closure(wrapper, a, b); \ -} -SWIGINTERN int -SwigPyBuiltin_funpack_objobjproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b) { - int result; - PyObject *pyresult; - pyresult = wrapper(a, b); - result = pyresult ? (PyObject_IsTrue(pyresult) ? 1 : 0) : -1; - Py_XDECREF(pyresult); - return result; -} - -#define SWIGPY_OBJOBJARGPROC_CLOSURE(wrapper) \ -SWIGINTERN int \ -wrapper##_objobjargproc_closure(PyObject *a, PyObject *b, PyObject *c) { \ - return SwigPyBuiltin_objobjargproc_closure(wrapper, a, b, c); \ -} -SWIGINTERN int -SwigPyBuiltin_objobjargproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b, PyObject *c) { - PyObject *tuple, *resultobj; - int result; - tuple = PyTuple_New(c ? 2 : 1); - assert(tuple); - Py_INCREF(b); - PyTuple_SET_ITEM(tuple, 0, b); - if (c) { - Py_INCREF(c); - PyTuple_SET_ITEM(tuple, 1, c); - } - resultobj = wrapper(a, tuple); - result = resultobj ? 0 : -1; - Py_XDECREF(resultobj); - Py_DECREF(tuple); - return result; -} - -#define SWIGPY_REPRFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_reprfunc_closure(PyObject *a) { \ - return SwigPyBuiltin_reprfunc_closure(wrapper, a); \ -} -SWIGINTERN PyObject * -SwigPyBuiltin_reprfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { - return wrapper(a, NULL); -} - -#define SWIGPY_HASHFUNC_CLOSURE(wrapper) \ -SWIGINTERN Py_hash_t \ -wrapper##_hashfunc_closure(PyObject *a) { \ - return SwigPyBuiltin_hashfunc_closure(wrapper, a); \ -} -SWIGINTERN Py_hash_t -SwigPyBuiltin_hashfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { - PyObject *pyresult; - Py_hash_t result; - pyresult = wrapper(a, NULL); - if (!pyresult) - return -1; - result = SWIG_PyNumber_AsPyHash(pyresult); - Py_DECREF(pyresult); - return result; -} - -#define SWIGPY_ITERNEXTFUNC_CLOSURE(wrapper) \ -SWIGINTERN PyObject * \ -wrapper##_iternextfunc_closure(PyObject *a) { \ - return SwigPyBuiltin_iternextfunc_closure(wrapper, a);\ -} -SWIGINTERN PyObject * -SwigPyBuiltin_iternextfunc_closure(SwigPyWrapperFunction wrapper, PyObject *a) { - return wrapper(a, NULL); -} - -/* End of callback function macros for use in PyTypeObject */ - -#ifdef __cplusplus -} -#endif - diff --git a/contrib/tools/swig/Lib/python/pyapi.swg b/contrib/tools/swig/Lib/python/pyapi.swg deleted file mode 100644 index 19e6979b56d..00000000000 --- a/contrib/tools/swig/Lib/python/pyapi.swg +++ /dev/null @@ -1,30 +0,0 @@ -/* ----------------------------------------------------------------------------- - * Python API portion that goes into the runtime - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* ----------------------------------------------------------------------------- - * Constant declarations - * ----------------------------------------------------------------------------- */ - -/* Constant Types */ -#define SWIG_PY_POINTER 4 -#define SWIG_PY_BINARY 5 - -/* Constant information structure */ -typedef struct swig_const_info { - int type; - const char *name; - long lvalue; - double dvalue; - void *pvalue; - swig_type_info **ptype; -} swig_const_info; - -#ifdef __cplusplus -} -#endif - diff --git a/contrib/tools/swig/Lib/python/pybackward.swg b/contrib/tools/swig/Lib/python/pybackward.swg deleted file mode 100644 index 8305fc78b7c..00000000000 --- a/contrib/tools/swig/Lib/python/pybackward.swg +++ /dev/null @@ -1,45 +0,0 @@ -/* - adding backward compatibility macros -*/ - -#define SWIG_arg(x...) %arg(x) -#define SWIG_Mangle(x...) %mangle(x) - -#define SWIG_As_frag(Type...) %fragment_name(As, Type) -#define SWIG_As_name(Type...) %symbol_name(As, Type) -#define SWIG_As(Type...) SWIG_As_name(Type) SWIG_AS_CALL_ARGS - -#define SWIG_Check_frag(Type...) %fragment_name(Check, Type) -#define SWIG_Check_name(Type...) %symbol_name(Check, Type) -#define SWIG_Check(Type...) SWIG_Check_name(Type) SWIG_AS_CALL_ARGS - -%define %ascheck_methods(Code, Type...) -%fragment(SWIG_As_frag(Type),"header", fragment=SWIG_AsVal_frag(Type)) { -SWIGINTERNINLINE Type -SWIG_As(Type)(PyObject* obj) -{ - Type v; - int res = SWIG_AsVal(Type)(obj, &v); - if (!SWIG_IsOK(res)) { - /* - this is needed to make valgrind/purify happier. - */ - memset((void*)&v, 0, sizeof(Type)); - SWIG_Error(res, ""); - } - return v; -} -} - -%fragment(SWIG_Check_frag(Type),"header",fragment=SWIG_AsVal_frag(Type)) { -SWIGINTERNINLINE int -SWIG_Check(Type)(PyObject* obj) -{ - int res = SWIG_AsVal(Type)(obj, (Type*)0); - return SWIG_IsOK(res); -} -} -%enddef - -%apply_checkctypes(%ascheck_methods) - diff --git a/contrib/tools/swig/Lib/python/pyclasses.swg b/contrib/tools/swig/Lib/python/pyclasses.swg deleted file mode 100644 index 31ebdd2a151..00000000000 --- a/contrib/tools/swig/Lib/python/pyclasses.swg +++ /dev/null @@ -1,157 +0,0 @@ -#ifdef __cplusplus - -/* - SwigPtr_PyObject is used as a replacement of PyObject *, where - the INCREF/DECREF are applied as needed. - - You can use SwigPtr_PyObject in a container, such as - - std::vector<SwigPtr_PyObject>; - - or as a member variable: - - struct A { - SwigPtr_PyObject obj; - A(PyObject *o) : _obj(o) { - } - }; - - or as a input/output value - - SwigPtr_PyObject func(SwigPtr_PyObject obj) { - SwigPtr_PyObject out = PyString_FromFormat("hello %s", PyObject_AsString(obj)); - Py_DECREF(out); - return out; - } - - just remember to pair the object creation with the proper DECREF, - the same as with plain PyObject *ptr, since SwigPtr_PyObject always add - one reference at construction. - - SwigPtr_PyObject is 'visible' at the wrapped side, so you can do: - - - %template(pyvector) std::vector<swig::SwigPtr_PyObject>; - - and all the proper typemaps will be used. - -*/ - -namespace swig { - %ignore SwigPtr_PyObject; - struct SwigPtr_PyObject {}; - %apply PyObject * {SwigPtr_PyObject}; - %apply PyObject * const& {SwigPtr_PyObject const&}; - - %typemap(typecheck,precedence=SWIG_TYPECHECK_SWIGOBJECT,noblock=1) SwigPtr_PyObject const& "$1 = ($input != 0);" - - - /* For output */ - %typemap(out,noblock=1) SwigPtr_PyObject { - $result = (PyObject *)$1; - Py_INCREF($result); - } - - %typemap(out,noblock=1) SwigPtr_PyObject const & { - $result = (PyObject *)*$1; - Py_INCREF($result); - } - -} - -%{ -namespace swig { - class SwigPtr_PyObject { - protected: - PyObject *_obj; - - public: - SwigPtr_PyObject() :_obj(0) - { - } - - SwigPtr_PyObject(const SwigPtr_PyObject& item) : _obj(item._obj) - { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - Py_XINCREF(_obj); - SWIG_PYTHON_THREAD_END_BLOCK; - } - - SwigPtr_PyObject(PyObject *obj, bool initial_ref = true) :_obj(obj) - { - if (initial_ref) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - Py_XINCREF(_obj); - SWIG_PYTHON_THREAD_END_BLOCK; - } - } - - SwigPtr_PyObject & operator=(const SwigPtr_PyObject& item) - { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - Py_XINCREF(item._obj); - Py_XDECREF(_obj); - _obj = item._obj; - SWIG_PYTHON_THREAD_END_BLOCK; - return *this; - } - - ~SwigPtr_PyObject() - { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - Py_XDECREF(_obj); - SWIG_PYTHON_THREAD_END_BLOCK; - } - - operator PyObject *() const - { - return _obj; - } - - PyObject *operator->() const - { - return _obj; - } - }; -} -%} - -/* - SwigVar_PyObject is used to manage 'in the scope' PyObject * variables, - as in - - int func () { - SwigVar_PyObject obj = PyString_FromString("hello"); - } - - ie, 'obj' is created and destructed in the same scope from - a python object that carries at least one reference value. - - SwigVar_PyObject just take care of applying the proper Py_DECREF. - - Hence, this class is purely internal and not visible at the wrapped side. - */ -namespace swig { - %ignore SwigVar_PyObject; - struct SwigVar_PyObject {}; - %apply PyObject * {SwigVar_PyObject}; - %apply PyObject * const& {SwigVar_PyObject const&}; -} - -%{ -namespace swig { - struct SwigVar_PyObject : SwigPtr_PyObject { - SwigVar_PyObject(PyObject* obj = 0) : SwigPtr_PyObject(obj, false) { } - - SwigVar_PyObject & operator = (PyObject* obj) - { - Py_XDECREF(_obj); - _obj = obj; - return *this; - } - }; -} -%} - - -#endif diff --git a/contrib/tools/swig/Lib/python/pydocs.swg b/contrib/tools/swig/Lib/python/pydocs.swg deleted file mode 100644 index 5a25423d4ca..00000000000 --- a/contrib/tools/swig/Lib/python/pydocs.swg +++ /dev/null @@ -1,45 +0,0 @@ - -// Documentation for use with the autodoc feature. - -#ifdef SWIG_DOC_DOXYGEN_STYLE -%typemap(doc) SWIGTYPE "@param $1_name $1_type" -%typemap(doc) SWIGTYPE * "@param $1_name $1_type" -%typemap(doc) const SWIGTYPE & "@param $1_name $1_type" -%typemap(doc) const SWIGTYPE && "@param $1_name $1_type" -%typemap(doc) enum SWIGTYPE "@param $1_name enum $1_type" - -%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "@param $1_name $1_type (input/output)" -%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "@param $1_name $1_type (input)" -%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "@param $1_name $1_type (output)" -#else -%typemap(doc) SWIGTYPE "$1_name: $1_type" -%typemap(doc) SWIGTYPE * "$1_name: $1_type" -%typemap(doc) const SWIGTYPE & "$1_name: $1_type" -%typemap(doc) const SWIGTYPE && "$1_name: $1_type" -%typemap(doc) enum SWIGTYPE "$1_name: enum $1_type" - -%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "$1_name: $1_type (input/output)" -%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "$1_name: $1_type (input)" -%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "$1_name: $1_type (output)" -#endif - - -// Types to use in Python documentation for the parameters of the given C++ type. -%typemap(doctype) bool "boolean" - -%define int_doctype_for_cppint_type(cppint_type) - %typemap(doctype) cppint_type, unsigned cppint_type "int" -%enddef -%formacro(int_doctype_for_cppint_type, short, int, long, long long) - -%typemap(doctype) size_t "int" - -%typemap(doctype) enum SWIGTYPE "int" - -%typemap(doctype) float, double, long double "float" - -%typemap(doctype) char*, std::string "string" - -%typemap(doctype) SWIGTYPE "$1_basetype" -%typemap(doctype) SWIGTYPE * "$typemap(doctype, $*1_ltype)" -%typemap(doctype) SWIGTYPE & "$typemap(doctype, $*1_ltype)" diff --git a/contrib/tools/swig/Lib/python/pyerrors.swg b/contrib/tools/swig/Lib/python/pyerrors.swg deleted file mode 100644 index 10b694cde61..00000000000 --- a/contrib/tools/swig/Lib/python/pyerrors.swg +++ /dev/null @@ -1,107 +0,0 @@ -/* ----------------------------------------------------------------------------- - * error manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIME PyObject* -SWIG_Python_ErrorType(int code) { - PyObject* type = 0; - switch(code) { - case SWIG_MemoryError: - type = PyExc_MemoryError; - break; - case SWIG_IOError: - type = PyExc_IOError; - break; - case SWIG_RuntimeError: - type = PyExc_RuntimeError; - break; - case SWIG_IndexError: - type = PyExc_IndexError; - break; - case SWIG_TypeError: - type = PyExc_TypeError; - break; - case SWIG_DivisionByZero: - type = PyExc_ZeroDivisionError; - break; - case SWIG_OverflowError: - type = PyExc_OverflowError; - break; - case SWIG_SyntaxError: - type = PyExc_SyntaxError; - break; - case SWIG_ValueError: - type = PyExc_ValueError; - break; - case SWIG_SystemError: - type = PyExc_SystemError; - break; - case SWIG_AttributeError: - type = PyExc_AttributeError; - break; - default: - type = PyExc_RuntimeError; - } - return type; -} - - -SWIGRUNTIME void -SWIG_Python_AddErrorMsg(const char* mesg) -{ - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - - if (PyErr_Occurred()) - PyErr_Fetch(&type, &value, &traceback); - if (value) { - PyObject *old_str = PyObject_Str(value); - const char *tmp = SWIG_Python_str_AsChar(old_str); - PyErr_Clear(); - Py_XINCREF(type); - if (tmp) - PyErr_Format(type, "%s %s", tmp, mesg); - else - PyErr_Format(type, "%s", mesg); - Py_DECREF(old_str); - Py_DECREF(value); - } else { - PyErr_SetString(PyExc_RuntimeError, mesg); - } -} - -SWIGRUNTIME int -SWIG_Python_TypeErrorOccurred(PyObject *obj) -{ - PyObject *error; - if (obj) - return 0; - error = PyErr_Occurred(); - return error && PyErr_GivenExceptionMatches(error, PyExc_TypeError); -} - -SWIGRUNTIME void -SWIG_Python_RaiseOrModifyTypeError(const char *message) -{ - if (SWIG_Python_TypeErrorOccurred(NULL)) { - /* Use existing TypeError to preserve stacktrace and enhance with given message */ - PyObject *newvalue; - PyObject *type = NULL, *value = NULL, *traceback = NULL; - PyErr_Fetch(&type, &value, &traceback); -#if PY_VERSION_HEX >= 0x03000000 - newvalue = PyUnicode_FromFormat("%S\nAdditional information:\n%s", value, message); -#else - newvalue = PyString_FromFormat("%s\nAdditional information:\n%s", PyString_AsString(value), message); -#endif - if (newvalue) { - Py_XDECREF(value); - PyErr_Restore(type, newvalue, traceback); - } else { - PyErr_Restore(type, value, traceback); - } - } else { - /* Raise TypeError using given message */ - PyErr_SetString(PyExc_TypeError, message); - } -} diff --git a/contrib/tools/swig/Lib/python/pyfragments.swg b/contrib/tools/swig/Lib/python/pyfragments.swg deleted file mode 100644 index 535a45bdf2d..00000000000 --- a/contrib/tools/swig/Lib/python/pyfragments.swg +++ /dev/null @@ -1,23 +0,0 @@ -/* - - Create a file with this name, 'pyfragments.swg', in your working - directory and add all the %fragments you want to take precedence - over the default ones defined by swig. - - For example, if you add: - - %fragment(SWIG_AsVal_frag(int),"header") { - SWIGINTERNINLINE int - SWIG_AsVal(int)(PyObject *obj, int *val) - { - <your code here>; - } - } - - this will replace the code used to retrieve an integer value for all - the typemaps that need it, including: - - int, std::vector<int>, std::list<std::pair<int,int> >, etc. - - -*/ diff --git a/contrib/tools/swig/Lib/python/pyhead.swg b/contrib/tools/swig/Lib/python/pyhead.swg deleted file mode 100644 index 6f37160bb23..00000000000 --- a/contrib/tools/swig/Lib/python/pyhead.swg +++ /dev/null @@ -1,75 +0,0 @@ -/* Compatibility macros for Python 3 */ -#if PY_VERSION_HEX >= 0x03000000 - -#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type) -#define PyInt_Check(x) PyLong_Check(x) -#define PyInt_AsLong(x) PyLong_AsLong(x) -#define PyInt_FromLong(x) PyLong_FromLong(x) -#define PyInt_FromSize_t(x) PyLong_FromSize_t(x) -#define PyString_Check(name) PyBytes_Check(name) -#define PyString_FromString(x) PyUnicode_FromString(x) -#define PyString_Format(fmt, args) PyUnicode_Format(fmt, args) -#define PyString_AsString(str) PyBytes_AsString(str) -#define PyString_Size(str) PyBytes_Size(str) -#define PyString_InternFromString(key) PyUnicode_InternFromString(key) -#define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE -#define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x) - -#endif - -#ifndef Py_TYPE -# define Py_TYPE(op) ((op)->ob_type) -#endif - -/* SWIG APIs for compatibility of both Python 2 & 3 */ - -#if PY_VERSION_HEX >= 0x03000000 -# define SWIG_Python_str_FromFormat PyUnicode_FromFormat -#else -# define SWIG_Python_str_FromFormat PyString_FromFormat -#endif - - -SWIGINTERN char* -SWIG_Python_str_AsChar(PyObject *str) -{ -#if PY_VERSION_HEX >= 0x03030000 - return (char *)PyUnicode_AsUTF8(str); -#else - return PyString_AsString(str); -#endif -} - -/* Was useful for Python 3.0.x-3.2.x - now provided only for compatibility - * with any uses in user interface files. */ -#define SWIG_Python_str_DelForPy3(x) - - -SWIGINTERN PyObject* -SWIG_Python_str_FromChar(const char *c) -{ -#if PY_VERSION_HEX >= 0x03000000 - return PyUnicode_FromString(c); -#else - return PyString_FromString(c); -#endif -} - -#ifndef PyObject_DEL -# define PyObject_DEL PyObject_Del -#endif - -/* SWIGPY_USE_CAPSULE is no longer used within SWIG itself, but some user interface files check for it. */ -# define SWIGPY_USE_CAPSULE -#ifdef SWIGPYTHON_BUILTIN -# define SWIGPY_CAPSULE_ATTR_NAME "type_pointer_capsule_builtin" SWIG_TYPE_TABLE_NAME -#else -# define SWIGPY_CAPSULE_ATTR_NAME "type_pointer_capsule" SWIG_TYPE_TABLE_NAME -#endif -# define SWIGPY_CAPSULE_NAME ("swig_runtime_data" SWIG_RUNTIME_VERSION "." SWIGPY_CAPSULE_ATTR_NAME) - -#if PY_VERSION_HEX < 0x03020000 -#define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type) -#define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name) -#define Py_hash_t long -#endif diff --git a/contrib/tools/swig/Lib/python/pyinit.swg b/contrib/tools/swig/Lib/python/pyinit.swg deleted file mode 100644 index 6833b455aa9..00000000000 --- a/contrib/tools/swig/Lib/python/pyinit.swg +++ /dev/null @@ -1,325 +0,0 @@ -/* ------------------------------------------------------------ - * The start of the Python initialization function - * ------------------------------------------------------------ */ - -%insert(init) "swiginit.swg" - -#if defined(SWIGPYTHON_BUILTIN) -%fragment("<stddef.h>"); // For offsetof -#endif - -#if defined SWIGPYTHON_FASTPROXY && !defined SWIGPYTHON_BUILTIN - -%insert(runtime) %{ -#ifdef __cplusplus -extern "C" { -#endif - -/* Method creation and docstring support functions */ - -SWIGINTERN PyMethodDef *SWIG_PythonGetProxyDoc(const char *name); -SWIGINTERN PyObject *SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func); -SWIGINTERN PyObject *SWIG_PyStaticMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func); - -#ifdef __cplusplus -} -#endif -%} - -#endif - -%init %{ - -#ifdef __cplusplus -extern "C" { -#endif - -/* ----------------------------------------------------------------------------- - * constants/methods manipulation - * ----------------------------------------------------------------------------- */ - -/* Install Constants */ -SWIGINTERN void -SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { - PyObject *obj = 0; - size_t i; - for (i = 0; constants[i].type; ++i) { - switch(constants[i].type) { - case SWIG_PY_POINTER: - obj = SWIG_InternalNewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); - break; - case SWIG_PY_BINARY: - obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); - break; - default: - obj = 0; - break; - } - if (obj) { - PyDict_SetItemString(d, constants[i].name, obj); - Py_DECREF(obj); - } - } -} - -/* ----------------------------------------------------------------------------- - * Patch %callback methods' docstrings to hold the callback ptrs - * -----------------------------------------------------------------------------*/ - -SWIGINTERN void -SWIG_Python_FixMethods(PyMethodDef *methods, const swig_const_info *const_table, swig_type_info **types, swig_type_info **types_initial) { - size_t i; - for (i = 0; methods[i].ml_name; ++i) { - const char *c = methods[i].ml_doc; - if (!c) continue; - c = strstr(c, "swig_ptr: "); - if (c) { - int j; - const swig_const_info *ci = 0; - const char *name = c + 10; - for (j = 0; const_table[j].type; ++j) { - if (strncmp(const_table[j].name, name, - strlen(const_table[j].name)) == 0) { - ci = &(const_table[j]); - break; - } - } - if (ci) { - void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; - if (ptr) { - size_t shift = (ci->ptype) - types; - swig_type_info *ty = types_initial[shift]; - size_t ldoc = (c - methods[i].ml_doc); - size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; - char *ndoc = (char*)malloc(ldoc + lptr + 10); - if (ndoc) { - char *buff = ndoc; - memcpy(buff, methods[i].ml_doc, ldoc); - buff += ldoc; - memcpy(buff, "swig_ptr: ", 10); - buff += 10; - SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); - methods[i].ml_doc = ndoc; - } - } - } - } - } -} - -#ifdef __cplusplus -} -#endif - -%} - -#if defined SWIGPYTHON_FASTPROXY && !defined SWIGPYTHON_BUILTIN - -%init %{ - -#ifdef __cplusplus -extern "C" { -#endif - -/* ----------------------------------------------------------------------------- - * Method creation and docstring support functions - * ----------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------------- - * Function to find the method definition with the correct docstring for the - * proxy module as opposed to the low-level API - * ----------------------------------------------------------------------------- */ - -SWIGINTERN PyMethodDef *SWIG_PythonGetProxyDoc(const char *name) { - /* Find the function in the modified method table */ - size_t offset = 0; - int found = 0; - while (SwigMethods_proxydocs[offset].ml_meth != NULL) { - if (strcmp(SwigMethods_proxydocs[offset].ml_name, name) == 0) { - found = 1; - break; - } - offset++; - } - /* Use the copy with the modified docstring if available */ - return found ? &SwigMethods_proxydocs[offset] : NULL; -} - -/* ----------------------------------------------------------------------------- - * Wrapper of PyInstanceMethod_New() used in Python 3 - * It is exported to the generated module, used for -fastproxy - * ----------------------------------------------------------------------------- */ - -SWIGINTERN PyObject *SWIG_PyInstanceMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func) { - if (PyCFunction_Check(func)) { - PyCFunctionObject *funcobj = (PyCFunctionObject *)func; - PyMethodDef *ml = SWIG_PythonGetProxyDoc(funcobj->m_ml->ml_name); - if (ml) - func = PyCFunction_NewEx(ml, funcobj->m_self, funcobj->m_module); - } -#if PY_VERSION_HEX >= 0x03000000 - return PyInstanceMethod_New(func); -#else - return PyMethod_New(func, NULL, NULL); -#endif -} - -/* ----------------------------------------------------------------------------- - * Wrapper of PyStaticMethod_New() - * It is exported to the generated module, used for -fastproxy - * ----------------------------------------------------------------------------- */ - -SWIGINTERN PyObject *SWIG_PyStaticMethod_New(PyObject *SWIGUNUSEDPARM(self), PyObject *func) { - if (PyCFunction_Check(func)) { - PyCFunctionObject *funcobj = (PyCFunctionObject *)func; - PyMethodDef *ml = SWIG_PythonGetProxyDoc(funcobj->m_ml->ml_name); - if (ml) - func = PyCFunction_NewEx(ml, funcobj->m_self, funcobj->m_module); - } - return PyStaticMethod_New(func); -} - -#ifdef __cplusplus -} -#endif - -%} - -#endif - -%init %{ - -/* -----------------------------------------------------------------------------* - * Partial Init method - * -----------------------------------------------------------------------------*/ - -#ifdef __cplusplus -extern "C" -#endif - -SWIGEXPORT -#if PY_VERSION_HEX >= 0x03000000 - PyObject* -#else - void -#endif -SWIG_init(void) { - PyObject *m, *d, *md, *globals; - -#if PY_VERSION_HEX >= 0x03000000 - static struct PyModuleDef SWIG_module = { - PyModuleDef_HEAD_INIT, - SWIG_name, - NULL, - -1, - SwigMethods, - NULL, - NULL, - NULL, - NULL - }; -#endif - -#if defined(SWIGPYTHON_BUILTIN) - static SwigPyClientData SwigPyObject_clientdata = {0, 0, 0, 0, 0, 0, 0}; - static PyGetSetDef this_getset_def = { - (char *)"this", &SwigPyBuiltin_ThisClosure, NULL, NULL, NULL - }; - static SwigPyGetSet thisown_getset_closure = { - SwigPyObject_own, - SwigPyObject_own - }; - static PyGetSetDef thisown_getset_def = { - (char *)"thisown", SwigPyBuiltin_GetterClosure, SwigPyBuiltin_SetterClosure, NULL, &thisown_getset_closure - }; - PyTypeObject *builtin_pytype; - int builtin_base_count; - swig_type_info *builtin_basetype; - PyObject *tuple; - PyGetSetDescrObject *static_getset; - PyTypeObject *metatype; - PyTypeObject *swigpyobject; - SwigPyClientData *cd; - PyObject *public_interface, *public_symbol; - PyObject *this_descr; - PyObject *thisown_descr; - PyObject *self = 0; - int i; - - (void)builtin_pytype; - (void)builtin_base_count; - (void)builtin_basetype; - (void)tuple; - (void)static_getset; - (void)self; - - /* Metaclass is used to implement static member variables */ - metatype = SwigPyObjectType(); - assert(metatype); -#endif - - (void)globals; - - /* Create singletons now to avoid potential deadlocks with multi-threaded usage after module initialization */ - SWIG_This(); - SWIG_Python_TypeCache(); - SwigPyPacked_type(); -#ifndef SWIGPYTHON_BUILTIN - SwigPyObject_type(); -#endif - - /* Fix SwigMethods to carry the callback ptrs when needed */ - SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); - -#if PY_VERSION_HEX >= 0x03000000 - m = PyModule_Create(&SWIG_module); -#else - m = Py_InitModule(SWIG_name, SwigMethods); -#endif - - md = d = PyModule_GetDict(m); - (void)md; - - SWIG_InitializeModule(0); - -#ifdef SWIGPYTHON_BUILTIN - swigpyobject = SwigPyObject_TypeOnce(); - - SwigPyObject_stype = SWIG_MangledTypeQuery("_p_SwigPyObject"); - assert(SwigPyObject_stype); - cd = (SwigPyClientData*) SwigPyObject_stype->clientdata; - if (!cd) { - SwigPyObject_stype->clientdata = &SwigPyObject_clientdata; - SwigPyObject_clientdata.pytype = swigpyobject; - } else if (swigpyobject->tp_basicsize != cd->pytype->tp_basicsize) { - PyErr_SetString(PyExc_RuntimeError, "Import error: attempted to load two incompatible swig-generated modules."); -# if PY_VERSION_HEX >= 0x03000000 - return NULL; -# else - return; -# endif - } - - /* All objects have a 'this' attribute */ - this_descr = PyDescr_NewGetSet(SwigPyObject_type(), &this_getset_def); - (void)this_descr; - - /* All objects have a 'thisown' attribute */ - thisown_descr = PyDescr_NewGetSet(SwigPyObject_type(), &thisown_getset_def); - (void)thisown_descr; - - public_interface = PyList_New(0); - public_symbol = 0; - (void)public_symbol; - - PyDict_SetItemString(md, "__all__", public_interface); - Py_DECREF(public_interface); - for (i = 0; SwigMethods[i].ml_name != NULL; ++i) - SwigPyBuiltin_AddPublicSymbol(public_interface, SwigMethods[i].ml_name); - for (i = 0; swig_const_table[i].name != 0; ++i) - SwigPyBuiltin_AddPublicSymbol(public_interface, swig_const_table[i].name); -#endif - - SWIG_InstallConstants(d,swig_const_table); -%} - diff --git a/contrib/tools/swig/Lib/python/pymacros.swg b/contrib/tools/swig/Lib/python/pymacros.swg deleted file mode 100644 index ab7bace5bac..00000000000 --- a/contrib/tools/swig/Lib/python/pymacros.swg +++ /dev/null @@ -1,4 +0,0 @@ -%include <typemaps/swigmacros.swg> - - - diff --git a/contrib/tools/swig/Lib/python/pyopers.swg b/contrib/tools/swig/Lib/python/pyopers.swg deleted file mode 100644 index fd2fcc58120..00000000000 --- a/contrib/tools/swig/Lib/python/pyopers.swg +++ /dev/null @@ -1,264 +0,0 @@ -/* ------------------------------------------------------------ - * Overloaded operator support - - The directives in this file apply whether or not you use the - -builtin option to SWIG, but operator overloads are particularly - attractive when using -builtin, because they are much faster - than named methods. - - If you're using the -builtin option to SWIG, and you want to define - python operator overloads beyond the defaults defined in this file, - here's what you need to know: - - There are two ways to define a python slot function: dispatch to a - statically defined function; or dispatch to a method defined on the - operand. - - To dispatch to a statically defined function, use %feature("python:<slot>"), - where <slot> is the name of a field in a PyTypeObject, PyNumberMethods, - PyMappingMethods, PySequenceMethods, or PyBufferProcs. For example: - - %feature("python:tp_hash") MyClass "myHashFunc"; - - class MyClass { - public: - ... - }; - - %{ - // Note: Py_hash_t was introduced in Python 3.2 - static Py_hash_t myHashFunc(PyObject *pyobj) { - MyClass *cobj; - // Convert pyobj to cobj - return (cobj->field1 * (cobj->field2 << 7)); - } - %} - - NOTE: It is the responsibility of the programmer (that's you) to ensure - that a statically defined slot function has the correct signature. - - If, instead, you want to dispatch to an instance method, you can - use %feature("python:slot"). For example: - - %feature("python:slot", "tp_hash", functype="hashfunc") MyClass::myHashFunc; - - class MyClass { - public: - Py_hash_t myHashFunc () const; - ... - }; - - NOTE: Some python slots use a method signature which does not - match the signature of SWIG-wrapped methods. For those slots, - SWIG will automatically generate a "closure" function to re-marshall - the arguments before dispatching to the wrapped method. Setting - the "functype" attribute of the feature enables SWIG to generate - a correct closure function. - - -------------------------------------------------------------- - - The tp_richcompare slot is a special case: SWIG automatically generates - a rich compare function for all wrapped types. If a type defines C++ - operator overloads for comparison (operator==, operator<, etc.), they - will be called from the generated rich compare function. If you - want to explicitly choose a method to handle a certain comparison - operation, you may use a different feature, %feature("python:compare") - like this: - - %feature("python:compare", "Py_LT") MyClass::lessThan; - - class MyClass { - public: - bool lessThan(const MyClass& other) const; - ... - }; - - ... where "Py_LT" is one of the rich comparison opcodes defined in the - python header file object.h. - - If there's no method defined to handle a particular comparison operation, - the default behavior is to compare pointer values of the wrapped - C++ objects. - - -------------------------------------------------------------- - - - For more information about python slots, including their names and - signatures, you may refer to the python documentation : - - http://docs.python.org/c-api/typeobj.html - - * ------------------------------------------------------------ */ - - -#ifdef __cplusplus - -#if defined(SWIGPYTHON_BUILTIN) -#define %pybinoperator(pyname,oper,functp,slt) %rename(pyname) oper; %pythonmaybecall oper; %feature("python:slot", #slt, functype=#functp) oper; %feature("python:slot", #slt, functype=#functp) pyname; -#define %pycompare(pyname,oper,comptype) %rename(pyname) oper; %pythonmaybecall oper; %feature("python:compare", #comptype) oper; %feature("python:compare", #comptype) pyname; -#else -#define %pybinoperator(pyname,oper,functp,slt) %rename(pyname) oper; %pythonmaybecall oper -#define %pycompare(pyname,oper,comptype) %pybinoperator(pyname,oper,,comptype) -#endif - -%pybinoperator(__add__, *::operator+, binaryfunc, nb_add); -%pybinoperator(__pos__, *::operator+(), unaryfunc, nb_positive); -%pybinoperator(__pos__, *::operator+() const, unaryfunc, nb_positive); -%pybinoperator(__sub__, *::operator-, binaryfunc, nb_subtract); -%pybinoperator(__neg__, *::operator-(), unaryfunc, nb_negative); -%pybinoperator(__neg__, *::operator-() const, unaryfunc, nb_negative); -%pybinoperator(__mul__, *::operator*, binaryfunc, nb_multiply); -%pybinoperator(__mod__, *::operator%, binaryfunc, nb_remainder); -%pybinoperator(__lshift__, *::operator<<, binaryfunc, nb_lshift); -%pybinoperator(__rshift__, *::operator>>, binaryfunc, nb_rshift); -%pybinoperator(__and__, *::operator&, binaryfunc, nb_and); -%pybinoperator(__or__, *::operator|, binaryfunc, nb_or); -%pybinoperator(__xor__, *::operator^, binaryfunc, nb_xor); -%pycompare(__lt__, *::operator<, Py_LT); -%pycompare(__le__, *::operator<=, Py_LE); -%pycompare(__gt__, *::operator>, Py_GT); -%pycompare(__ge__, *::operator>=, Py_GE); -%pycompare(__eq__, *::operator==, Py_EQ); -%pycompare(__ne__, *::operator!=, Py_NE); - -/* Special cases */ -%rename(__invert__) *::operator~; -%feature("python:slot", "nb_invert", functype="unaryfunc") *::operator~; -%rename(__call__) *::operator(); -%feature("python:slot", "tp_call", functype="ternarycallfunc") *::operator(); - -#if defined(SWIGPYTHON_BUILTIN) -%pybinoperator(__nonzero__, *::operator bool, inquiry, nb_nonzero); -%pybinoperator(__truediv__, *::operator/ , binaryfunc, nb_divide); -#else -%feature("shadow") *::operator bool %{ -def __nonzero__(self): - return $action(self) -__bool__ = __nonzero__ -%}; -%rename(__nonzero__) *::operator bool; -%feature("shadow") *::operator/ %{ -def __truediv__(self, *args): - return $action(self, *args) -__div__ = __truediv__ -%}; -%rename(__truediv__) *::operator/; -%pythonmaybecall *::operator/; -#endif - -/* Ignored operators */ -%ignoreoperator(LNOT) operator!; -%ignoreoperator(LAND) operator&&; -%ignoreoperator(LOR) operator||; -%ignoreoperator(EQ) *::operator=; -%ignoreoperator(PLUSPLUS) *::operator++; -%ignoreoperator(MINUSMINUS) *::operator--; -%ignoreoperator(ARROWSTAR) *::operator->*; -%ignoreoperator(INDEX) *::operator[]; - -/* - Inplace operator declarations. - - They translate the inplace C++ operators (+=, -=, ...) into the - corresponding python equivalents(__iadd__,__isub__), etc, - disabling the ownership of the input 'this' pointer, and assigning - it to the returning object: - - %feature("del") *::Operator; // disables ownership by generating SWIG_POINTER_DISOWN - %feature("new") *::Operator; // claims ownership by generating SWIG_POINTER_OWN - - This makes the most common case safe, ie: - - A& A::operator+=(int i) { ...; return *this; } - ^^^^ ^^^^^^ - - will work fine, even when the resulting python object shares the - 'this' pointer with the input one. The input object is usually - deleted after the operation, including the shared 'this' pointer, - producing 'strange' seg faults, as reported by Lucriz - (lucriz@sitilandia.it). - - If you have an interface that already takes care of that, ie, you - already are using inplace operators and you are not getting - seg. faults, with the new scheme you could end with 'free' elements - that never get deleted (maybe, not sure, it depends). But if that is - the case, you could recover the old behaviour using - - %feature("del","0") A::operator+=; - %feature("new","0") A::operator+=; - - which recovers the old behaviour for the class 'A', or if you are - 100% sure your entire system works fine in the old way, use: - - %feature("del","") *::operator+=; - %feature("new","") *::operator+=; - - The default behaviour assumes that the 'this' pointer's memory is - already owned by the SWIG object; it relinquishes ownership then - takes it back. This may not be the case though as the SWIG object - might be owned by memory managed elsewhere, eg after calling a - function that returns a C++ reference. In such case you will need - to use the features above to recover the old behaviour too. -*/ - -#if defined(SWIGPYTHON_BUILTIN) -#define %pyinplaceoper(SwigPyOper, Oper, functp, slt) %delobject Oper; %newobject Oper; %feature("python:slot", #slt, functype=#functp) Oper; %rename(SwigPyOper) Oper -#else -#define %pyinplaceoper(SwigPyOper, Oper, functp, slt) %delobject Oper; %newobject Oper; %rename(SwigPyOper) Oper -#endif - -%pyinplaceoper(__iadd__ , *::operator +=, binaryfunc, nb_inplace_add); -%pyinplaceoper(__isub__ , *::operator -=, binaryfunc, nb_inplace_subtract); -%pyinplaceoper(__imul__ , *::operator *=, binaryfunc, nb_inplace_multiply); -%pyinplaceoper(__imod__ , *::operator %=, binaryfunc, nb_inplace_remainder); -%pyinplaceoper(__iand__ , *::operator &=, binaryfunc, nb_inplace_and); -%pyinplaceoper(__ior__ , *::operator |=, binaryfunc, nb_inplace_or); -%pyinplaceoper(__ixor__ , *::operator ^=, binaryfunc, nb_inplace_xor); -%pyinplaceoper(__ilshift__, *::operator <<=, binaryfunc, nb_inplace_lshift); -%pyinplaceoper(__irshift__, *::operator >>=, binaryfunc, nb_inplace_rshift); - -/* Special cases */ -#if defined(SWIGPYTHON_BUILTIN) -%pyinplaceoper(__itruediv__ , *::operator /=, binaryfunc, nb_inplace_divide); -#else -%delobject *::operator /=; -%newobject *::operator /=; -%feature("shadow") *::operator /= %{ -def __itruediv__(self, *args): - return $action(self, *args) -__idiv__ = __itruediv__ -%}; -%rename(__itruediv__) *::operator /=; -#endif - -/* Finally, in python we need to mark the binary operations to fail as - 'maybecall' methods */ - -#define %pybinopermaybecall(oper) %pythonmaybecall __ ## oper ## __; %pythonmaybecall __r ## oper ## __ - -%pybinopermaybecall(add); -%pybinopermaybecall(pos); -%pybinopermaybecall(pos); -%pybinopermaybecall(sub); -%pybinopermaybecall(neg); -%pybinopermaybecall(neg); -%pybinopermaybecall(mul); -%pybinopermaybecall(div); -%pybinopermaybecall(truediv); -%pybinopermaybecall(mod); -%pybinopermaybecall(lshift); -%pybinopermaybecall(rshift); -%pybinopermaybecall(and); -%pybinopermaybecall(or); -%pybinopermaybecall(xor); -%pybinopermaybecall(lt); -%pybinopermaybecall(le); -%pybinopermaybecall(gt); -%pybinopermaybecall(ge); -%pybinopermaybecall(eq); -%pybinopermaybecall(ne); - -#endif - - - diff --git a/contrib/tools/swig/Lib/python/pyprimtypes.swg b/contrib/tools/swig/Lib/python/pyprimtypes.swg deleted file mode 100644 index 6a01af17cfa..00000000000 --- a/contrib/tools/swig/Lib/python/pyprimtypes.swg +++ /dev/null @@ -1,353 +0,0 @@ -/* ------------------------------------------------------------ - * Primitive Types - * ------------------------------------------------------------ */ - -/* boolean */ - -%fragment(SWIG_From_frag(bool),"header") { -SWIGINTERNINLINE PyObject* - SWIG_From_dec(bool)(bool value) -{ - return PyBool_FromLong(value ? 1 : 0); -} -} - -#ifdef SWIG_PYTHON_LEGACY_BOOL -// Default prior to SWIG 3.0.0 -%fragment(SWIG_AsVal_frag(bool),"header", - fragment=SWIG_AsVal_frag(long)) { -SWIGINTERN int -SWIG_AsVal_dec(bool)(PyObject *obj, bool *val) -{ - int r = PyObject_IsTrue(obj); - if (r == -1) - return SWIG_ERROR; - if (val) *val = r ? true : false; - return SWIG_OK; -} -} -#else -%fragment(SWIG_AsVal_frag(bool),"header", - fragment=SWIG_AsVal_frag(long)) { -SWIGINTERN int -SWIG_AsVal_dec(bool)(PyObject *obj, bool *val) -{ - int r; - if (!PyBool_Check(obj)) - return SWIG_ERROR; - r = PyObject_IsTrue(obj); - if (r == -1) - return SWIG_ERROR; - if (val) *val = r ? true : false; - return SWIG_OK; -} -} -#endif - -/* int */ - -%fragment(SWIG_From_frag(int),"header") { -SWIGINTERNINLINE PyObject* - SWIG_From_dec(int)(int value) -{ - return PyInt_FromLong((long) value); -} -} - -/* unsigned int */ - -%fragment(SWIG_From_frag(unsigned int),"header") { -SWIGINTERNINLINE PyObject* - SWIG_From_dec(unsigned int)(unsigned int value) -{ - return PyInt_FromSize_t((size_t) value); -} -} - -/* long */ - -%fragment(SWIG_From_frag(long),"header") { - %define_as(SWIG_From_dec(long), PyInt_FromLong) -} - -%fragment(SWIG_AsVal_frag(long),"header", - fragment="SWIG_CanCastAsInteger") { -SWIGINTERN int -SWIG_AsVal_dec(long)(PyObject *obj, long* val) -{ -%#if PY_VERSION_HEX < 0x03000000 - if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else -%#endif - if (PyLong_Check(obj)) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - return SWIG_OverflowError; - } - } -%#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - long v = PyInt_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { - if (val) *val = (long)(d); - return res; - } - } - } -%#endif - return SWIG_TypeError; -} -} - -/* unsigned long */ - -%fragment(SWIG_From_frag(unsigned long),"header", - fragment=SWIG_From_frag(long)) { -SWIGINTERNINLINE PyObject* -SWIG_From_dec(unsigned long)(unsigned long value) -{ - return (value > LONG_MAX) ? - PyLong_FromUnsignedLong(value) : PyInt_FromLong(%numeric_cast(value,long)); -} -} - -%fragment(SWIG_AsVal_frag(unsigned long),"header", - fragment="SWIG_CanCastAsInteger") { -SWIGINTERN int -SWIG_AsVal_dec(unsigned long)(PyObject *obj, unsigned long *val) -{ -%#if PY_VERSION_HEX < 0x03000000 - if (PyInt_Check(obj)) { - long v = PyInt_AsLong(obj); - if (v >= 0) { - if (val) *val = v; - return SWIG_OK; - } else { - return SWIG_OverflowError; - } - } else -%#endif - if (PyLong_Check(obj)) { - unsigned long v = PyLong_AsUnsignedLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - return SWIG_OverflowError; - } - } -%#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - unsigned long v = PyLong_AsUnsignedLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) { - if (val) *val = (unsigned long)(d); - return res; - } - } - } -%#endif - return SWIG_TypeError; -} -} - -/* long long */ - -%fragment(SWIG_From_frag(long long),"header", - fragment="SWIG_LongLongAvailable") { -%#ifdef SWIG_LONG_LONG_AVAILABLE -SWIGINTERNINLINE PyObject* -SWIG_From_dec(long long)(long long value) -{ - return ((value < LONG_MIN) || (value > LONG_MAX)) ? - PyLong_FromLongLong(value) : PyInt_FromLong(%numeric_cast(value,long)); -} -%#endif -} - -%fragment(SWIG_AsVal_frag(long long),"header", - fragment=SWIG_AsVal_frag(long), - fragment="SWIG_CanCastAsInteger", - fragment="SWIG_LongLongAvailable") { -%#ifdef SWIG_LONG_LONG_AVAILABLE -SWIGINTERN int -SWIG_AsVal_dec(long long)(PyObject *obj, long long *val) -{ - int res = SWIG_TypeError; - if (PyLong_Check(obj)) { - long long v = PyLong_AsLongLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - res = SWIG_OverflowError; - } - } else { - long v; - res = SWIG_AsVal(long)(obj,&v); - if (SWIG_IsOK(res)) { - if (val) *val = v; - return res; - } - } -%#ifdef SWIG_PYTHON_CAST_MODE - { - const double mant_max = 1LL << DBL_MANT_DIG; - const double mant_min = -mant_max; - double d; - res = SWIG_AsVal(double)(obj,&d); - if (SWIG_IsOK(res) && !SWIG_CanCastAsInteger(&d, mant_min, mant_max)) - return SWIG_OverflowError; - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, mant_min, mant_max)) { - if (val) *val = (long long)(d); - return SWIG_AddCast(res); - } - res = SWIG_TypeError; - } -%#endif - return res; -} -%#endif -} - -/* unsigned long long */ - -%fragment(SWIG_From_frag(unsigned long long),"header", - fragment="SWIG_LongLongAvailable") { -%#ifdef SWIG_LONG_LONG_AVAILABLE -SWIGINTERNINLINE PyObject* -SWIG_From_dec(unsigned long long)(unsigned long long value) -{ - return (value > LONG_MAX) ? - PyLong_FromUnsignedLongLong(value) : PyInt_FromLong(%numeric_cast(value,long)); -} -%#endif -} - -%fragment(SWIG_AsVal_frag(unsigned long long),"header", - fragment=SWIG_AsVal_frag(unsigned long), - fragment="SWIG_CanCastAsInteger", - fragment="SWIG_LongLongAvailable") { -%#ifdef SWIG_LONG_LONG_AVAILABLE -SWIGINTERN int -SWIG_AsVal_dec(unsigned long long)(PyObject *obj, unsigned long long *val) -{ - int res = SWIG_TypeError; - if (PyLong_Check(obj)) { - unsigned long long v = PyLong_AsUnsignedLongLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - res = SWIG_OverflowError; - } - } else { - unsigned long v; - res = SWIG_AsVal(unsigned long)(obj,&v); - if (SWIG_IsOK(res)) { - if (val) *val = v; - return res; - } - } -%#ifdef SWIG_PYTHON_CAST_MODE - { - const double mant_max = 1LL << DBL_MANT_DIG; - double d; - res = SWIG_AsVal(double)(obj,&d); - if (SWIG_IsOK(res) && !SWIG_CanCastAsInteger(&d, 0, mant_max)) - return SWIG_OverflowError; - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, mant_max)) { - if (val) *val = (unsigned long long)(d); - return SWIG_AddCast(res); - } - res = SWIG_TypeError; - } -%#endif - return res; -} -%#endif -} - -/* double */ - -%fragment(SWIG_From_frag(double),"header") { - %define_as(SWIG_From_dec(double), PyFloat_FromDouble) -} - -%fragment(SWIG_AsVal_frag(double),"header") { -SWIGINTERN int -SWIG_AsVal_dec(double)(PyObject *obj, double *val) -{ - int res = SWIG_TypeError; - if (PyFloat_Check(obj)) { - if (val) *val = PyFloat_AsDouble(obj); - return SWIG_OK; -%#if PY_VERSION_HEX < 0x03000000 - } else if (PyInt_Check(obj)) { - if (val) *val = (double) PyInt_AsLong(obj); - return SWIG_OK; -%#endif - } else if (PyLong_Check(obj)) { - double v = PyLong_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -%#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - double d = PyFloat_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = d; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); - } else { - PyErr_Clear(); - } - } - } -%#endif - return res; -} -} - - - diff --git a/contrib/tools/swig/Lib/python/pyrun.swg b/contrib/tools/swig/Lib/python/pyrun.swg deleted file mode 100644 index 6b119be1c43..00000000000 --- a/contrib/tools/swig/Lib/python/pyrun.swg +++ /dev/null @@ -1,1913 +0,0 @@ -/* ----------------------------------------------------------------------------- - * pyrun.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * ----------------------------------------------------------------------------- */ - -#if PY_VERSION_HEX < 0x02070000 /* 2.7.0 */ -# error "This version of SWIG only supports Python >= 2.7" -#endif - -#if PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03030000 -# error "This version of SWIG only supports Python 3 >= 3.3" -#endif - -/* Common SWIG API */ - -/* for raw pointers */ -#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) -#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) -#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) - -#ifdef SWIGPYTHON_BUILTIN -#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(self, ptr, type, flags) -#else -#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) -#endif - -#define SWIG_InternalNewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(NULL, ptr, type, flags) - -#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) -#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) -#define swig_owntype int - -/* for raw packed data */ -#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - -/* for class or struct pointers */ -#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) -#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) - -/* for C or C++ function pointers */ -#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) -#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(NULL, ptr, type, 0) - -/* for C++ member pointers, ie, member methods */ -#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - - -/* Runtime API */ - -#define SWIG_GetModule(clientdata) SWIG_Python_GetModule(clientdata) -#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) -#define SWIG_NewClientData(obj) SwigPyClientData_New(obj) - -#define SWIG_SetErrorObj SWIG_Python_SetErrorObj -#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg -#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) -#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) -#define SWIG_fail goto fail - - -/* Runtime API implementation */ - -/* Error manipulation */ - -SWIGINTERN void -SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetObject(errtype, obj); - Py_DECREF(obj); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -SWIGINTERN void -SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetString(errtype, msg); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) - -/* Set a constant value */ - -#if defined(SWIGPYTHON_BUILTIN) - -SWIGINTERN void -SwigPyBuiltin_AddPublicSymbol(PyObject *seq, const char *key) { - PyObject *s = PyString_InternFromString(key); - PyList_Append(seq, s); - Py_DECREF(s); -} - -SWIGINTERN void -SWIG_Python_SetConstant(PyObject *d, PyObject *public_interface, const char *name, PyObject *obj) { - PyDict_SetItemString(d, name, obj); - Py_DECREF(obj); - if (public_interface) - SwigPyBuiltin_AddPublicSymbol(public_interface, name); -} - -#else - -SWIGINTERN void -SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { - PyDict_SetItemString(d, name, obj); - Py_DECREF(obj); -} - -#endif - -/* Append a value to the result obj */ - -SWIGINTERN PyObject* -SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyList_Check(result)) { - PyObject *o2 = result; - result = PyList_New(1); - if (result) { - PyList_SET_ITEM(result, 0, o2); - } else { - Py_DECREF(obj); - return o2; - } - } - PyList_Append(result,obj); - Py_DECREF(obj); - } - return result; -} - -/* Unpack the argument tuple */ - -SWIGINTERN Py_ssize_t -SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) -{ - if (!args) { - if (!min && !max) { - return 1; - } else { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", - name, (min == max ? "" : "at least "), (int)min); - return 0; - } - } - if (!PyTuple_Check(args)) { - if (min <= 1 && max >= 1) { - Py_ssize_t i; - objs[0] = args; - for (i = 1; i < max; ++i) { - objs[i] = 0; - } - return 2; - } - PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); - return 0; - } else { - Py_ssize_t l = PyTuple_GET_SIZE(args); - if (l < min) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at least "), (int)min, (int)l); - return 0; - } else if (l > max) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at most "), (int)max, (int)l); - return 0; - } else { - Py_ssize_t i; - for (i = 0; i < l; ++i) { - objs[i] = PyTuple_GET_ITEM(args, i); - } - for (; l < max; ++l) { - objs[l] = 0; - } - return i + 1; - } - } -} - -SWIGINTERN int -SWIG_Python_CheckNoKeywords(PyObject *kwargs, const char *name) { - int no_kwargs = 1; - if (kwargs) { - assert(PyDict_Check(kwargs)); - if (PyDict_Size(kwargs) > 0) { - PyErr_Format(PyExc_TypeError, "%s() does not take keyword arguments", name); - no_kwargs = 0; - } - } - return no_kwargs; -} - -/* A functor is a function object with one single object argument */ -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); - -/* - Helper for static pointer initialization for both C and C++ code, for example - static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); -*/ -#ifdef __cplusplus -#define SWIG_STATIC_POINTER(var) var -#else -#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Python-specific SWIG API */ -#define SWIG_newvarlink() SWIG_Python_newvarlink() -#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) -#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) - -/* ----------------------------------------------------------------------------- - * global variable support code. - * ----------------------------------------------------------------------------- */ - -typedef struct swig_globalvar { - char *name; /* Name of global variable */ - PyObject *(*get_attr)(void); /* Return the current value */ - int (*set_attr)(PyObject *); /* Set the value */ - struct swig_globalvar *next; -} swig_globalvar; - -typedef struct swig_varlinkobject { - PyObject_HEAD - swig_globalvar *vars; -} swig_varlinkobject; - -SWIGINTERN PyObject * -swig_varlink_repr(PyObject *SWIGUNUSEDPARM(v)) { -#if PY_VERSION_HEX >= 0x03000000 - return PyUnicode_InternFromString("<Swig global variables>"); -#else - return PyString_FromString("<Swig global variables>"); -#endif -} - -SWIGINTERN PyObject * -swig_varlink_str(PyObject *o) { - swig_varlinkobject *v = (swig_varlinkobject *) o; -#if PY_VERSION_HEX >= 0x03000000 - PyObject *str = PyUnicode_InternFromString("("); - PyObject *tail; - PyObject *joined; - swig_globalvar *var; - for (var = v->vars; var; var=var->next) { - tail = PyUnicode_FromString(var->name); - joined = PyUnicode_Concat(str, tail); - Py_DecRef(str); - Py_DecRef(tail); - str = joined; - if (var->next) { - tail = PyUnicode_InternFromString(", "); - joined = PyUnicode_Concat(str, tail); - Py_DecRef(str); - Py_DecRef(tail); - str = joined; - } - } - tail = PyUnicode_InternFromString(")"); - joined = PyUnicode_Concat(str, tail); - Py_DecRef(str); - Py_DecRef(tail); - str = joined; -#else - PyObject *str = PyString_FromString("("); - swig_globalvar *var; - for (var = v->vars; var; var=var->next) { - PyString_ConcatAndDel(&str,PyString_FromString(var->name)); - if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); - } - PyString_ConcatAndDel(&str,PyString_FromString(")")); -#endif - return str; -} - -SWIGINTERN void -swig_varlink_dealloc(PyObject *o) { - swig_varlinkobject *v = (swig_varlinkobject *) o; - swig_globalvar *var = v->vars; - while (var) { - swig_globalvar *n = var->next; - free(var->name); - free(var); - var = n; - } -} - -SWIGINTERN PyObject * -swig_varlink_getattr(PyObject *o, char *n) { - swig_varlinkobject *v = (swig_varlinkobject *) o; - PyObject *res = NULL; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->get_attr)(); - break; - } - var = var->next; - } - if (res == NULL && !PyErr_Occurred()) { - PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n); - } - return res; -} - -SWIGINTERN int -swig_varlink_setattr(PyObject *o, char *n, PyObject *p) { - swig_varlinkobject *v = (swig_varlinkobject *) o; - int res = 1; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->set_attr)(p); - break; - } - var = var->next; - } - if (res == 1 && !PyErr_Occurred()) { - PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n); - } - return res; -} - -SWIGINTERN PyTypeObject* -swig_varlink_type(void) { - static char varlink__doc__[] = "Swig var link object"; - static PyTypeObject varlink_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp = { -#if PY_VERSION_HEX >= 0x03000000 - PyVarObject_HEAD_INIT(NULL, 0) -#else - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ -#endif - "swigvarlink", /* tp_name */ - sizeof(swig_varlinkobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor) swig_varlink_dealloc, /* tp_dealloc */ -#if PY_VERSION_HEX < 0x030800b4 - (printfunc)0, /*tp_print*/ -#else - (Py_ssize_t)0, /*tp_vectorcall_offset*/ -#endif - (getattrfunc) swig_varlink_getattr, /* tp_getattr */ - (setattrfunc) swig_varlink_setattr, /* tp_setattr */ - 0, /* tp_compare */ - (reprfunc) swig_varlink_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - (reprfunc) swig_varlink_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - varlink__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ -#if PY_VERSION_HEX >= 0x03040000 - 0, /* tp_finalize */ -#endif -#if PY_VERSION_HEX >= 0x03080000 - 0, /* tp_vectorcall */ -#endif -#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000) - 0, /* tp_print */ -#endif -#ifdef COUNT_ALLOCS - 0, /* tp_allocs */ - 0, /* tp_frees */ - 0, /* tp_maxalloc */ - 0, /* tp_prev */ - 0 /* tp_next */ -#endif - }; - varlink_type = tmp; - type_init = 1; - if (PyType_Ready(&varlink_type) < 0) - return NULL; - } - return &varlink_type; -} - -/* Create a variable linking object for use later */ -SWIGINTERN PyObject * -SWIG_Python_newvarlink(void) { - swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); - if (result) { - result->vars = 0; - } - return ((PyObject*) result); -} - -SWIGINTERN void -SWIG_Python_addvarlink(PyObject *p, const char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { - swig_varlinkobject *v = (swig_varlinkobject *) p; - swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); - if (gv) { - size_t size = strlen(name)+1; - gv->name = (char *)malloc(size); - if (gv->name) { - memcpy(gv->name, name, size); - gv->get_attr = get_attr; - gv->set_attr = set_attr; - gv->next = v->vars; - } - } - v->vars = gv; -} - - -static PyObject *Swig_Globals_global = NULL; - -SWIGINTERN PyObject * -SWIG_globals(void) { - if (Swig_Globals_global == NULL) { - Swig_Globals_global = SWIG_newvarlink(); - } - return Swig_Globals_global; -} - -#ifdef __cplusplus -} -#endif - -/* ----------------------------------------------------------------------------- - * Pointer declarations - * ----------------------------------------------------------------------------- */ - -/* Flags for new pointer objects */ -#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) -#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) - -#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) - -#define SWIG_BUILTIN_TP_INIT (SWIG_POINTER_OWN << 2) -#define SWIG_BUILTIN_INIT (SWIG_BUILTIN_TP_INIT | SWIG_POINTER_OWN) - -#ifdef __cplusplus -extern "C" { -#endif - -/* The python void return value */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Py_Void(void) -{ - PyObject *none = Py_None; - Py_INCREF(none); - return none; -} - -/* SwigPyClientData */ - -typedef struct { - PyObject *klass; - PyObject *newraw; - PyObject *newargs; - PyObject *destroy; - int delargs; - int implicitconv; - PyTypeObject *pytype; -} SwigPyClientData; - -SWIGRUNTIMEINLINE int -SWIG_Python_CheckImplicit(swig_type_info *ty) -{ - SwigPyClientData *data = (SwigPyClientData *)ty->clientdata; - int fail = data ? data->implicitconv : 0; - if (fail) - PyErr_SetString(PyExc_TypeError, "Implicit conversion is prohibited for explicit constructors."); - return fail; -} - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_ExceptionType(swig_type_info *desc) { - SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0; - PyObject *klass = data ? data->klass : 0; - return (klass ? klass : PyExc_RuntimeError); -} - - -SWIGRUNTIME SwigPyClientData * -SwigPyClientData_New(PyObject* obj) -{ - if (!obj) { - return 0; - } else { - SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData)); - /* the klass element */ - data->klass = obj; - Py_INCREF(data->klass); - /* the newraw method and newargs arguments used to create a new raw instance */ - if (PyClass_Check(obj)) { - data->newraw = 0; - Py_INCREF(obj); - data->newargs = obj; - } else { - data->newraw = PyObject_GetAttrString(data->klass, "__new__"); - if (data->newraw) { - data->newargs = PyTuple_New(1); - if (data->newargs) { - Py_INCREF(obj); - PyTuple_SET_ITEM(data->newargs, 0, obj); - } else { - Py_DECREF(data->newraw); - Py_DECREF(data->klass); - free(data); - return 0; - } - } else { - Py_INCREF(obj); - data->newargs = obj; - } - } - /* the destroy method, aka as the C++ delete method */ - data->destroy = PyObject_GetAttrString(data->klass, "__swig_destroy__"); - if (PyErr_Occurred()) { - PyErr_Clear(); - data->destroy = 0; - } - if (data->destroy) { - data->delargs = !(PyCFunction_GET_FLAGS(data->destroy) & METH_O); - } else { - data->delargs = 0; - } - data->implicitconv = 0; - data->pytype = 0; - return data; - } -} - -SWIGRUNTIME void -SwigPyClientData_Del(SwigPyClientData *data) -{ - Py_XDECREF(data->klass); - Py_XDECREF(data->newraw); - Py_XDECREF(data->newargs); - Py_XDECREF(data->destroy); - free(data); -} - -/* =============== SwigPyObject =====================*/ - -typedef struct { - PyObject_HEAD - void *ptr; - swig_type_info *ty; - int own; - PyObject *next; -#ifdef SWIGPYTHON_BUILTIN - PyObject *dict; -#endif -} SwigPyObject; - - -#ifdef SWIGPYTHON_BUILTIN - -SWIGRUNTIME PyObject * -SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) -{ - SwigPyObject *sobj = (SwigPyObject *)v; - - if (!sobj->dict) - sobj->dict = PyDict_New(); - - Py_XINCREF(sobj->dict); - return sobj->dict; -} - -#endif - -SWIGRUNTIME PyObject * -SwigPyObject_long(SwigPyObject *v) -{ - return PyLong_FromVoidPtr(v->ptr); -} - -SWIGRUNTIME PyObject * -SwigPyObject_format(const char* fmt, SwigPyObject *v) -{ - PyObject *res = NULL; - PyObject *args = PyTuple_New(1); - if (args) { - PyObject *val = SwigPyObject_long(v); - if (val) { - PyObject *ofmt; - PyTuple_SET_ITEM(args, 0, val); - ofmt = SWIG_Python_str_FromChar(fmt); - if (ofmt) { -#if PY_VERSION_HEX >= 0x03000000 - res = PyUnicode_Format(ofmt,args); -#else - res = PyString_Format(ofmt,args); -#endif - Py_DECREF(ofmt); - } - } - Py_DECREF(args); - } - return res; -} - -SWIGRUNTIME PyObject * -SwigPyObject_oct(SwigPyObject *v) -{ - return SwigPyObject_format("%o",v); -} - -SWIGRUNTIME PyObject * -SwigPyObject_hex(SwigPyObject *v) -{ - return SwigPyObject_format("%x",v); -} - -SWIGRUNTIME PyObject * -SwigPyObject_repr(SwigPyObject *v) -{ - const char *name = SWIG_TypePrettyName(v->ty); - PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v); - if (repr && v->next) { - PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next); - if (nrep) { -# if PY_VERSION_HEX >= 0x03000000 - PyObject *joined = PyUnicode_Concat(repr, nrep); - Py_DecRef(repr); - Py_DecRef(nrep); - repr = joined; -# else - PyString_ConcatAndDel(&repr,nrep); -# endif - } else { - Py_DecRef(repr); - repr = NULL; - } - } - return repr; -} - -/* We need a version taking two PyObject* parameters so it's a valid - * PyCFunction to use in swigobject_methods[]. */ -SWIGRUNTIME PyObject * -SwigPyObject_repr2(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) -{ - return SwigPyObject_repr((SwigPyObject*)v); -} - -SWIGRUNTIME int -SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w) -{ - void *i = v->ptr; - void *j = w->ptr; - return (i < j) ? -1 : ((i > j) ? 1 : 0); -} - -/* Added for Python 3.x, would it also be useful for Python 2.x? */ -SWIGRUNTIME PyObject* -SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op) -{ - PyObject* res; - if( op != Py_EQ && op != Py_NE ) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0); - return res; -} - - -SWIGRUNTIME PyTypeObject* SwigPyObject_TypeOnce(void); - -#ifdef SWIGPYTHON_BUILTIN -static swig_type_info *SwigPyObject_stype = 0; -SWIGRUNTIME PyTypeObject* -SwigPyObject_type(void) { - SwigPyClientData *cd; - assert(SwigPyObject_stype); - cd = (SwigPyClientData*) SwigPyObject_stype->clientdata; - assert(cd); - assert(cd->pytype); - return cd->pytype; -} -#else -SWIGRUNTIME PyTypeObject* -SwigPyObject_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyObject_TypeOnce(); - return type; -} -#endif - -SWIGRUNTIMEINLINE int -SwigPyObject_Check(PyObject *op) { -#ifdef SWIGPYTHON_BUILTIN - PyTypeObject *target_tp = SwigPyObject_type(); - if (PyType_IsSubtype(op->ob_type, target_tp)) - return 1; - return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0); -#else - return (Py_TYPE(op) == SwigPyObject_type()) - || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0); -#endif -} - -SWIGRUNTIME PyObject * -SwigPyObject_New(void *ptr, swig_type_info *ty, int own); - -static PyObject* Swig_Capsule_global = NULL; - -SWIGRUNTIME void -SwigPyObject_dealloc(PyObject *v) -{ - SwigPyObject *sobj = (SwigPyObject *) v; - PyObject *next = sobj->next; - if (sobj->own == SWIG_POINTER_OWN) { - swig_type_info *ty = sobj->ty; - SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; - PyObject *destroy = data ? data->destroy : 0; - if (destroy) { - /* destroy is always a VARARGS method */ - PyObject *res; - - /* PyObject_CallFunction() has the potential to silently drop - the active exception. In cases of unnamed temporary - variable or where we just finished iterating over a generator - StopIteration will be active right now, and this needs to - remain true upon return from SwigPyObject_dealloc. So save - and restore. */ - - PyObject *type = NULL, *value = NULL, *traceback = NULL; - PyErr_Fetch(&type, &value, &traceback); - - if (data->delargs) { - /* we need to create a temporary object to carry the destroy operation */ - PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0); - if (tmp) { - res = SWIG_Python_CallFunctor(destroy, tmp); - } else { - res = 0; - } - Py_XDECREF(tmp); - } else { - PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); - PyObject *mself = PyCFunction_GET_SELF(destroy); - res = ((*meth)(mself, v)); - } - if (!res) - PyErr_WriteUnraisable(destroy); - - PyErr_Restore(type, value, traceback); - - Py_XDECREF(res); - } -#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - else { - const char *name = SWIG_TypePrettyName(ty); - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); - } -#endif - Py_XDECREF(Swig_Capsule_global); - } - Py_XDECREF(next); -#ifdef SWIGPYTHON_BUILTIN - Py_XDECREF(sobj->dict); -#endif - PyObject_DEL(v); -} - -SWIGRUNTIME PyObject* -SwigPyObject_append(PyObject* v, PyObject* next) -{ - SwigPyObject *sobj = (SwigPyObject *) v; - if (!SwigPyObject_Check(next)) { - PyErr_SetString(PyExc_TypeError, "Attempt to append a non SwigPyObject"); - return NULL; - } - ((SwigPyObject *)next)->next = sobj->next; - sobj->next = next; - Py_INCREF(next); - return SWIG_Py_Void(); -} - -SWIGRUNTIME PyObject* -SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -{ - SwigPyObject *sobj = (SwigPyObject *) v; - if (sobj->next) { - Py_INCREF(sobj->next); - return sobj->next; - } else { - return SWIG_Py_Void(); - } -} - -SWIGINTERN PyObject* -SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -{ - SwigPyObject *sobj = (SwigPyObject *)v; - sobj->own = 0; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -{ - SwigPyObject *sobj = (SwigPyObject *)v; - sobj->own = SWIG_POINTER_OWN; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -SwigPyObject_own(PyObject *v, PyObject *args) -{ - PyObject *val = 0; - if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) { - return NULL; - } else { - SwigPyObject *sobj = (SwigPyObject *)v; - PyObject *obj = PyBool_FromLong(sobj->own); - if (val) { - if (PyObject_IsTrue(val)) { - Py_DECREF(SwigPyObject_acquire(v,args)); - } else { - Py_DECREF(SwigPyObject_disown(v,args)); - } - } - return obj; - } -} - -static PyMethodDef -swigobject_methods[] = { - {"disown", SwigPyObject_disown, METH_NOARGS, "releases ownership of the pointer"}, - {"acquire", SwigPyObject_acquire, METH_NOARGS, "acquires ownership of the pointer"}, - {"own", SwigPyObject_own, METH_VARARGS, "returns/sets ownership of the pointer"}, - {"append", SwigPyObject_append, METH_O, "appends another 'this' object"}, - {"next", SwigPyObject_next, METH_NOARGS, "returns the next 'this' object"}, - {"__repr__",SwigPyObject_repr2, METH_NOARGS, "returns object representation"}, - {0, 0, 0, 0} -}; - -SWIGRUNTIME PyTypeObject* -SwigPyObject_TypeOnce(void) { - static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; - - static PyNumberMethods SwigPyObject_as_number = { - (binaryfunc)0, /*nb_add*/ - (binaryfunc)0, /*nb_subtract*/ - (binaryfunc)0, /*nb_multiply*/ - /* nb_divide removed in Python 3 */ -#if PY_VERSION_HEX < 0x03000000 - (binaryfunc)0, /*nb_divide*/ -#endif - (binaryfunc)0, /*nb_remainder*/ - (binaryfunc)0, /*nb_divmod*/ - (ternaryfunc)0,/*nb_power*/ - (unaryfunc)0, /*nb_negative*/ - (unaryfunc)0, /*nb_positive*/ - (unaryfunc)0, /*nb_absolute*/ - (inquiry)0, /*nb_nonzero*/ - 0, /*nb_invert*/ - 0, /*nb_lshift*/ - 0, /*nb_rshift*/ - 0, /*nb_and*/ - 0, /*nb_xor*/ - 0, /*nb_or*/ -#if PY_VERSION_HEX < 0x03000000 - 0, /*nb_coerce*/ -#endif - (unaryfunc)SwigPyObject_long, /*nb_int*/ -#if PY_VERSION_HEX < 0x03000000 - (unaryfunc)SwigPyObject_long, /*nb_long*/ -#else - 0, /*nb_reserved*/ -#endif - (unaryfunc)0, /*nb_float*/ -#if PY_VERSION_HEX < 0x03000000 - (unaryfunc)SwigPyObject_oct, /*nb_oct*/ - (unaryfunc)SwigPyObject_hex, /*nb_hex*/ -#endif -#if PY_VERSION_HEX >= 0x03050000 /* 3.5 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_matrix_multiply */ -#elif PY_VERSION_HEX >= 0x03000000 /* 3.0 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */ -#else - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */ -#endif - }; - - static PyTypeObject swigpyobject_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp = { -#if PY_VERSION_HEX >= 0x03000000 - PyVarObject_HEAD_INIT(NULL, 0) -#else - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ -#endif - "SwigPyObject", /* tp_name */ - sizeof(SwigPyObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)SwigPyObject_dealloc, /* tp_dealloc */ -#if PY_VERSION_HEX < 0x030800b4 - (printfunc)0, /*tp_print*/ -#else - (Py_ssize_t)0, /*tp_vectorcall_offset*/ -#endif - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ -#if PY_VERSION_HEX >= 0x03000000 - 0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */ -#else - (cmpfunc)SwigPyObject_compare, /* tp_compare */ -#endif - (reprfunc)SwigPyObject_repr, /* tp_repr */ - &SwigPyObject_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigobject_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)SwigPyObject_richcompare,/* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - swigobject_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ -#if PY_VERSION_HEX >= 0x03040000 - 0, /* tp_finalize */ -#endif -#if PY_VERSION_HEX >= 0x03080000 - 0, /* tp_vectorcall */ -#endif -#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000) - 0, /* tp_print */ -#endif -#ifdef COUNT_ALLOCS - 0, /* tp_allocs */ - 0, /* tp_frees */ - 0, /* tp_maxalloc */ - 0, /* tp_prev */ - 0 /* tp_next */ -#endif - }; - swigpyobject_type = tmp; - type_init = 1; - if (PyType_Ready(&swigpyobject_type) != 0) - return NULL; - } - return &swigpyobject_type; -} - -SWIGRUNTIME PyObject * -SwigPyObject_New(void *ptr, swig_type_info *ty, int own) -{ - SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type()); - if (sobj) { - sobj->ptr = ptr; - sobj->ty = ty; - sobj->own = own; - sobj->next = 0; -#ifdef SWIGPYTHON_BUILTIN - sobj->dict = 0; -#endif - if (own == SWIG_POINTER_OWN) { - /* Obtain a reference to the Python capsule wrapping the module information, so that the - * module information is correctly destroyed after all SWIG python objects have been freed - * by the GC (and corresponding destructors invoked) */ - Py_XINCREF(Swig_Capsule_global); - } - } - return (PyObject *)sobj; -} - -/* ----------------------------------------------------------------------------- - * Implements a simple Swig Packed type, and use it instead of string - * ----------------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - void *pack; - swig_type_info *ty; - size_t size; -} SwigPyPacked; - -SWIGRUNTIME PyObject * -SwigPyPacked_repr(SwigPyPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { - return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name); - } else { - return SWIG_Python_str_FromFormat("<Swig Packed %s>", v->ty->name); - } -} - -SWIGRUNTIME PyObject * -SwigPyPacked_str(SwigPyPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ - return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name); - } else { - return SWIG_Python_str_FromChar(v->ty->name); - } -} - -SWIGRUNTIME int -SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w) -{ - size_t i = v->size; - size_t j = w->size; - int s = (i < j) ? -1 : ((i > j) ? 1 : 0); - return s ? s : strncmp((const char *)v->pack, (const char *)w->pack, 2*v->size); -} - -SWIGRUNTIME PyTypeObject* SwigPyPacked_TypeOnce(void); - -SWIGRUNTIME PyTypeObject* -SwigPyPacked_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = SwigPyPacked_TypeOnce(); - return type; -} - -SWIGRUNTIMEINLINE int -SwigPyPacked_Check(PyObject *op) { - return ((op)->ob_type == SwigPyPacked_TypeOnce()) - || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0); -} - -SWIGRUNTIME void -SwigPyPacked_dealloc(PyObject *v) -{ - if (SwigPyPacked_Check(v)) { - SwigPyPacked *sobj = (SwigPyPacked *) v; - free(sobj->pack); - } - PyObject_DEL(v); -} - -SWIGRUNTIME PyTypeObject* -SwigPyPacked_TypeOnce(void) { - static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; - static PyTypeObject swigpypacked_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp = { -#if PY_VERSION_HEX>=0x03000000 - PyVarObject_HEAD_INIT(NULL, 0) -#else - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ -#endif - "SwigPyPacked", /* tp_name */ - sizeof(SwigPyPacked), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)SwigPyPacked_dealloc, /* tp_dealloc */ -#if PY_VERSION_HEX < 0x030800b4 - (printfunc)0, /*tp_print*/ -#else - (Py_ssize_t)0, /*tp_vectorcall_offset*/ -#endif - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ -#if PY_VERSION_HEX>=0x03000000 - 0, /* tp_reserved in 3.0.1 */ -#else - (cmpfunc)SwigPyPacked_compare, /* tp_compare */ -#endif - (reprfunc)SwigPyPacked_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)SwigPyPacked_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigpacked_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ -#if PY_VERSION_HEX >= 0x03040000 - 0, /* tp_finalize */ -#endif -#if PY_VERSION_HEX >= 0x03080000 - 0, /* tp_vectorcall */ -#endif -#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000) - 0, /* tp_print */ -#endif -#ifdef COUNT_ALLOCS - 0, /* tp_allocs */ - 0, /* tp_frees */ - 0, /* tp_maxalloc */ - 0, /* tp_prev */ - 0 /* tp_next */ -#endif - }; - swigpypacked_type = tmp; - type_init = 1; - if (PyType_Ready(&swigpypacked_type) != 0) - return NULL; - } - return &swigpypacked_type; -} - -SWIGRUNTIME PyObject * -SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty) -{ - SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type()); - if (sobj) { - void *pack = malloc(size); - if (pack) { - memcpy(pack, ptr, size); - sobj->pack = pack; - sobj->ty = ty; - sobj->size = size; - } else { - PyObject_DEL((PyObject *) sobj); - sobj = 0; - } - } - return (PyObject *) sobj; -} - -SWIGRUNTIME swig_type_info * -SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size) -{ - if (SwigPyPacked_Check(obj)) { - SwigPyPacked *sobj = (SwigPyPacked *)obj; - if (sobj->size != size) return 0; - memcpy(ptr, sobj->pack, size); - return sobj->ty; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * pointers/data manipulation - * ----------------------------------------------------------------------------- */ - -static PyObject *Swig_This_global = NULL; - -SWIGRUNTIME PyObject * -SWIG_This(void) -{ - if (Swig_This_global == NULL) - Swig_This_global = SWIG_Python_str_FromChar("this"); - return Swig_This_global; -} - -/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ - -/* TODO: I don't know how to implement the fast getset in Python 3 right now */ -#if PY_VERSION_HEX>=0x03000000 -#define SWIG_PYTHON_SLOW_GETSET_THIS -#endif - -SWIGRUNTIME SwigPyObject * -SWIG_Python_GetSwigThis(PyObject *pyobj) -{ - PyObject *obj; - - if (SwigPyObject_Check(pyobj)) - return (SwigPyObject *) pyobj; - -#ifdef SWIGPYTHON_BUILTIN - (void)obj; -# ifdef PyWeakref_CheckProxy - if (PyWeakref_CheckProxy(pyobj)) { - pyobj = PyWeakref_GET_OBJECT(pyobj); - if (pyobj && SwigPyObject_Check(pyobj)) - return (SwigPyObject*) pyobj; - } -# endif - return NULL; -#else - - obj = 0; - -#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - if (PyInstance_Check(pyobj)) { - obj = _PyInstance_Lookup(pyobj, SWIG_This()); - } else { - PyObject **dictptr = _PyObject_GetDictPtr(pyobj); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; - } else { -#ifdef PyWeakref_CheckProxy - if (PyWeakref_CheckProxy(pyobj)) { - PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); - return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; - } -#endif - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } - } - } -#else - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } -#endif - if (obj && !SwigPyObject_Check(obj)) { - /* a PyObject is called 'this', try to get the 'real this' - SwigPyObject from it */ - return SWIG_Python_GetSwigThis(obj); - } - return (SwigPyObject *)obj; -#endif -} - -/* Acquire a pointer value */ - -SWIGRUNTIME int -SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own == SWIG_POINTER_OWN) { - SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj); - if (sobj) { - int oldown = sobj->own; - sobj->own = own; - return oldown; - } - } - return 0; -} - -/* Convert a pointer value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { - int res; - SwigPyObject *sobj; - int implicit_conv = (flags & SWIG_POINTER_IMPLICIT_CONV) != 0; - - if (!obj) - return SWIG_ERROR; - if (obj == Py_None && !implicit_conv) { - if (ptr) - *ptr = 0; - return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK; - } - - res = SWIG_ERROR; - - sobj = SWIG_Python_GetSwigThis(obj); - if (own) - *own = 0; - while (sobj) { - void *vptr = sobj->ptr; - if (ty) { - swig_type_info *to = sobj->ty; - if (to == ty) { - /* no type cast needed */ - if (ptr) *ptr = vptr; - break; - } else { - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) { - sobj = (SwigPyObject *)sobj->next; - } else { - if (ptr) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - if (newmemory == SWIG_CAST_NEW_MEMORY) { - assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */ - if (own) - *own = *own | SWIG_CAST_NEW_MEMORY; - } - } - break; - } - } - } else { - if (ptr) *ptr = vptr; - break; - } - } - if (sobj) { - if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !sobj->own) { - res = SWIG_ERROR_RELEASE_NOT_OWNED; - } else { - if (own) - *own = *own | sobj->own; - if (flags & SWIG_POINTER_DISOWN) { - sobj->own = 0; - } - if (flags & SWIG_POINTER_CLEAR) { - sobj->ptr = 0; - } - res = SWIG_OK; - } - } else { - if (implicit_conv) { - SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0; - if (data && !data->implicitconv) { - PyObject *klass = data->klass; - if (klass) { - PyObject *impconv; - data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ - impconv = SWIG_Python_CallFunctor(klass, obj); - data->implicitconv = 0; - if (PyErr_Occurred()) { - PyErr_Clear(); - impconv = 0; - } - if (impconv) { - SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv); - if (iobj) { - void *vptr; - res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); - if (SWIG_IsOK(res)) { - if (ptr) { - *ptr = vptr; - /* transfer the ownership to 'ptr' */ - iobj->own = 0; - res = SWIG_AddCast(res); - res = SWIG_AddNewMask(res); - } else { - res = SWIG_AddCast(res); - } - } - } - Py_DECREF(impconv); - } - } - } - if (!SWIG_IsOK(res) && obj == Py_None) { - if (ptr) - *ptr = 0; - if (PyErr_Occurred()) - PyErr_Clear(); - res = SWIG_OK; - } - } - } - return res; -} - -/* Convert a function ptr value */ - -SWIGRUNTIME int -SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { - if (!PyCFunction_Check(obj)) { - return SWIG_ConvertPtr(obj, ptr, ty, 0); - } else { - void *vptr = 0; - swig_cast_info *tc; - - /* here we get the method pointer for callbacks */ - const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); - const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; - if (desc) - desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; - if (!desc) - return SWIG_ERROR; - tc = SWIG_TypeCheck(desc,ty); - if (tc) { - int newmemory = 0; - *ptr = SWIG_TypeCast(tc,vptr,&newmemory); - assert(!newmemory); /* newmemory handling not yet implemented */ - } else { - return SWIG_ERROR; - } - return SWIG_OK; - } -} - -/* Convert a packed pointer value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { - swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz); - if (!to) return SWIG_ERROR; - if (ty) { - if (to != ty) { - /* check type cast? */ - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) return SWIG_ERROR; - } - } - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Create a new pointer object - * ----------------------------------------------------------------------------- */ - -/* - Create a new instance object, without calling __init__, and set the - 'this' attribute. -*/ - -SWIGRUNTIME PyObject* -SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this) -{ - PyObject *inst = 0; - PyObject *newraw = data->newraw; - if (newraw) { - inst = PyObject_Call(newraw, data->newargs, NULL); - if (inst) { -#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - } - if (dict) { - PyDict_SetItem(dict, SWIG_This(), swig_this); - } else{ - Py_DECREF(inst); - inst = 0; - } - } -#else - if (PyObject_SetAttr(inst, SWIG_This(), swig_this) == -1) { - Py_DECREF(inst); - inst = 0; - } -#endif - } - } else { -#if PY_VERSION_HEX >= 0x03000000 - PyObject *empty_args = PyTuple_New(0); - if (empty_args) { - PyObject *empty_kwargs = PyDict_New(); - if (empty_kwargs) { - inst = ((PyTypeObject *)data->newargs)->tp_new((PyTypeObject *)data->newargs, empty_args, empty_kwargs); - Py_DECREF(empty_kwargs); - if (inst) { - if (PyObject_SetAttr(inst, SWIG_This(), swig_this) == -1) { - Py_DECREF(inst); - inst = 0; - } else { - PyType_Modified(Py_TYPE(inst)); - } - } - } - Py_DECREF(empty_args); - } -#else - PyObject *dict = PyDict_New(); - if (dict) { - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - } -#endif - } - return inst; -} - -SWIGRUNTIME int -SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) -{ -#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - } - if (dict) { - return PyDict_SetItem(dict, SWIG_This(), swig_this); - } else{ - return -1; - } - } -#endif - return PyObject_SetAttr(inst, SWIG_This(), swig_this); -} - - -SWIGINTERN PyObject * -SWIG_Python_InitShadowInstance(PyObject *args) { - PyObject *obj[2]; - if (!SWIG_Python_UnpackTuple(args, "swiginit", 2, 2, obj)) { - return NULL; - } else { - SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]); - if (sthis) { - Py_DECREF(SwigPyObject_append((PyObject*) sthis, obj[1])); - } else { - if (SWIG_Python_SetSwigThis(obj[0], obj[1]) != 0) - return NULL; - } - return SWIG_Py_Void(); - } -} - -/* Create a new pointer object */ - -SWIGRUNTIME PyObject * -SWIG_Python_NewPointerObj(PyObject *self, void *ptr, swig_type_info *type, int flags) { - SwigPyClientData *clientdata; - PyObject * robj; - int own; - - if (!ptr) - return SWIG_Py_Void(); - - clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0; - own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; - if (clientdata && clientdata->pytype) { - SwigPyObject *newobj; - if (flags & SWIG_BUILTIN_TP_INIT) { - newobj = (SwigPyObject*) self; - if (newobj->ptr) { - PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0); - while (newobj->next) - newobj = (SwigPyObject *) newobj->next; - newobj->next = next_self; - newobj = (SwigPyObject *)next_self; -#ifdef SWIGPYTHON_BUILTIN - newobj->dict = 0; -#endif - } - } else { - newobj = PyObject_New(SwigPyObject, clientdata->pytype); -#ifdef SWIGPYTHON_BUILTIN - if (newobj) { - newobj->dict = 0; - } -#endif - } - if (newobj) { - newobj->ptr = ptr; - newobj->ty = type; - newobj->own = own; - newobj->next = 0; - return (PyObject*) newobj; - } - return SWIG_Py_Void(); - } - - assert(!(flags & SWIG_BUILTIN_TP_INIT)); - - robj = SwigPyObject_New(ptr, type, own); - if (robj && clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { - PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); - Py_DECREF(robj); - robj = inst; - } - return robj; -} - -/* Create a new packed object */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { - return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); -} - -/* -----------------------------------------------------------------------------* - * Get type list - * -----------------------------------------------------------------------------*/ - -#ifdef SWIG_LINK_RUNTIME -void *SWIG_ReturnGlobalTypeList(void *); -#endif - -static PyObject *Swig_TypeCache_global = NULL; - -/* The python cached type query */ -SWIGRUNTIME PyObject * -SWIG_Python_TypeCache(void) { - if (Swig_TypeCache_global == NULL) { - Swig_TypeCache_global = PyDict_New(); - } - return Swig_TypeCache_global; -} - -SWIGRUNTIME swig_module_info * -SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) { -#ifdef SWIG_LINK_RUNTIME - static void *type_pointer = (void *)0; - /* first check if module already created */ - if (!type_pointer) { - type_pointer = SWIG_ReturnGlobalTypeList((void *)0); - } -#else - void *type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0); - if (PyErr_Occurred()) { - PyErr_Clear(); - type_pointer = (void *)0; - } -#endif - return (swig_module_info *) type_pointer; -} - - -static int interpreter_counter = 0; // how many (sub-)interpreters are using swig_module's types - -SWIGRUNTIME void -SWIG_Python_DestroyModule(PyObject *obj) -{ - swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME); - swig_type_info **types = swig_module->types; - size_t i; - if (--interpreter_counter != 0) // another sub-interpreter may still be using the swig_module's types - return; - for (i =0; i < swig_module->size; ++i) { - swig_type_info *ty = types[i]; - if (ty->owndata) { - SwigPyClientData *data = (SwigPyClientData *) ty->clientdata; - ty->clientdata = 0; - if (data) SwigPyClientData_Del(data); - } - } - Py_DECREF(SWIG_This()); - Swig_This_global = NULL; - Py_DECREF(SWIG_globals()); - Swig_Globals_global = NULL; - Py_DECREF(SWIG_Python_TypeCache()); - Swig_TypeCache_global = NULL; - Swig_Capsule_global = NULL; -} - -SWIGRUNTIME void -SWIG_Python_SetModule(swig_module_info *swig_module) { -#if PY_VERSION_HEX >= 0x03000000 - /* Add a dummy module object into sys.modules */ - PyObject *module = PyImport_AddModule("swig_runtime_data" SWIG_RUNTIME_VERSION); -#else - static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} }; /* Sentinel */ - PyObject *module = Py_InitModule("swig_runtime_data" SWIG_RUNTIME_VERSION, swig_empty_runtime_method_table); -#endif - PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule); - if (pointer && module) { - if (PyModule_AddObject(module, SWIGPY_CAPSULE_ATTR_NAME, pointer) == 0) { - ++interpreter_counter; - Swig_Capsule_global = pointer; - } else { - Py_DECREF(pointer); - } - } else { - Py_XDECREF(pointer); - } -} - -SWIGRUNTIME swig_type_info * -SWIG_Python_TypeQuery(const char *type) -{ - PyObject *cache = SWIG_Python_TypeCache(); - PyObject *key = SWIG_Python_str_FromChar(type); - PyObject *obj = PyDict_GetItem(cache, key); - swig_type_info *descriptor; - if (obj) { - descriptor = (swig_type_info *) PyCapsule_GetPointer(obj, NULL); - } else { - swig_module_info *swig_module = SWIG_GetModule(0); - descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); - if (descriptor) { - obj = PyCapsule_New((void*) descriptor, NULL, NULL); - if (obj) { - PyDict_SetItem(cache, key, obj); - Py_DECREF(obj); - } - } - } - Py_DECREF(key); - return descriptor; -} - -/* - For backward compatibility only -*/ -#define SWIG_POINTER_EXCEPTION 0 -#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) -#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) - -SWIGRUNTIME int -SWIG_Python_AddErrMesg(const char* mesg, int infront) -{ - if (PyErr_Occurred()) { - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - PyErr_Fetch(&type, &value, &traceback); - if (value) { - PyObject *old_str = PyObject_Str(value); - const char *tmp = SWIG_Python_str_AsChar(old_str); - const char *errmesg = tmp ? tmp : "Invalid error message"; - Py_XINCREF(type); - PyErr_Clear(); - if (infront) { - PyErr_Format(type, "%s %s", mesg, errmesg); - } else { - PyErr_Format(type, "%s %s", errmesg, mesg); - } - Py_DECREF(old_str); - } - return 1; - } else { - return 0; - } -} - -SWIGRUNTIME int -SWIG_Python_ArgFail(int argnum) -{ - if (PyErr_Occurred()) { - /* add information about failing argument */ - char mesg[256]; - PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); - return SWIG_Python_AddErrMesg(mesg, 1); - } else { - return 0; - } -} - -SWIGRUNTIMEINLINE const char * -SwigPyObject_GetDesc(PyObject *self) -{ - SwigPyObject *v = (SwigPyObject *)self; - swig_type_info *ty = v ? v->ty : 0; - return ty ? ty->str : ""; -} - -SWIGRUNTIME void -SWIG_Python_TypeError(const char *type, PyObject *obj) -{ - if (type) { -#if defined(SWIG_COBJECT_TYPES) - if (obj && SwigPyObject_Check(obj)) { - const char *otype = (const char *) SwigPyObject_GetDesc(obj); - if (otype) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received", - type, otype); - return; - } - } else -#endif - { - const char *otype = (obj ? obj->ob_type->tp_name : 0); - if (otype) { - PyObject *str = PyObject_Str(obj); - const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0; - if (cstr) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", - type, otype, cstr); - } else { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", - type, otype); - } - Py_XDECREF(str); - return; - } - } - PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); - } else { - PyErr_Format(PyExc_TypeError, "unexpected type is received"); - } -} - - -/* Convert a pointer value, signal an exception on a type mismatch */ -SWIGRUNTIME void * -SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int SWIGUNUSEDPARM(argnum), int flags) { - void *result; - if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { - PyErr_Clear(); - } - return result; -} - -#ifdef SWIGPYTHON_BUILTIN -SWIGRUNTIME int -SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) { - PyTypeObject *tp = obj->ob_type; - PyObject *descr; - PyObject *encoded_name; - descrsetfunc f; - int res = -1; - -# ifdef Py_USING_UNICODE - if (PyString_Check(name)) { - name = PyUnicode_Decode(PyString_AsString(name), PyString_Size(name), NULL, NULL); - if (!name) - return -1; - } else if (!PyUnicode_Check(name)) -# else - if (!PyString_Check(name)) -# endif - { - PyErr_Format(PyExc_TypeError, "attribute name must be string, not '%.200s'", name->ob_type->tp_name); - return -1; - } else { - Py_INCREF(name); - } - - if (!tp->tp_dict) { - if (PyType_Ready(tp) != 0) - goto done; - } - - descr = _PyType_Lookup(tp, name); - f = NULL; - if (descr != NULL) - f = descr->ob_type->tp_descr_set; - if (!f) { - if (PyString_Check(name)) { - encoded_name = name; - Py_INCREF(name); - } else { - encoded_name = PyUnicode_AsUTF8String(name); - if (!encoded_name) - goto done; - } - PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name)); - Py_DECREF(encoded_name); - } else { - res = f(descr, obj, value); - } - - done: - Py_DECREF(name); - return res; -} -#endif - - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/swig/Lib/python/pyruntime.swg b/contrib/tools/swig/Lib/python/pyruntime.swg deleted file mode 100644 index 1d028adaf0b..00000000000 --- a/contrib/tools/swig/Lib/python/pyruntime.swg +++ /dev/null @@ -1,49 +0,0 @@ -%insert(runtime) %{ -#if defined(__GNUC__) && defined(_WIN32) && !defined(SWIG_PYTHON_NO_HYPOT_WORKAROUND) -/* Workaround for '::hypot' has not been declared', see https://bugs.python.org/issue11566 */ -# include <math.h> -#endif - -#if !defined(PY_SSIZE_T_CLEAN) && !defined(SWIG_NO_PY_SSIZE_T_CLEAN) -#define PY_SSIZE_T_CLEAN -#endif - -#if __GNUC__ >= 7 -#pragma GCC diagnostic push -#if defined(__cplusplus) && __cplusplus >=201703L -#pragma GCC diagnostic ignored "-Wregister" /* For python-2.7 headers that use register */ -#endif -#endif - -#if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG) -/* Use debug wrappers with the Python release dll */ - -#if defined(_MSC_VER) && _MSC_VER >= 1929 -/* Workaround compilation errors when redefining _DEBUG in MSVC 2019 version 16.10 and later - * See https://github.com/swig/swig/issues/2090 */ -# include <corecrt.h> -#endif - -# undef _DEBUG -# include <Python.h> -# define _DEBUG 1 -#else -# include <Python.h> -#endif - -#if __GNUC__ >= 7 -#pragma GCC diagnostic pop -#endif -%} - -%insert(runtime) "swigrun.swg"; /* SWIG API */ -%insert(runtime) "swigerrors.swg"; /* SWIG errors */ -%insert(runtime) "pyhead.swg"; /* Python includes and fixes */ -%insert(runtime) "pyerrors.swg"; /* Python errors */ -%insert(runtime) "pythreads.swg"; /* Python thread code */ -%insert(runtime) "pyapi.swg"; /* Python API */ -%insert(runtime) "pyrun.swg"; /* Python run-time code */ - -#if defined(SWIGPYTHON_BUILTIN) -%insert(runtime) "builtin.swg"; /* Specialization for classes with single inheritance */ -#endif diff --git a/contrib/tools/swig/Lib/python/pystrings.swg b/contrib/tools/swig/Lib/python/pystrings.swg deleted file mode 100644 index 64ed685e8c9..00000000000 --- a/contrib/tools/swig/Lib/python/pystrings.swg +++ /dev/null @@ -1,139 +0,0 @@ -/* ------------------------------------------------------------ - * utility methods for char strings - * ------------------------------------------------------------ */ -%fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { -SWIGINTERN int -SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) -{ -%#if PY_VERSION_HEX>=0x03000000 -%#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) - if (PyBytes_Check(obj)) -%#else - if (PyUnicode_Check(obj)) -%#endif -%#else - if (PyString_Check(obj)) -%#endif - { - char *cstr; Py_ssize_t len; - int ret = SWIG_OK; -%#if PY_VERSION_HEX>=0x03000000 -%#if !defined(SWIG_PYTHON_STRICT_BYTE_CHAR) - if (!alloc && cptr) { - /* We can't allow converting without allocation, since the internal - representation of string in Python 3 is UCS-2/UCS-4 but we require - a UTF-8 representation. - TODO(bhy) More detailed explanation */ - return SWIG_RuntimeError; - } - obj = PyUnicode_AsUTF8String(obj); - if (!obj) - return SWIG_TypeError; - if (alloc) - *alloc = SWIG_NEWOBJ; -%#endif - if (PyBytes_AsStringAndSize(obj, &cstr, &len) == -1) - return SWIG_TypeError; -%#else - if (PyString_AsStringAndSize(obj, &cstr, &len) == -1) - return SWIG_TypeError; -%#endif - if (cptr) { - if (alloc) { - if (*alloc == SWIG_NEWOBJ) { - *cptr = %new_copy_array(cstr, len + 1, char); - *alloc = SWIG_NEWOBJ; - } else { - *cptr = cstr; - *alloc = SWIG_OLDOBJ; - } - } else { -%#if PY_VERSION_HEX>=0x03000000 -%#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) - *cptr = PyBytes_AsString(obj); -%#else - assert(0); /* Should never reach here with Unicode strings in Python 3 */ -%#endif -%#else - *cptr = SWIG_Python_str_AsChar(obj); - if (!*cptr) - ret = SWIG_TypeError; -%#endif - } - } - if (psize) *psize = len + 1; -%#if PY_VERSION_HEX>=0x03000000 && !defined(SWIG_PYTHON_STRICT_BYTE_CHAR) - Py_XDECREF(obj); -%#endif - return ret; - } else { -%#if defined(SWIG_PYTHON_2_UNICODE) -%#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) -%#error "Cannot use both SWIG_PYTHON_2_UNICODE and SWIG_PYTHON_STRICT_BYTE_CHAR at once" -%#endif -%#if PY_VERSION_HEX<0x03000000 - if (PyUnicode_Check(obj)) { - char *cstr; Py_ssize_t len; - if (!alloc && cptr) { - return SWIG_RuntimeError; - } - obj = PyUnicode_AsUTF8String(obj); - if (!obj) - return SWIG_TypeError; - if (PyString_AsStringAndSize(obj, &cstr, &len) != -1) { - if (cptr) { - if (alloc) *alloc = SWIG_NEWOBJ; - *cptr = %new_copy_array(cstr, len + 1, char); - } - if (psize) *psize = len + 1; - - Py_XDECREF(obj); - return SWIG_OK; - } else { - Py_XDECREF(obj); - } - } -%#endif -%#endif - - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - if (pchar_descriptor) { - void* vptr = 0; - if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { - if (cptr) *cptr = (char *) vptr; - if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; - if (alloc) *alloc = SWIG_OLDOBJ; - return SWIG_OK; - } - } - } - return SWIG_TypeError; -} -} - -%fragment("SWIG_FromCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { -SWIGINTERNINLINE PyObject * -SWIG_FromCharPtrAndSize(const char* carray, size_t size) -{ - if (carray) { - if (size > INT_MAX) { - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - return pchar_descriptor ? - SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void(); - } else { -%#if PY_VERSION_HEX >= 0x03000000 -%#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR) - return PyBytes_FromStringAndSize(carray, %numeric_cast(size, Py_ssize_t)); -%#else - return PyUnicode_DecodeUTF8(carray, %numeric_cast(size, Py_ssize_t), "surrogateescape"); -%#endif -%#else - return PyString_FromStringAndSize(carray, %numeric_cast(size, Py_ssize_t)); -%#endif - } - } else { - return SWIG_Py_Void(); - } -} -} - diff --git a/contrib/tools/swig/Lib/python/python.swg b/contrib/tools/swig/Lib/python/python.swg deleted file mode 100644 index 769d9e104a0..00000000000 --- a/contrib/tools/swig/Lib/python/python.swg +++ /dev/null @@ -1,59 +0,0 @@ -/* ------------------------------------------------------------ - * python.swg - * - * Python configuration module. - * ------------------------------------------------------------ */ - -/* ------------------------------------------------------------ - * Inner macros - * ------------------------------------------------------------ */ -%include <pymacros.swg> - - -/* ------------------------------------------------------------ - * The runtime part - * ------------------------------------------------------------ */ -%include <pyruntime.swg> - -/* ------------------------------------------------------------ - * Special user directives - * ------------------------------------------------------------ */ -%include <pyuserdir.swg> - -/* ------------------------------------------------------------ - * Typemap specializations - * ------------------------------------------------------------ */ -%include <pytypemaps.swg> - -/* ------------------------------------------------------------ - * Overloaded operator support - * ------------------------------------------------------------ */ -%include <pyopers.swg> - -/* ------------------------------------------------------------ - * Warnings for Python keywords - * ------------------------------------------------------------ */ -%include <pythonkw.swg> - -/* ------------------------------------------------------------ - * The Python autodoc support - * ------------------------------------------------------------ */ -%include <pydocs.swg> - -/* ------------------------------------------------------------ - * The Python classes, for C++ - * ------------------------------------------------------------ */ -%include <pyclasses.swg> - -/* ------------------------------------------------------------ - * The Python initialization function - * ------------------------------------------------------------ */ -%include <pyinit.swg> - - -/* ------------------------------------------------------------ - * For backward compatibility - * ------------------------------------------------------------ */ -%include <pybackward.swg> - - diff --git a/contrib/tools/swig/Lib/python/pythonkw.swg b/contrib/tools/swig/Lib/python/pythonkw.swg deleted file mode 100644 index a21034524fd..00000000000 --- a/contrib/tools/swig/Lib/python/pythonkw.swg +++ /dev/null @@ -1,140 +0,0 @@ -/* - Warnings for Python keywords, built-in names and bad names. -*/ - -#define PYTHONKW(x) %keywordwarn("'" `x` "' is a python keyword", rename="_%s") `x` -#define PYTHONBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in python") `x` - - -/* - Warnings for Python keywords - https://docs.python.org/2/reference/lexical_analysis.html#keywords -*/ - -PYTHONKW(and); -PYTHONKW(as); -PYTHONKW(assert); -PYTHONKW(async); -PYTHONKW(await); -PYTHONKW(break); -PYTHONKW(class); -PYTHONKW(continue); -PYTHONKW(def); -PYTHONKW(del); -PYTHONKW(elif); -PYTHONKW(else); -PYTHONKW(except); -PYTHONKW(exec); -PYTHONKW(finally); -PYTHONKW(for); -PYTHONKW(from); -PYTHONKW(global); -PYTHONKW(if); -PYTHONKW(import); -PYTHONKW(in); -PYTHONKW(is); -PYTHONKW(lambda); -PYTHONKW(not); -PYTHONKW(or); -PYTHONKW(pass); -PYTHONKW(print); -PYTHONKW(raise); -PYTHONKW(return); -PYTHONKW(try); -PYTHONKW(while); -PYTHONKW(with); -PYTHONKW(yield); - -/* - built-in functions - https://docs.python.org/2/library/functions.html - */ - -PYTHONBN(abs); -PYTHONBN(apply); -PYTHONBN(bool); -PYTHONBN(buffer); -PYTHONBN(callable); -PYTHONBN(chr); -PYTHONBN(classmethod); -PYTHONBN(cmp); -PYTHONBN(coerce); -PYTHONBN(compile); -PYTHONBN(complex); -PYTHONBN(delattr); -PYTHONBN(dict); -PYTHONBN(dir); -PYTHONBN(divmod); -PYTHONBN(enumerate); -PYTHONBN(eval); -PYTHONBN(execfile); -PYTHONBN(file); -PYTHONBN(filter); -PYTHONBN(float); -PYTHONBN(frozenset); -PYTHONBN(getattr); -PYTHONBN(globals); -PYTHONBN(hasattr); -PYTHONBN(hash); -PYTHONBN(hex); -PYTHONBN(id); -PYTHONBN(input); -PYTHONBN(int); -PYTHONBN(intern); -PYTHONBN(isinstance); -PYTHONBN(issubclass); -PYTHONBN(iter); -PYTHONBN(len); -PYTHONBN(list); -PYTHONBN(locals); -PYTHONBN(long); -PYTHONBN(map); -PYTHONBN(max); -PYTHONBN(min); -PYTHONBN(object); -PYTHONBN(oct); -PYTHONBN(open); -PYTHONBN(ord); -PYTHONBN(pow); -PYTHONBN(property); -PYTHONBN(range); -PYTHONBN(raw_input); -PYTHONBN(reduce); -PYTHONBN(reload); -PYTHONBN(repr); -PYTHONBN(reversed); -PYTHONBN(round); -PYTHONBN(set); -PYTHONBN(setattr); -PYTHONBN(slice); -PYTHONBN(sorted); -PYTHONBN(staticmethod); -PYTHONBN(str); -PYTHONBN(sum); -PYTHONBN(super); -PYTHONBN(tuple); -PYTHONBN(type); -PYTHONBN(unichr); -PYTHONBN(unicode); -PYTHONBN(vars); -PYTHONBN(xrange); -PYTHONBN(zip); - - -/* - built-in names - boolean type and None -*/ -PYTHONBN(True); -PYTHONBN(False); - -PYTHONKW(None); - - -/* - 'self' is also a bad Name -*/ -PYTHONKW(self); - -#undef PYTHONBN -#undef PYTHONKW diff --git a/contrib/tools/swig/Lib/python/pythreads.swg b/contrib/tools/swig/Lib/python/pythreads.swg deleted file mode 100644 index 8d6c5ab49e1..00000000000 --- a/contrib/tools/swig/Lib/python/pythreads.swg +++ /dev/null @@ -1,68 +0,0 @@ -#if defined(SWIG_PYTHON_NO_THREADS) -# if defined(SWIG_PYTHON_THREADS) -# undef SWIG_PYTHON_THREADS -# endif -#endif -#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ -# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) -# define SWIG_PYTHON_USE_GIL -# endif -# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ -# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) -# if PY_VERSION_HEX < 0x03070000 -# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() -# else -# define SWIG_PYTHON_INITIALIZE_THREADS -# endif -# endif -# ifdef __cplusplus /* C++ code */ - class SWIG_Python_Thread_Block { - bool status; - PyGILState_STATE state; - public: - void end() { if (status) { PyGILState_Release(state); status = false;} } - SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} - ~SWIG_Python_Thread_Block() { end(); } - }; - class SWIG_Python_Thread_Allow { - bool status; - PyThreadState *save; - public: - void end() { if (status) { PyEval_RestoreThread(save); status = false; }} - SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} - ~SWIG_Python_Thread_Allow() { end(); } - }; -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block -# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow -# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() -# else /* C code */ -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() -# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() -# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) -# endif -# else /* Old thread way, not implemented, user must provide it */ -# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) -# define SWIG_PYTHON_INITIALIZE_THREADS -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) -# define SWIG_PYTHON_THREAD_END_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# endif -# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) -# define SWIG_PYTHON_THREAD_END_ALLOW -# endif -# endif -#else /* No thread support */ -# define SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# define SWIG_PYTHON_THREAD_END_BLOCK -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# define SWIG_PYTHON_THREAD_END_ALLOW -#endif diff --git a/contrib/tools/swig/Lib/python/pytypemaps.swg b/contrib/tools/swig/Lib/python/pytypemaps.swg deleted file mode 100644 index 0ae25a686e5..00000000000 --- a/contrib/tools/swig/Lib/python/pytypemaps.swg +++ /dev/null @@ -1,105 +0,0 @@ -/* ------------------------------------------------------------ - * Typemap specializations for Python - * ------------------------------------------------------------ */ - -/* ------------------------------------------------------------ - * Fragment section - * ------------------------------------------------------------ */ -#ifdef SWIG_PYTHON_LEGACY_BOOL -// Default prior to SWIG 3.0.0 -#undef SWIG_TYPECHECK_BOOL -%define SWIG_TYPECHECK_BOOL 10000 %enddef -#endif - -/* Include fundamental fragment definitions */ -%include <typemaps/fragments.swg> - -/* Look for user fragments file. */ -%include <pyfragments.swg> - -/* Python fragments for fundamental types */ -%include <pyprimtypes.swg> - -/* Python fragments for char* strings */ -%include <pystrings.swg> - -/* Backward compatibility output helper */ -%fragment("t_output_helper","header") %{ -#define t_output_helper SWIG_Python_AppendOutput -%} - - -/* ------------------------------------------------------------ - * Unified typemap section - * ------------------------------------------------------------ */ - -/* directors are supported in Python */ -#ifndef SWIG_DIRECTOR_TYPEMAPS -#define SWIG_DIRECTOR_TYPEMAPS -#endif - - -/* Python types */ -#define SWIG_Object PyObject * -#define VOID_Object SWIG_Py_Void() - -/* Python allows implicit conversion */ -#define %implicitconv_flag $implicitconv - - -/* Overload of the output/constant/exception/dirout handling */ - -/* append output */ -#define SWIG_AppendOutput(result, obj) SWIG_Python_AppendOutput(result, obj) - -/* set constant */ -#if defined(SWIGPYTHON_BUILTIN) -#define SWIG_SetConstant(name, obj) SWIG_Python_SetConstant(d, d == md ? public_interface : NULL, name,obj) -#else -#define SWIG_SetConstant(name, obj) SWIG_Python_SetConstant(d, name,obj) -#endif - -/* raise */ -#define SWIG_Raise(obj, type, desc) SWIG_Python_Raise(obj, type, desc) - -/* Include the unified typemap library */ -%include <typemaps/swigtypemaps.swg> - - -/* ------------------------------------------------------------ - * Python extra typemaps / typemap overrides - * ------------------------------------------------------------ */ - -/* Get the address of the 'python self' object */ - -%typemap(in,numinputs=0,noblock=1) PyObject **PYTHON_SELF { - $1 = &$self; -} - - -/* Consttab, needed for callbacks, it should be removed later */ - -%typemap(consttab) SWIGTYPE ((*)(ANY)) -{ SWIG_PY_POINTER, "$symname", 0, 0, (void *)($value), &$descriptor } -%typemap(consttab) SWIGTYPE ((* const)(ANY)) = SWIGTYPE ((*)(ANY)); - -%typemap(constcode) SWIGTYPE ((*)(ANY)) "" -%typemap(constcode) SWIGTYPE ((* const)(ANY)) = SWIGTYPE ((*)(ANY)); - - -/* Smart Pointers */ -%typemap(out,noblock=1) const SWIGTYPE & SMARTPOINTER { - $result = SWIG_NewPointerObj(%new_copy(*$1, $*ltype), $descriptor, SWIG_POINTER_OWN | %newpointer_flags); -} - -%typemap(ret,noblock=1) const SWIGTYPE & SMARTPOINTER, SWIGTYPE SMARTPOINTER { - if ($result) { - PyObject *robj = PyObject_CallMethod($result, (char *)"__deref__", NULL); - if (robj && !PyErr_Occurred()) { - SwigPyObject_append((PyObject *) SWIG_Python_GetSwigThis($result), - (PyObject *) SWIG_Python_GetSwigThis(robj)); - Py_DECREF(robj); - } - } -} - diff --git a/contrib/tools/swig/Lib/python/pyuserdir.swg b/contrib/tools/swig/Lib/python/pyuserdir.swg deleted file mode 100644 index 3110760793e..00000000000 --- a/contrib/tools/swig/Lib/python/pyuserdir.swg +++ /dev/null @@ -1,242 +0,0 @@ -/* ------------------------------------------------------------------------- - * Special user directives - * ------------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------------- */ - -/* shadow code */ -#define %shadow %insert("shadow") -#define %pythoncode %insert("python") -#define %pythonbegin %insert("pythonbegin") - - -/* ------------------------------------------------------------------------- */ -/* -Use the "nondynamic" feature to make a wrapped class behave as a "nondynamic" -one, ie, a python class that doesn't dynamically add new attributes. - -For example, for the class - -%pythonnondynamic A; -struct A -{ - int a; - int b; -}; - -you will get: - - aa = A() - aa.a = 1 # Ok - aa.b = 1 # Ok - aa.c = 3 # error - -Since nondynamic is a feature, if you use it like - - %pythonnondynamic; - -it will make all the wrapped classes nondynamic ones. - -The implementation is based on this recipe: - - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252158 - -*/ - -#define %pythonnondynamic %feature("python:nondynamic", "1") -#define %nopythonnondynamic %feature("python:nondynamic", "0") -#define %clearpythonnondynamic %feature("python:nondynamic", "") -#define %pythondynamic %nopythonnondynamic - - -/* ------------------------------------------------------------------------- */ -/* - -Use %pythonmaybecall to flag a method like __add__ or __radd__. These -don't produce an error when called, they just return NotImplemented. - -These methods "may be called" if needed. - -*/ - -#define %pythonmaybecall %feature("python:maybecall", "1") -#define %nopythonmaybecall %feature("python:maybecall", "0") -#define %clearpythonmaybecall %feature("python:maybecall", "") - -/* ------------------------------------------------------------------------- */ -/* - The %pythoncallback feature produce a more natural callback wrapper - than the %callback mechanism, ie, it uses the original name for - the callback and callable objects. - - Just use it as - - %pythoncallback(1) foo; - int foo(int a); - - %pythoncallback(1) A::foo; - struct A { - static int foo(int a); - }; - - int bar(int, int (*pf)(int)); - - then, you can use it as: - - a = foo(1) - b = bar(2, foo) - - c = A.foo(3) - d = bar(4, A.foo) - - - If you use it with a member method - %pythoncallback(1) A::foom; - struct A { - int foom(int a); - }; - - then you can use it as - - r = a.foom(3) # eval the method - mptr = A.foom_cb_ptr # returns the callback pointer - - where the '_cb_ptr' suffix is added for the callback pointer. - -*/ - -#define %pythoncallback %feature("python:callback") -#define %nopythoncallback %feature("python:callback","0") -#define %clearpythoncallback %feature("python:callback","") - -/* ------------------------------------------------------------------------- */ -/* - Support for the old %callback directive name -*/ -#ifdef %callback -#undef %callback -#endif - -#ifdef %nocallback -#undef %nocallback -#endif - -#ifdef %clearcallback -#undef %clearcallback -#endif - -#define %callback(x) %feature("python:callback",`x`) -#define %nocallback %nopythoncallback -#define %clearcallback %clearpythoncallback - -/* ------------------------------------------------------------------------- */ -/* - Thread support - Advance control - -*/ - -#define %nothread %feature("nothread") -#define %thread %feature("nothread","0") -#define %clearnothread %feature("nothread","") - -#define %nothreadblock %feature("nothreadblock") -#define %threadblock %feature("nothreadblock","0") -#define %clearnothreadblock %feature("nothreadblock","") - -#define %nothreadallow %feature("nothreadallow") -#define %threadallow %feature("nothreadallow","0") -#define %clearnothreadallow %feature("nothreadallow","") - - -/* ------------------------------------------------------------------------- */ -/* - Implicit Conversion using the C++ constructor mechanism -*/ - -#define %implicitconv %feature("implicitconv") -#define %noimplicitconv %feature("implicitconv", "0") -#define %clearimplicitconv %feature("implicitconv", "") - - -/* ------------------------------------------------------------------------- */ -/* - Enable keywords parameters -*/ - -#define %kwargs %feature("kwargs") -#define %nokwargs %feature("kwargs", "0") -#define %clearkwargs %feature("kwargs", "") - -/* ------------------------------------------------------------------------- */ -/* - Add python code to the proxy/shadow code - - %pythonprepend - Add code before the C++ function is called - %pythonappend - Add code after the C++ function is called -*/ - -#define %pythonprepend %feature("pythonprepend") -#define %clearpythonprepend %feature("pythonprepend","") - -#define %pythonappend %feature("pythonappend") -#define %clearpythonappend %feature("pythonappend","") - - -/* ------------------------------------------------------------------------- */ -/* - %extend_smart_pointer extend the smart pointer support. - - For example, if you have a smart pointer as: - - template <class Type> class RCPtr { - public: - ... - RCPtr(Type *p); - Type * operator->() const; - ... - }; - - you use the %extend_smart_pointer directive as: - - %extend_smart_pointer(RCPtr<A>); - %template(RCPtr_A) RCPtr<A>; - - then, if you have something like: - - RCPtr<A> make_ptr(); - int foo(A *); - - you can do the following: - - a = make_ptr(); - b = foo(a); - - ie, swig will accept a RCPtr<A> object where a 'A *' is - expected. - - Also, when using vectors - - %extend_smart_pointer(RCPtr<A>); - %template(RCPtr_A) RCPtr<A>; - %template(vector_A) std::vector<RCPtr<A> >; - - you can type - - a = A(); - v = vector_A(2) - v[0] = a - - ie, an 'A *' object is accepted, via implicit conversion, - where a RCPtr<A> object is expected. Additionally - - x = v[0] - - returns (and sets 'x' as) a copy of v[0], making reference - counting possible and consistent. -*/ - -%define %extend_smart_pointer(Type...) -%implicitconv Type; -%apply const SWIGTYPE& SMARTPOINTER { const Type& }; -%apply SWIGTYPE SMARTPOINTER { Type }; -%enddef diff --git a/contrib/tools/swig/Lib/python/typemaps.i b/contrib/tools/swig/Lib/python/typemaps.i deleted file mode 100644 index dba63dd59e0..00000000000 --- a/contrib/tools/swig/Lib/python/typemaps.i +++ /dev/null @@ -1,148 +0,0 @@ -/* ----------------------------------------------------------------------------- - * typemaps.i - * - * Pointer handling - * These mappings provide support for input/output arguments and common - * uses for C/C++ pointers. - * ----------------------------------------------------------------------------- */ - -// INPUT typemaps. -// These remap a C pointer to be an "INPUT" value which is passed by value -// instead of reference. - -/* -The following methods can be applied to turn a pointer into a simple -"input" value. That is, instead of passing a pointer to an object, -you would use a real value instead. - - int *INPUT - short *INPUT - long *INPUT - long long *INPUT - unsigned int *INPUT - unsigned short *INPUT - unsigned long *INPUT - unsigned long long *INPUT - unsigned char *INPUT - bool *INPUT - float *INPUT - double *INPUT - -To use these, suppose you had a C function like this : - - double fadd(double *a, double *b) { - return *a+*b; - } - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - double fadd(double *INPUT, double *INPUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *INPUT { double *a, double *b }; - double fadd(double *a, double *b); - -*/ - -// OUTPUT typemaps. These typemaps are used for parameters that -// are output only. The output value is appended to the result as -// a list element. - -/* -The following methods can be applied to turn a pointer into an "output" -value. When calling a function, no input value would be given for -a parameter, but an output value would be returned. In the case of -multiple output values, they are returned in the form of a Python tuple. - - int *OUTPUT - short *OUTPUT - long *OUTPUT - long long *OUTPUT - unsigned int *OUTPUT - unsigned short *OUTPUT - unsigned long *OUTPUT - unsigned long long *OUTPUT - unsigned char *OUTPUT - bool *OUTPUT - float *OUTPUT - double *OUTPUT - -For example, suppose you were trying to wrap the modf() function in the -C math library which splits x into integral and fractional parts (and -returns the integer part in one of its parameters) : - - double modf(double x, double *ip); - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - double modf(double x, double *OUTPUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *OUTPUT { double *ip }; - double modf(double x, double *ip); - -The Python output of the function would be a tuple containing both -output values. - -*/ - -// INOUT -// Mappings for an argument that is both an input and output -// parameter - -/* -The following methods can be applied to make a function parameter both -an input and output value. This combines the behavior of both the -"INPUT" and "OUTPUT" methods described earlier. Output values are -returned in the form of a Python tuple. - - int *INOUT - short *INOUT - long *INOUT - long long *INOUT - unsigned int *INOUT - unsigned short *INOUT - unsigned long *INOUT - unsigned long long *INOUT - unsigned char *INOUT - bool *INOUT - float *INOUT - double *INOUT - -For example, suppose you were trying to wrap the following function : - - void neg(double *x) { - *x = -(*x); - } - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - void neg(double *INOUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *INOUT { double *x }; - void neg(double *x); - -Unlike C, this mapping does not directly modify the input value (since -this makes no sense in Python). Rather, the modified input value shows -up as the return value of the function. Thus, to apply this function -to a Python variable you might do this : - - x = neg(x) - -Note : previous versions of SWIG used the symbol 'BOTH' to mark -input/output arguments. This is still supported, but will be slowly -phased out in future releases. - -*/ - -%include <typemaps/typemaps.swg> diff --git a/contrib/tools/swig/Lib/python/ya.make b/contrib/tools/swig/Lib/python/ya.make deleted file mode 100644 index e843bff4989..00000000000 --- a/contrib/tools/swig/Lib/python/ya.make +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by devtools/yamaker. - -LIBRARY() - -LICENSE(LicenseRef-scancode-swig) - -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - -VERSION(4.1.1) - -ORIGINAL_SOURCE(https://github.com/swig/swig/archive/v4.1.1.tar.gz) - -ADDINCL( - GLOBAL FOR - swig - contrib/tools/swig/Lib/python - GLOBAL FOR - swig - contrib/tools/swig/Lib -) - -END() diff --git a/contrib/tools/swig/Lib/std/README b/contrib/tools/swig/Lib/std/README deleted file mode 100644 index 5cd759dda19..00000000000 --- a/contrib/tools/swig/Lib/std/README +++ /dev/null @@ -1,22 +0,0 @@ -/* ----------------------------------------------------------------------------- - * C++ STD + STL - * ----------------------------------------------------------------------------- */ - -std_common.i general common code -std_container.i general container code -std_basic_string.i basic string -std_char_traits.i char traits -std_complex.i complex -std_deque.i deque -std_except.i exceptions -std_ios.i ios -std_iostream.i istream/ostream -std_list.i list -std_map.i map -std_multimap.i multimap -std_multiset.i multiset -std_pair.i pair -std_set.i set -std_streambuf.i streambuf -std_vector.i vector -std_vectora.i vector + allocator diff --git a/contrib/tools/swig/Lib/swig.swg b/contrib/tools/swig/Lib/swig.swg deleted file mode 100644 index 9f9d5334986..00000000000 --- a/contrib/tools/swig/Lib/swig.swg +++ /dev/null @@ -1,729 +0,0 @@ -/* ----------------------------------------------------------------------------- - * swig.swg - * - * Common macro definitions for various SWIG directives. This file is always - * included at the top of each input file. - * ----------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------------- - * User Directives - * ----------------------------------------------------------------------------- */ - -/* Deprecated SWIG-1.1 directives */ - -#define %disabledoc %warn "104:%disabledoc is deprecated" -#define %enabledoc %warn "105:%enabledoc is deprecated" -#define %doconly %warn "106:%doconly is deprecated" -#define %style %warn "107:%style is deprecated" /##/ -#define %localstyle %warn "108:%localstyle is deprecated" /##/ -#define %title %warn "109:%title is deprecated" /##/ -#define %section %warn "110:%section is deprecated" /##/ -#define %subsection %warn "111:%subsection is deprecated" /##/ -#define %subsubsection %warn "112:%subsubsection is deprecated" /##/ -#define %new %warn "117:%new is deprecated. Use %newobject" -#define %text %insert("null") - -/* Code insertion directives such as %wrapper %{ ... %} */ - -#define %begin %insert("begin") -#define %runtime %insert("runtime") -#define %header %insert("header") -#define %wrapper %insert("wrapper") -#define %init %insert("init") - -/* Class extension */ - -#define %addmethods %warn "113:%addmethods is now %extend" %extend - -/* %ignore directive */ - -#define %ignore %rename($ignore) -#define %ignorewarn(x) %rename("$ignore:" x) - -/* Access control directives */ - -#define %readonly %warn "114:%readonly is deprecated. Use %immutable; " %feature("immutable"); -#define %readwrite %warn "115:%readwrite is deprecated. Use %mutable; " %feature("immutable",""); - -#define %immutable %feature("immutable") -#define %noimmutable %feature("immutable","0") -#define %clearimmutable %feature("immutable","") -#define %mutable %clearimmutable - -/* Generation of default constructors/destructors (old form, don't use) */ -#define %nodefault %feature("nodefault","1") -#define %default %feature("nodefault","0") -#define %clearnodefault %feature("nodefault","") -#define %makedefault %clearnodefault - -/* Disable the generation of implicit default constructor */ -#define %nodefaultctor %feature("nodefaultctor","1") -#define %defaultctor %feature("nodefaultctor","0") -#define %clearnodefaultctor %feature("nodefaultctor","") - -/* Disable the generation of implicit default destructor (dangerous) */ -#define %nodefaultdtor %feature("nodefaultdtor","1") -#define %defaultdtor %feature("nodefaultdtor","0") -#define %clearnodefaultdtor %feature("nodefaultdtor","") - -/* Enable the generation of copy constructor */ -#define %copyctor %feature("copyctor","1") -#define %nocopyctor %feature("copyctor","0") -#define %clearcopyctor %feature("copyctor","") - -/* Force the old nodefault behavior, ie disable both constructor and destructor */ -#define %oldnodefault %feature("oldnodefault","1") -#define %nooldnodefault %feature("oldnodefault","0") -#define %clearoldnodefault %feature("oldnodefault","") - -/* the %exception directive */ -#if defined(SWIGCSHARP) || defined(SWIGD) -#define %exception %feature("except", canthrow=1) -#else -#define %exception %feature("except") -#endif -#define %noexception %feature("except","0") -#define %clearexception %feature("except","") - -/* the %allowexception directive allows the %exception feature to - be applied to set/get variable methods */ -#define %allowexception %feature("allowexcept") -#define %noallowexception %feature("allowexcept","0") -#define %clearallowexception %feature("allowexcept","") - -/* the %exceptionvar directive, as %exception but it is only applied - to set/get variable methods. You don't need to use the - %allowexception directive when using %exceptionvar. -*/ -#if defined(SWIGCSHARP) || defined(SWIGD) -#define %exceptionvar %feature("exceptvar", canthrow=1) -#else -#define %exceptionvar %feature("exceptvar") -#endif -#define %noexceptionvar %feature("exceptvar","0") -#define %clearexceptionvar %feature("exceptvar","") - -/* the %catches directive */ -#define %catches(tlist...) %feature("catches","("`tlist`")") -#define %clearcatches %feature("catches","") - -/* the %exceptionclass directive */ -#define %exceptionclass %feature("exceptionclass") -#define %noexceptionclass %feature("exceptionclass","0") -#define %clearexceptionclass %feature("exceptionclass","") - -/* the %newobject directive */ -#define %newobject %feature("new") -#define %nonewobject %feature("new","0") -#define %clearnewobject %feature("new","") - -/* the %delobject directive */ -#define %delobject %feature("del") -#define %nodelobject %feature("del","0") -#define %cleardelobject %feature("del","") - -/* the %refobject/%unrefobject directives */ -#define %refobject %feature("ref") -#define %norefobject %feature("ref","0") -#define %clearrefobject %feature("ref","") - -#define %unrefobject %feature("unref") -#define %nounrefobject %feature("unref","0") -#define %clearunrefobject %feature("unref","") - -/* Directives for callback functions (experimental) */ -#define %callback(x) %feature("callback",`x`) -#define %nocallback %feature("callback","0") -#define %clearcallback %feature("callback","") - -/* the %nestedworkaround directive (deprecated) */ -#define %nestedworkaround %feature("nestedworkaround") -#define %nonestedworkaround %feature("nestedworkaround","0") -#define %clearnestedworkaround %feature("nestedworkaround","") - -/* the %flatnested directive */ -#define %flatnested %feature("flatnested") -#define %noflatnested %feature("flatnested","0") -#define %clearflatnested %feature("flatnested","") - -/* the %fastdispatch directive */ -#define %fastdispatch %feature("fastdispatch") -#define %nofastdispatch %feature("fastdispatch","0") -#define %clearfastdispatch %feature("fastdispatch","") - -/* directors directives */ -#define %director %feature("director") -#define %nodirector %feature("director","0") -#define %cleardirector %feature("director","") - -/* naturalvar directives */ -#define %naturalvar %feature("naturalvar") -#define %nonaturalvar %feature("naturalvar","0") -#define %clearnaturalvar %feature("naturalvar","") - -/* nspace directives */ -#define %nspace %feature("nspace") -#define %nonspace %feature("nspace","0") -#define %clearnspace %feature("nspace","") - -/* valuewrapper directives */ -#define %valuewrapper %feature("valuewrapper") -#define %clearvaluewrapper %feature("valuewrapper","") -#define %novaluewrapper %feature("novaluewrapper") -#define %clearnovaluewrapper %feature("novaluewrapper","") - -/* Contract support - Experimental */ -#define %contract %feature("contract") -#define %nocontract %feature("contract","0") -#define %clearcontract %feature("contract","") - -/* Macro for setting a dynamic cast function */ -%define DYNAMIC_CAST(mangle,func) -%init %{ - mangle->dcast = (swig_dycast_func) func; -%} -%enddef - -/* aggregation support */ -/* - This macro performs constant aggregation. Basically the idea of - constant aggregation is that you can group a collection of constants - together. For example, suppose you have some code like this: - - #define UP 1 - #define DOWN 2 - #define LEFT 3 - #define RIGHT 4 - - Now, suppose you had a function like this: - - int move(int direction) - - In this case, you might want to restrict the direction argument to - one of the supplied constant names. To do this, you could write some - typemap code by hand. Alternatively, you can use the - %aggregate_check macro defined here to create a simple check - function for you. Here is an example: - - %aggregate_check(int, check_direction, UP, DOWN, LEFT, RIGHT); - - Now, using a typemap - - %typemap(check) int direction { - if (!check_direction($1)) SWIG_exception(SWIG_ValueError,"Bad direction."); - } - - or a contract (better) - - %contract move(int x) { - require: - check_direction(x); - } - -*/ - -%define %aggregate_check(TYPE, NAME, FIRST, ...) -%wrapper %{ -static int NAME(TYPE x) { - static TYPE values[] = { FIRST, ##__VA_ARGS__ }; - static int size = sizeof(values); - int i,j; - for (i = 0, j = 0; i < size; i+=sizeof(TYPE),j++) { - if (x == values[j]) return 1; - } - return 0; -} -%} -%enddef - - -/* ----------------------------------------------------------------------------- - * %rename predicates - * ----------------------------------------------------------------------------- */ -/* - Predicates to be used with %rename, for example: - - - to rename all the functions: - - %rename("%(utitle)s", %$isfunction) ""; - - - to rename only the member methods: - - %rename("m_%(utitle)s", %$isfunction, %$ismember) ""; - - - to rename only the global functions: - - %rename("m_%(utitle)s", %$isfunction, %$not %$ismember) ""; - - or - - %rename("g_%(utitle)s", %$isfunction, %$isglobal) ""; - - - to ignore the enumitems in a given class: - - %rename("$ignore", %$isenumitem, %$classname="MyClass") ""; - - we use the prefix '%$' to avoid clashes with other swig - macros/directives. - -*/ - -/* Note that when %$not is used with another macro, say %enum as follows: %$not %$enum, the result is "notmatch=enum" */ -%define %$not "not" %enddef - -%define %$isenum "match"="enum" %enddef -%define %$isenumitem "match"="enumitem" %enddef -%define %$isaccess "match"="access" %enddef -%define %$isclass "match"="class","notmatch$template$templatetype"="class" %enddef -%define %$isextend "match"="extend" %enddef -%define %$isconstructor "match"="constructor" %enddef -%define %$isdestructor "match"="destructor" %enddef -%define %$isnamespace "match"="namespace" %enddef -%define %$istemplate "match"="template" %enddef -%define %$isconstant "match"="constant" %enddef /* %constant definition */ -%define %$isusing "match"="using" %enddef - -%define %$isunion "match$kind"="union" %enddef -%define %$isfunction "match$kind"="function" %enddef -%define %$isvariable "match$kind"="variable" %enddef -%define %$isimmutable "match$feature:immutable"="1" %enddef -%define %$hasconsttype "match$hasconsttype"="1" %enddef -%define %$hasvalue "match$hasvalue"="1" %enddef -%define %$isextension "match$isextension"="1" %enddef - -%define %$isstatic "match$storage"="static" %enddef -%define %$isfriend "match$storage"="friend" %enddef -%define %$istypedef "match$storage"="typedef" %enddef -%define %$isvirtual "match$storage"="virtual" %enddef -%define %$isexplicit "match$storage"="explicit" %enddef -%define %$isextern "match$storage"="extern" %enddef - -%define %$ismember "match$ismember"="1" %enddef -%define %$isglobal %$not %$ismember %enddef -%define %$isextendmember "match$isextendmember"="1" %enddef -%define %$innamespace "match$parentNode$nodeType"="namespace" %enddef - -%define %$ispublic "match$access"="public" %enddef -%define %$isprotected "match$access"="protected" %enddef -%define %$isprivate "match$access"="private" %enddef - -%define %$ismemberget "match$memberget"="1" %enddef -%define %$ismemberset "match$memberset"="1" %enddef - -%define %$classname %$ismember,"match$parentNode$name" %enddef -%define %$isnested "match$nested"="1" %enddef - -/* ----------------------------------------------------------------------------- - * Common includes for warning labels, macros, fragments etc - * ----------------------------------------------------------------------------- */ - -%include <swigwarnings.swg> -%include <swigfragments.swg> - -/* ----------------------------------------------------------------------------- - * Overloading support - * ----------------------------------------------------------------------------- */ - -/* - * Function/method overloading support. This is done through typemaps, - * but also involves a precedence level. - */ - -/* Macro for overload resolution */ - -%define %typecheck(_x...) %typemap(typecheck, precedence=_x) %enddef - -/* Macros for precedence levels */ - -%define SWIG_TYPECHECK_POINTER 0 %enddef -%define SWIG_TYPECHECK_ITERATOR 5 %enddef -%define SWIG_TYPECHECK_VOIDPTR 10 %enddef -%define SWIG_TYPECHECK_BOOL 15 %enddef -%define SWIG_TYPECHECK_UINT8 20 %enddef -%define SWIG_TYPECHECK_INT8 25 %enddef -%define SWIG_TYPECHECK_UINT16 30 %enddef -%define SWIG_TYPECHECK_INT16 35 %enddef -%define SWIG_TYPECHECK_UINT32 40 %enddef -%define SWIG_TYPECHECK_INT32 45 %enddef -%define SWIG_TYPECHECK_SIZE 47 %enddef -%define SWIG_TYPECHECK_PTRDIFF 48 %enddef -%define SWIG_TYPECHECK_UINT64 50 %enddef -%define SWIG_TYPECHECK_INT64 55 %enddef -%define SWIG_TYPECHECK_UINT128 60 %enddef -%define SWIG_TYPECHECK_INT128 65 %enddef -%define SWIG_TYPECHECK_INTEGER 70 %enddef -%define SWIG_TYPECHECK_FLOAT 80 %enddef -%define SWIG_TYPECHECK_DOUBLE 90 %enddef -%define SWIG_TYPECHECK_CPLXFLT 95 %enddef -%define SWIG_TYPECHECK_CPLXDBL 100 %enddef -%define SWIG_TYPECHECK_COMPLEX 105 %enddef -%define SWIG_TYPECHECK_UNICHAR 110 %enddef -%define SWIG_TYPECHECK_STDUNISTRING 115 %enddef -%define SWIG_TYPECHECK_UNISTRING 120 %enddef -%define SWIG_TYPECHECK_CHAR 130 %enddef -%define SWIG_TYPECHECK_STDSTRING 135 %enddef -%define SWIG_TYPECHECK_STRING 140 %enddef -%define SWIG_TYPECHECK_PAIR 150 %enddef -%define SWIG_TYPECHECK_STDARRAY 155 %enddef -%define SWIG_TYPECHECK_VECTOR 160 %enddef -%define SWIG_TYPECHECK_DEQUE 170 %enddef -%define SWIG_TYPECHECK_LIST 180 %enddef -%define SWIG_TYPECHECK_SET 190 %enddef -%define SWIG_TYPECHECK_MULTISET 200 %enddef -%define SWIG_TYPECHECK_MAP 210 %enddef -%define SWIG_TYPECHECK_MULTIMAP 220 %enddef -%define SWIG_TYPECHECK_STACK 230 %enddef -%define SWIG_TYPECHECK_QUEUE 240 %enddef - -%define SWIG_TYPECHECK_BOOL_ARRAY 1015 %enddef -%define SWIG_TYPECHECK_INT8_ARRAY 1025 %enddef -%define SWIG_TYPECHECK_INT16_ARRAY 1035 %enddef -%define SWIG_TYPECHECK_INT32_ARRAY 1045 %enddef -%define SWIG_TYPECHECK_INT64_ARRAY 1055 %enddef -%define SWIG_TYPECHECK_INT128_ARRAY 1065 %enddef -%define SWIG_TYPECHECK_FLOAT_ARRAY 1080 %enddef -%define SWIG_TYPECHECK_DOUBLE_ARRAY 1090 %enddef -%define SWIG_TYPECHECK_CHAR_ARRAY 1130 %enddef -%define SWIG_TYPECHECK_STRING_ARRAY 1140 %enddef -%define SWIG_TYPECHECK_OBJECT_ARRAY 1150 %enddef - -%define SWIG_TYPECHECK_BOOL_PTR 2015 %enddef -%define SWIG_TYPECHECK_UINT8_PTR 2020 %enddef -%define SWIG_TYPECHECK_INT8_PTR 2025 %enddef -%define SWIG_TYPECHECK_UINT16_PTR 2030 %enddef -%define SWIG_TYPECHECK_INT16_PTR 2035 %enddef -%define SWIG_TYPECHECK_UINT32_PTR 2040 %enddef -%define SWIG_TYPECHECK_INT32_PTR 2045 %enddef -%define SWIG_TYPECHECK_UINT64_PTR 2050 %enddef -%define SWIG_TYPECHECK_INT64_PTR 2055 %enddef -%define SWIG_TYPECHECK_FLOAT_PTR 2080 %enddef -%define SWIG_TYPECHECK_DOUBLE_PTR 2090 %enddef -%define SWIG_TYPECHECK_CHAR_PTR 2130 %enddef - -%define SWIG_TYPECHECK_SWIGOBJECT 5000 %enddef - - -/* ----------------------------------------------------------------------------- - * Default handling of certain overloaded operators - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -%ignoreoperator(NEW) operator new; -%ignoreoperator(DELETE) operator delete; -%ignoreoperator(NEWARR) operator new[]; -%ignoreoperator(DELARR) operator delete[]; - -/* add C++ operator aliases */ -%rename("operator &&") operator and; // `and' `&&' -%rename("operator ||") operator or; // `or' `||' -%rename("operator !") operator not; // `not' `!' -%rename("operator &=") operator and_eq; // `and_eq' `&=' -%rename("operator &") operator bitand; // `bitand' `&' -%rename("operator |") operator bitor; // `bitor' `|' -%rename("operator ~") operator compl; // `compl' `~' -%rename("operator !=") operator not_eq; // `not_eq' `!=' -%rename("operator |=") operator or_eq; // `or_eq' `|=' -%rename("operator ^") operator xor; // `xor' `^' -%rename("operator ^=") operator xor_eq; // `xor_eq' `^=' - -/* Smart pointer handling */ - -%rename(__deref__) *::operator->; -%rename(__ref__) *::operator*(); -%rename(__ref__) *::operator*() const; - -/* Define std namespace */ -namespace std { - /* Warn about std::initializer_list usage. The constructor/method where used should probably be ignored. See docs. */ - template<typename T> class initializer_list {}; - %typemap(in, warning=SWIGWARN_TYPEMAP_INITIALIZER_LIST_MSG) initializer_list<T> "" - %typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) initializer_list<T> "" -} -#endif - -/* ----------------------------------------------------------------------------- - * Default char * and C array typemaps - * ----------------------------------------------------------------------------- */ - -/* Set up the typemap for handling new return strings */ - -#ifdef __cplusplus -%typemap(newfree) char * "delete [] $1;" -#else -%typemap(newfree) char * "free($1);" -#endif - -/* Default typemap for handling char * members */ - -#ifdef __cplusplus -%typemap(memberin,fragment="<string.h>") char * { - delete [] $1; - if ($input) { - $1 = ($1_type) (new char[strlen((const char *)$input)+1]); - strcpy((char *)$1, (const char *)$input); - } else { - $1 = 0; - } -} -%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * { - if ($input) { - $1 = ($1_type) (new char[strlen((const char *)$input)+1]); - strcpy((char *)$1, (const char *)$input); - } else { - $1 = 0; - } -} -%typemap(globalin,fragment="<string.h>") char * { - delete [] $1; - if ($input) { - $1 = ($1_type) (new char[strlen((const char *)$input)+1]); - strcpy((char *)$1, (const char *)$input); - } else { - $1 = 0; - } -} -%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * { - if ($input) { - $1 = ($1_type) (new char[strlen((const char *)$input)+1]); - strcpy((char *)$1, (const char *)$input); - } else { - $1 = 0; - } -} -#else -%typemap(memberin,fragment="<string.h>") char * { - free($1); - if ($input) { - $1 = ($1_type) malloc(strlen((const char *)$input)+1); - strcpy((char *)$1, (const char *)$input); - } else { - $1 = 0; - } -} -%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * { - if ($input) { - $1 = ($1_type) malloc(strlen((const char *)$input)+1); - strcpy((char *)$1, (const char *)$input); - } else { - $1 = 0; - } -} -%typemap(globalin,fragment="<string.h>") char * { - free($1); - if ($input) { - $1 = ($1_type) malloc(strlen((const char *)$input)+1); - strcpy((char *)$1, (const char *)$input); - } else { - $1 = 0; - } -} -%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * { - if ($input) { - $1 = ($1_type) malloc(strlen((const char *)$input)+1); - strcpy((char *)$1, (const char *)$input); - } else { - $1 = 0; - } -} - -#endif - -/* Character array handling */ - -%typemap(memberin,fragment="<string.h>") char [ANY] { - if($input) { - strncpy((char*)$1, (const char *)$input, $1_dim0-1); - $1[$1_dim0-1] = 0; - } else { - $1[0] = 0; - } -} - -%typemap(globalin,fragment="<string.h>") char [ANY] { - if($input) { - strncpy((char*)$1, (const char *)$input, $1_dim0-1); - $1[$1_dim0-1] = 0; - } else { - $1[0] = 0; - } -} - -%typemap(memberin,fragment="<string.h>") char [] { - if ($input) strcpy((char *)$1, (const char *)$input); - else $1[0] = 0; -} - -%typemap(globalin,fragment="<string.h>") char [] { - if ($input) strcpy((char *)$1, (const char *)$input); - else $1[0] = 0; -} - -/* memberin/globalin typemap for arrays. */ - -%typemap(memberin,fragment="<string.h>") SWIGTYPE [ANY] { - size_t ii; - $1_basetype *b = ($1_basetype *) $1; - for (ii = 0; ii < (size_t)$1_size; ii++) b[ii] = *(($1_basetype *) $input + ii); -} - -%typemap(globalin,fragment="<string.h>") SWIGTYPE [ANY] { - size_t ii; - $1_basetype *b = ($1_basetype *) $1; - for (ii = 0; ii < (size_t)$1_size; ii++) b[ii] = *(($1_basetype *) $input + ii); -} - -/* memberin/globalin typemap for double arrays. */ - -%typemap(memberin,fragment="<string.h>") SWIGTYPE [ANY][ANY] { - $basetype (*inp)[$1_dim1] = ($basetype (*)[$1_dim1])($input); - $basetype (*dest)[$1_dim1] = ($basetype (*)[$1_dim1])($1); - size_t ii = 0; - for (; ii < $1_dim0; ++ii) { - $basetype *ip = inp[ii]; - $basetype *dp = dest[ii]; - size_t jj = 0; - for (; jj < $1_dim1; ++jj) dp[jj] = ip[jj]; - } -} - -%typemap(globalin,fragment="<string.h>") SWIGTYPE [ANY][ANY] { - $basetype (*inp)[$1_dim1] = ($basetype (*)[$1_dim1])($input); - $basetype (*dest)[$1_dim1] = ($basetype (*)[$1_dim1])($1); - size_t ii = 0; - for (; ii < $1_dim0; ++ii) { - $basetype *ip = inp[ii]; - $basetype *dp = dest[ii]; - size_t jj = 0; - for (; jj < $1_dim1; ++jj) dp[jj] = ip[jj]; - } -} - -/* ----------------------------------------------------------------------------- - * Runtime code - * ----------------------------------------------------------------------------- */ - - -%insert("runtime") "swiglabels.swg" - - -/* The SwigValueWrapper class */ - -/* - * This template wrapper is used to handle C++ objects that are passed or - * returned by value. This is necessary to handle objects that define - * no default-constructor (making it difficult for SWIG to properly declare - * local variables). - * - * The wrapper is used as follows. First consider a function like this: - * - * Vector cross_product(Vector a, Vector b) - * - * Now, if Vector is defined as a C++ class with no default constructor, - * code is generated as follows: - * - * Vector *wrap_cross_product(Vector *inarg1, Vector *inarg2) { - * SwigValueWrapper<Vector> arg1; - * SwigValueWrapper<Vector> arg2; - * SwigValueWrapper<Vector> result; - * - * arg1 = *inarg1; - * arg2 = *inarg2; - * ... - * result = cross_product(arg1,arg2); - * ... - * return new Vector(result); - * } - * - * In the wrappers, the template SwigValueWrapper simply provides a thin - * layer around a Vector *. However, it does this in a way that allows - * the object to be bound after the variable declaration (which is not possible - * with the bare object when it lacks a default constructor). - * - * An observant reader will notice that the code after the variable declarations - * is *identical* to the code used for classes that do define default constructors. - * Thus, this neat trick allows us to fix this special case without having to - * make massive changes to typemaps and other parts of the SWIG code generator. - * - * Note: this code is not included when SWIG runs in C-mode, when classes - * define default constructors, or when pointers and references are used. - * SWIG tries to avoid doing this except in very special circumstances. - * - * Note: This solution suffers from making a large number of copies - * of the underlying object. However, this is needed in the interest of - * safety and in order to cover all of the possible ways in which a value - * might be assigned. For example: - * - * arg1 = *inarg1; // Assignment from a pointer - * arg1 = Vector(1,2,3); // Assignment from a value - * - * SwigValueWrapper is a drop in replacement to modify normal value semantics by - * using the heap instead of the stack to copy/move the underlying object it is - * managing. Smart pointers also manage an underlying object on the heap, so - * SwigValueWrapper has characteristics of a smart pointer. The reset function - * is specific smart pointer functionality, but cannot be a non-static member as - * when SWIG modifies typemap code it assumes non-static member function calls - * are routed to the underlying object, changing for example $1.f() to (&x)->f(). - * The reset function was added as an optimisation to avoid some copying/moving - * and to take ownership of an object already created on the heap. - * - * The class offers a strong guarantee of exception safety. - * With regards to the implementation, the private SwigSmartPointer nested class is - * a simple smart pointer providing exception safety, much like std::auto_ptr. - * - * This wrapping technique was suggested by William Fulton and is henceforth - * known as the "Fulton Transform" :-). - */ - -#ifdef __cplusplus -// Placed in the header section to ensure the language specific header files are -// the first included headers and not <utility> -%insert("header") %{ -#ifdef __cplusplus -#include <utility> -/* SwigValueWrapper is described in swig.swg */ -template<typename T> class SwigValueWrapper { - struct SwigSmartPointer { - T *ptr; - SwigSmartPointer(T *p) : ptr(p) { } - ~SwigSmartPointer() { delete ptr; } - SwigSmartPointer& operator=(SwigSmartPointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } - void reset(T *p) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = p; } - } pointer; - SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs); - SwigValueWrapper(const SwigValueWrapper<T>& rhs); -public: - SwigValueWrapper() : pointer(0) { } - SwigValueWrapper& operator=(const T& t) { SwigSmartPointer tmp(new T(t)); pointer = tmp; return *this; } -#if __cplusplus >=201103L - SwigValueWrapper& operator=(T&& t) { SwigSmartPointer tmp(new T(std::move(t))); pointer = tmp; return *this; } - operator T&&() const { return std::move(*pointer.ptr); } -#else - operator T&() const { return *pointer.ptr; } -#endif - T *operator&() const { return pointer.ptr; } - static void reset(SwigValueWrapper& t, T *p) { t.pointer.reset(p); } -}; - -/* - * SwigValueInit() is a generic initialisation solution as the following approach: - * - * T c_result = T(); - * - * doesn't compile for all types for example: - * - * unsigned int c_result = unsigned int(); - */ -template <typename T> T SwigValueInit() { - return T(); -} - -#if __cplusplus >=201103L -# define SWIG_STD_MOVE(OBJ) std::move(OBJ) -#else -# define SWIG_STD_MOVE(OBJ) OBJ -#endif - -#endif -%} -#endif - diff --git a/contrib/tools/swig/Lib/swigerrors.swg b/contrib/tools/swig/Lib/swigerrors.swg deleted file mode 100644 index 4d5a8e473d1..00000000000 --- a/contrib/tools/swig/Lib/swigerrors.swg +++ /dev/null @@ -1,15 +0,0 @@ -/* SWIG Errors applicable to all language modules, values are reserved from -1 to -99 */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - diff --git a/contrib/tools/swig/Lib/swigfragments.swg b/contrib/tools/swig/Lib/swigfragments.swg deleted file mode 100644 index 28aa1180f92..00000000000 --- a/contrib/tools/swig/Lib/swigfragments.swg +++ /dev/null @@ -1,90 +0,0 @@ -/* ----------------------------------------------------------------------------- - * swigfragments.swg - * - * Common fragments - * ----------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------------- - * Fragments for C header files - * ----------------------------------------------------------------------------- */ - -%fragment("<float.h>", "header") %{ -#include <float.h> -%} - -/* Default compiler options for gcc allow long_long but not LLONG_MAX. - * Define SWIG_NO_LLONG_MAX if this added limits support is not wanted. */ -%fragment("<limits.h>", "header") %{ -#include <limits.h> -#if !defined(SWIG_NO_LLONG_MAX) -# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) -# define LLONG_MAX __LONG_LONG_MAX__ -# define LLONG_MIN (-LLONG_MAX - 1LL) -# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) -# endif -#endif -%} - -%fragment("<math.h>", "header") %{ -#include <math.h> -%} - -%fragment("<string.h>", "header") %{ -#include <string.h> -%} - -%fragment("<stddef.h>", "header") %{ -#include <stddef.h> -%} - -%fragment("<stdio.h>", "header") %{ -#include <stdio.h> -#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__BORLANDC__) || defined(_WATCOM) -# ifndef snprintf -# define snprintf _snprintf -# endif -#endif -%} - -%fragment("<stdlib.h>", "header") %{ -#include <stdlib.h> -#ifdef _MSC_VER -# ifndef strtoull -# define strtoull _strtoui64 -# endif -# ifndef strtoll -# define strtoll _strtoi64 -# endif -#endif -%} - -%fragment("<wchar.h>", "header") %{ -#include <wchar.h> -#include <limits.h> -#ifndef WCHAR_MIN -# define WCHAR_MIN 0 -#endif -#ifndef WCHAR_MAX -# define WCHAR_MAX 65535 -#endif -%} - -/* ----------------------------------------------------------------------------- - * Fragments for C++ header files - * ----------------------------------------------------------------------------- */ - -%fragment("<algorithm>", "header") %{ -#include <algorithm> -%} - -%fragment("<stdexcept>", "header") %{ -#include <stdexcept> -%} - -%fragment("<string>", "header") %{ -#include <string> -%} - -%fragment("<memory>", "header") %{ -#include <memory> -%} diff --git a/contrib/tools/swig/Lib/swiginit.swg b/contrib/tools/swig/Lib/swiginit.swg deleted file mode 100644 index e50b1b46dcf..00000000000 --- a/contrib/tools/swig/Lib/swiginit.swg +++ /dev/null @@ -1,233 +0,0 @@ -/* ----------------------------------------------------------------------------- - * Type initialization: - * This problem is tough by the requirement that no dynamic - * memory is used. Also, since swig_type_info structures store pointers to - * swig_cast_info structures and swig_cast_info structures store pointers back - * to swig_type_info structures, we need some lookup code at initialization. - * The idea is that swig generates all the structures that are needed. - * The runtime then collects these partially filled structures. - * The SWIG_InitializeModule function takes these initial arrays out of - * swig_module, and does all the lookup, filling in the swig_module.types - * array with the correct data and linking the correct swig_cast_info - * structures together. - * - * The generated swig_type_info structures are assigned statically to an initial - * array. We just loop through that array, and handle each type individually. - * First we lookup if this type has been already loaded, and if so, use the - * loaded structure instead of the generated one. Then we have to fill in the - * cast linked list. The cast data is initially stored in something like a - * two-dimensional array. Each row corresponds to a type (there are the same - * number of rows as there are in the swig_type_initial array). Each entry in - * a column is one of the swig_cast_info structures for that type. - * The cast_initial array is actually an array of arrays, because each row has - * a variable number of columns. So to actually build the cast linked list, - * we find the array of casts associated with the type, and loop through it - * adding the casts to the list. The one last trick we need to do is making - * sure the type pointer in the swig_cast_info struct is correct. - * - * First off, we lookup the cast->type name to see if it is already loaded. - * There are three cases to handle: - * 1) If the cast->type has already been loaded AND the type we are adding - * casting info to has not been loaded (it is in this module), THEN we - * replace the cast->type pointer with the type pointer that has already - * been loaded. - * 2) If BOTH types (the one we are adding casting info to, and the - * cast->type) are loaded, THEN the cast info has already been loaded by - * the previous module so we just ignore it. - * 3) Finally, if cast->type has not already been loaded, then we add that - * swig_cast_info to the linked list (because the cast->type) pointer will - * be correct. - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* c-mode */ -#endif -#endif - -#if 0 -#define SWIGRUNTIME_DEBUG -#endif - -#ifndef SWIG_INIT_CLIENT_DATA_TYPE -#define SWIG_INIT_CLIENT_DATA_TYPE void * -#endif - -SWIGRUNTIME void -SWIG_InitializeModule(SWIG_INIT_CLIENT_DATA_TYPE clientdata) { - size_t i; - swig_module_info *module_head, *iter; - int init; - - /* check to see if the circular list has been setup, if not, set it up */ - if (swig_module.next==0) { - /* Initialize the swig_module */ - swig_module.type_initial = swig_type_initial; - swig_module.cast_initial = swig_cast_initial; - swig_module.next = &swig_module; - init = 1; - } else { - init = 0; - } - - /* Try and load any already created modules */ - module_head = SWIG_GetModule(clientdata); - if (!module_head) { - /* This is the first module loaded for this interpreter */ - /* so set the swig module into the interpreter */ - SWIG_SetModule(clientdata, &swig_module); - } else { - /* the interpreter has loaded a SWIG module, but has it loaded this one? */ - iter=module_head; - do { - if (iter==&swig_module) { - /* Our module is already in the list, so there's nothing more to do. */ - return; - } - iter=iter->next; - } while (iter!= module_head); - - /* otherwise we must add our module into the list */ - swig_module.next = module_head->next; - module_head->next = &swig_module; - } - - /* When multiple interpreters are used, a module could have already been initialized in - a different interpreter, but not yet have a pointer in this interpreter. - In this case, we do not want to continue adding types... everything should be - set up already */ - if (init == 0) return; - - /* Now work on filling in swig_module.types */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: size %lu\n", (unsigned long)swig_module.size); -#endif - for (i = 0; i < swig_module.size; ++i) { - swig_type_info *type = 0; - swig_type_info *ret; - swig_cast_info *cast; - -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: type %lu %s\n", (unsigned long)i, swig_module.type_initial[i]->name); -#endif - - /* if there is another module already loaded */ - if (swig_module.next != &swig_module) { - type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); - } - if (type) { - /* Overwrite clientdata field */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found type %s\n", type->name); -#endif - if (swig_module.type_initial[i]->clientdata) { - type->clientdata = swig_module.type_initial[i]->clientdata; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); -#endif - } - } else { - type = swig_module.type_initial[i]; - } - - /* Insert casting types */ - cast = swig_module.cast_initial[i]; - while (cast->type) { - - /* Don't need to add information already in the list */ - ret = 0; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); -#endif - if (swig_module.next != &swig_module) { - ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); -#ifdef SWIGRUNTIME_DEBUG - if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); -#endif - } - if (ret) { - if (type == swig_module.type_initial[i]) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: skip old type %s\n", ret->name); -#endif - cast->type = ret; - ret = 0; - } else { - /* Check for casting already in the list */ - swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); -#ifdef SWIGRUNTIME_DEBUG - if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); -#endif - if (!ocast) ret = 0; - } - } - - if (!ret) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); -#endif - if (type->cast) { - type->cast->prev = cast; - cast->next = type->cast; - } - type->cast = cast; - } - cast++; - } - /* Set entry in modules->types array equal to the type */ - swig_module.types[i] = type; - } - swig_module.types[i] = 0; - -#ifdef SWIGRUNTIME_DEBUG - printf("**** SWIG_InitializeModule: Cast List ******\n"); - for (i = 0; i < swig_module.size; ++i) { - int j = 0; - swig_cast_info *cast = swig_module.cast_initial[i]; - printf("SWIG_InitializeModule: type %lu %s\n", (unsigned long)i, swig_module.type_initial[i]->name); - while (cast->type) { - printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); - cast++; - ++j; - } - printf("---- Total casts: %d\n",j); - } - printf("**** SWIG_InitializeModule: Cast List ******\n"); -#endif -} - -/* This function will propagate the clientdata field of type to -* any new swig_type_info structures that have been added into the list -* of equivalent types. It is like calling -* SWIG_TypeClientData(type, clientdata) a second time. -*/ -SWIGRUNTIME void -SWIG_PropagateClientData(void) { - size_t i; - swig_cast_info *equiv; - static int init_run = 0; - - if (init_run) return; - init_run = 1; - - for (i = 0; i < swig_module.size; i++) { - if (swig_module.types[i]->clientdata) { - equiv = swig_module.types[i]->cast; - while (equiv) { - if (!equiv->converter) { - if (equiv->type && !equiv->type->clientdata) - SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); - } - equiv = equiv->next; - } - } - } -} - -#ifdef __cplusplus -#if 0 -{ /* c-mode */ -#endif -} -#endif diff --git a/contrib/tools/swig/Lib/swiglabels.swg b/contrib/tools/swig/Lib/swiglabels.swg deleted file mode 100644 index b3855665e2c..00000000000 --- a/contrib/tools/swig/Lib/swiglabels.swg +++ /dev/null @@ -1,123 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This section contains generic SWIG labels for method/variable - * declarations/attributes, and other compiler dependent labels. - * ----------------------------------------------------------------------------- */ - -/* template workaround for compilers that cannot correctly implement the C++ standard */ -#ifndef SWIGTEMPLATEDISAMBIGUATOR -# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# elif defined(__HP_aCC) -/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ -/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -#endif - -/* inline attribute */ -#ifndef SWIGINLINE -# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -# else -# define SWIGINLINE -# endif -#endif - -/* attribute recognised by some compilers to avoid 'unused' warnings */ -#ifndef SWIGUNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIG_MSC_UNSUPPRESS_4505 -# if defined(_MSC_VER) -# pragma warning(disable : 4505) /* unreferenced local function has been removed */ -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* exporting methods */ -#if defined(__GNUC__) -# if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - -/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ -#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) -# define _SCL_SECURE_NO_DEPRECATE -#endif - -/* Deal with Apple's deprecated 'AssertMacros.h' from Carbon-framework */ -#if defined(__APPLE__) && !defined(__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES) -# define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0 -#endif - -/* Intel's compiler complains if a variable which was never initialised is - * cast to void, which is a common idiom which we use to indicate that we - * are aware a variable isn't used. So we just silence that warning. - * See: https://github.com/swig/swig/issues/192 for more discussion. - */ -#ifdef __INTEL_COMPILER -# pragma warning disable 592 -#endif diff --git a/contrib/tools/swig/Lib/swigrun.swg b/contrib/tools/swig/Lib/swigrun.swg deleted file mode 100644 index f632c4cb6d8..00000000000 --- a/contrib/tools/swig/Lib/swigrun.swg +++ /dev/null @@ -1,581 +0,0 @@ -/* ----------------------------------------------------------------------------- - * swigrun.swg - * - * This file contains generic C API SWIG runtime support for pointer - * type checking. - * ----------------------------------------------------------------------------- */ - -/* This should only be incremented when either the layout of swig_type_info changes, - or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "4" - -/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ -#ifdef SWIG_TYPE_TABLE -# define SWIG_QUOTE_STRING(x) #x -# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) -# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) -#else -# define SWIG_TYPE_TABLE_NAME -#endif - -/* - You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for - creating a static or dynamic library from the SWIG runtime code. - In 99.9% of the cases, SWIG just needs to declare them as 'static'. - - But only do this if strictly necessary, ie, if you have problems - with your compiler or suchlike. -*/ - -#ifndef SWIGRUNTIME -# define SWIGRUNTIME SWIGINTERN -#endif - -#ifndef SWIGRUNTIMEINLINE -# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE -#endif - -/* Generic buffer size */ -#ifndef SWIG_BUFFER_SIZE -# define SWIG_BUFFER_SIZE 1024 -#endif - -/* Flags for pointer conversions */ -#define SWIG_POINTER_DISOWN 0x1 -#define SWIG_CAST_NEW_MEMORY 0x2 -#define SWIG_POINTER_NO_NULL 0x4 -#define SWIG_POINTER_CLEAR 0x8 -#define SWIG_POINTER_RELEASE (SWIG_POINTER_CLEAR | SWIG_POINTER_DISOWN) - -/* Flags for new pointer objects */ -#define SWIG_POINTER_OWN 0x1 - - -/* - Flags/methods for returning states. - - The SWIG conversion methods, as ConvertPtr, return an integer - that tells if the conversion was successful or not. And if not, - an error code can be returned (see swigerrors.swg for the codes). - - Use the following macros/flags to set or process the returning - states. - - In old versions of SWIG, code such as the following was usually written: - - if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { - // success code - } else { - //fail code - } - - Now you can be more explicit: - - int res = SWIG_ConvertPtr(obj,vptr,ty.flags); - if (SWIG_IsOK(res)) { - // success code - } else { - // fail code - } - - which is the same really, but now you can also do - - Type *ptr; - int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); - if (SWIG_IsOK(res)) { - // success code - if (SWIG_IsNewObj(res) { - ... - delete *ptr; - } else { - ... - } - } else { - // fail code - } - - I.e., now SWIG_ConvertPtr can return new objects and you can - identify the case and take care of the deallocation. Of course that - also requires SWIG_ConvertPtr to return new result values, such as - - int SWIG_ConvertPtr(obj, ptr,...) { - if (<obj is ok>) { - if (<need new object>) { - *ptr = <ptr to new allocated object>; - return SWIG_NEWOBJ; - } else { - *ptr = <ptr to old object>; - return SWIG_OLDOBJ; - } - } else { - return SWIG_BADOBJ; - } - } - - Of course, returning the plain '0(success)/-1(fail)' still works, but you can be - more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the - SWIG errors code. - - Finally, if the SWIG_CASTRANK_MODE is enabled, the result code - allows returning the 'cast rank', for example, if you have this - - int food(double) - int fooi(int); - - and you call - - food(1) // cast rank '1' (1 -> 1.0) - fooi(1) // cast rank '0' - - just use the SWIG_AddCast()/SWIG_CheckState() -*/ - -#define SWIG_OK (0) -/* Runtime errors are < 0 */ -#define SWIG_ERROR (-1) -/* Errors in range -1 to -99 are in swigerrors.swg (errors for all languages including those not using the runtime) */ -/* Errors in range -100 to -199 are language specific errors defined in *errors.swg */ -/* Errors < -200 are generic runtime specific errors */ -#define SWIG_ERROR_RELEASE_NOT_OWNED (-200) - -#define SWIG_IsOK(r) (r >= 0) -#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) - -/* The CastRankLimit says how many bits are used for the cast rank */ -#define SWIG_CASTRANKLIMIT (1 << 8) -/* The NewMask denotes the object was created (using new/malloc) */ -#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) -/* The TmpMask is for in/out typemaps that use temporal objects */ -#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) -/* Simple returning values */ -#define SWIG_BADOBJ (SWIG_ERROR) -#define SWIG_OLDOBJ (SWIG_OK) -#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) -#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) -/* Check, add and del object mask methods */ -#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) -#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) -#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) -#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) -#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) -#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) - -/* Cast-Rank Mode */ -#if defined(SWIG_CASTRANK_MODE) -# ifndef SWIG_TypeRank -# define SWIG_TypeRank unsigned long -# endif -# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ -# define SWIG_MAXCASTRANK (2) -# endif -# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) -# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) -SWIGINTERNINLINE int SWIG_AddCast(int r) { - return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; -} -SWIGINTERNINLINE int SWIG_CheckState(int r) { - return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; -} -#else /* no cast-rank mode */ -# define SWIG_AddCast(r) (r) -# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) -#endif - - -#include <string.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *(*swig_converter_func)(void *, int *); -typedef struct swig_type_info *(*swig_dycast_func)(void **); - -/* Structure to store information on one type */ -typedef struct swig_type_info { - const char *name; /* mangled name of this type */ - const char *str; /* human readable name of this type */ - swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ - struct swig_cast_info *cast; /* linked list of types that can cast into this type */ - void *clientdata; /* language specific type data */ - int owndata; /* flag if the structure owns the clientdata */ -} swig_type_info; - -/* Structure to store a type and conversion function used for casting */ -typedef struct swig_cast_info { - swig_type_info *type; /* pointer to type that is equivalent to this type */ - swig_converter_func converter; /* function to cast the void pointers */ - struct swig_cast_info *next; /* pointer to next cast in linked list */ - struct swig_cast_info *prev; /* pointer to the previous cast */ -} swig_cast_info; - -/* Structure used to store module information - * Each module generates one structure like this, and the runtime collects - * all of these structures and stores them in a circularly linked list.*/ -typedef struct swig_module_info { - swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ - size_t size; /* Number of types in this module */ - struct swig_module_info *next; /* Pointer to next element in circularly linked list */ - swig_type_info **type_initial; /* Array of initially generated type structures */ - swig_cast_info **cast_initial; /* Array of initially generated casting structures */ - void *clientdata; /* Language specific module data */ -} swig_module_info; - -/* - Compare two type names skipping the space characters, therefore - "char*" == "char *" and "Class<int>" == "Class<int >", etc. - - Return 0 when the two name types are equivalent, as in - strncmp, but skipping ' '. -*/ -SWIGRUNTIME int -SWIG_TypeNameComp(const char *f1, const char *l1, - const char *f2, const char *l2) { - for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { - while ((*f1 == ' ') && (f1 != l1)) ++f1; - while ((*f2 == ' ') && (f2 != l2)) ++f2; - if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; - } - return (int)((l1 - f1) - (l2 - f2)); -} - -/* - Check type equivalence in a name list like <name1>|<name2>|... - Return 0 if equal, -1 if nb < tb, 1 if nb > tb -*/ -SWIGRUNTIME int -SWIG_TypeCmp(const char *nb, const char *tb) { - int equiv = 1; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (equiv != 0 && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = SWIG_TypeNameComp(nb, ne, tb, te); - if (*ne) ++ne; - } - return equiv; -} - -/* - Check type equivalence in a name list like <name1>|<name2>|... - Return 0 if not equal, 1 if equal -*/ -SWIGRUNTIME int -SWIG_TypeEquiv(const char *nb, const char *tb) { - return SWIG_TypeCmp(nb, tb) == 0 ? 1 : 0; -} - -/* - Check the typename -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheck(const char *c, swig_type_info *ty) { - if (ty) { - swig_cast_info *iter = ty->cast; - while (iter) { - if (strcmp(iter->type->name, c) == 0) { - if (iter == ty->cast) - return iter; - /* Move iter to the top of the linked list */ - iter->prev->next = iter->next; - if (iter->next) - iter->next->prev = iter->prev; - iter->next = ty->cast; - iter->prev = 0; - if (ty->cast) ty->cast->prev = iter; - ty->cast = iter; - return iter; - } - iter = iter->next; - } - } - return 0; -} - -/* - Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheckStruct(const swig_type_info *from, swig_type_info *ty) { - if (ty) { - swig_cast_info *iter = ty->cast; - while (iter) { - if (iter->type == from) { - if (iter == ty->cast) - return iter; - /* Move iter to the top of the linked list */ - iter->prev->next = iter->next; - if (iter->next) - iter->next->prev = iter->prev; - iter->next = ty->cast; - iter->prev = 0; - if (ty->cast) ty->cast->prev = iter; - ty->cast = iter; - return iter; - } - iter = iter->next; - } - } - return 0; -} - -/* - Cast a pointer up an inheritance hierarchy -*/ -SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); -} - -/* - Dynamic pointer casting. Down an inheritance hierarchy -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { - swig_type_info *lastty = ty; - if (!ty || !ty->dcast) return ty; - while (ty && (ty->dcast)) { - ty = (*ty->dcast)(ptr); - if (ty) lastty = ty; - } - return lastty; -} - -/* - Return the name associated with this type -*/ -SWIGRUNTIMEINLINE const char * -SWIG_TypeName(const swig_type_info *ty) { - return ty->name; -} - -/* - Return the pretty name associated with this type, - that is an unmangled type name in a form presentable to the user. -*/ -SWIGRUNTIME const char * -SWIG_TypePrettyName(const swig_type_info *type) { - /* The "str" field contains the equivalent pretty names of the - type, separated by vertical-bar characters. Choose the last - name. It should be the most specific; a fully resolved name - but not necessarily with default template parameters expanded. */ - if (!type) return NULL; - if (type->str != NULL) { - const char *last_name = type->str; - const char *s; - for (s = type->str; *s; s++) - if (*s == '|') last_name = s+1; - return last_name; - } - else - return type->name; -} - -/* - Set the clientdata field for a type -*/ -SWIGRUNTIME void -SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { - swig_cast_info *cast = ti->cast; - /* if (ti->clientdata == clientdata) return; */ - ti->clientdata = clientdata; - - while (cast) { - if (!cast->converter) { - swig_type_info *tc = cast->type; - if (!tc->clientdata) { - SWIG_TypeClientData(tc, clientdata); - } - } - cast = cast->next; - } -} -SWIGRUNTIME void -SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { - SWIG_TypeClientData(ti, clientdata); - ti->owndata = 1; -} - -/* - Search for a swig_type_info structure only by mangled name - Search is a O(log #types) - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_MangledTypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - swig_module_info *iter = start; - do { - if (iter->size) { - size_t l = 0; - size_t r = iter->size - 1; - do { - /* since l+r >= 0, we can (>> 1) instead (/ 2) */ - size_t i = (l + r) >> 1; - const char *iname = iter->types[i]->name; - if (iname) { - int compare = strcmp(name, iname); - if (compare == 0) { - return iter->types[i]; - } else if (compare < 0) { - if (i) { - r = i - 1; - } else { - break; - } - } else if (compare > 0) { - l = i + 1; - } - } else { - break; /* should never happen */ - } - } while (l <= r); - } - iter = iter->next; - } while (iter != end); - return 0; -} - -/* - Search for a swig_type_info structure for either a mangled name or a human readable name. - It first searches the mangled names of the types, which is a O(log #types) - If a type is not found it then searches the human readable names, which is O(#types). - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - /* STEP 1: Search the name field using binary search */ - swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); - if (ret) { - return ret; - } else { - /* STEP 2: If the type hasn't been found, do a complete search - of the str field (the human readable name) */ - swig_module_info *iter = start; - do { - size_t i = 0; - for (; i < iter->size; ++i) { - if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) - return iter->types[i]; - } - iter = iter->next; - } while (iter != end); - } - - /* neither found a match */ - return 0; -} - -/* - Pack binary data into a string -*/ -SWIGRUNTIME char * -SWIG_PackData(char *c, void *ptr, size_t sz) { - static const char hex[17] = "0123456789abcdef"; - const unsigned char *u = (unsigned char *) ptr; - const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - unsigned char uu = *u; - *(c++) = hex[(uu & 0xf0) >> 4]; - *(c++) = hex[uu & 0xf]; - } - return c; -} - -/* - Unpack binary data from a string -*/ -SWIGRUNTIME const char * -SWIG_UnpackData(const char *c, void *ptr, size_t sz) { - unsigned char *u = (unsigned char *) ptr; - const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - char d = *(c++); - unsigned char uu; - if ((d >= '0') && (d <= '9')) - uu = (unsigned char)((d - '0') << 4); - else if ((d >= 'a') && (d <= 'f')) - uu = (unsigned char)((d - ('a'-10)) << 4); - else - return (char *) 0; - d = *(c++); - if ((d >= '0') && (d <= '9')) - uu |= (unsigned char)(d - '0'); - else if ((d >= 'a') && (d <= 'f')) - uu |= (unsigned char)(d - ('a'-10)); - else - return (char *) 0; - *u = uu; - } - return c; -} - -/* - Pack 'void *' into a string buffer. -*/ -SWIGRUNTIME char * -SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { - char *r = buff; - if ((2*sizeof(void *) + 2) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,&ptr,sizeof(void *)); - if (strlen(name) + 1 > (bsz - (r - buff))) return 0; - strcpy(r,name); - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - *ptr = (void *) 0; - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sizeof(void *)); -} - -SWIGRUNTIME char * -SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { - char *r = buff; - size_t lname = (name ? strlen(name) : 0); - if ((2*sz + 2 + lname) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,ptr,sz); - if (lname) { - strncpy(r,name,lname+1); - } else { - *r = 0; - } - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - memset(ptr,0,sz); - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sz); -} - -#ifdef __cplusplus -} -#endif diff --git a/contrib/tools/swig/Lib/swigwarn.swg b/contrib/tools/swig/Lib/swigwarn.swg deleted file mode 100644 index 6a069220ef7..00000000000 --- a/contrib/tools/swig/Lib/swigwarn.swg +++ /dev/null @@ -1,300 +0,0 @@ -/* SWIG warning codes - generated from swigwarn.h - do not edit */ - - -%define SWIGWARN_NONE 0 %enddef - -/* -- Deprecated features -- */ - -%define SWIGWARN_DEPRECATED_EXTERN 101 %enddef -%define SWIGWARN_DEPRECATED_VAL 102 %enddef -%define SWIGWARN_DEPRECATED_OUT 103 %enddef -%define SWIGWARN_DEPRECATED_DISABLEDOC 104 %enddef -%define SWIGWARN_DEPRECATED_ENABLEDOC 105 %enddef -%define SWIGWARN_DEPRECATED_DOCONLY 106 %enddef -%define SWIGWARN_DEPRECATED_STYLE 107 %enddef -%define SWIGWARN_DEPRECATED_LOCALSTYLE 108 %enddef -%define SWIGWARN_DEPRECATED_TITLE 109 %enddef -%define SWIGWARN_DEPRECATED_SECTION 110 %enddef -%define SWIGWARN_DEPRECATED_SUBSECTION 111 %enddef -%define SWIGWARN_DEPRECATED_SUBSUBSECTION 112 %enddef -%define SWIGWARN_DEPRECATED_ADDMETHODS 113 %enddef -%define SWIGWARN_DEPRECATED_READONLY 114 %enddef -%define SWIGWARN_DEPRECATED_READWRITE 115 %enddef -%define SWIGWARN_DEPRECATED_EXCEPT 116 %enddef -%define SWIGWARN_DEPRECATED_NEW 117 %enddef -%define SWIGWARN_DEPRECATED_EXCEPT_TM 118 %enddef -%define SWIGWARN_DEPRECATED_IGNORE_TM 119 %enddef -%define SWIGWARN_DEPRECATED_OPTC 120 %enddef -%define SWIGWARN_DEPRECATED_NAME 121 %enddef -%define SWIGWARN_DEPRECATED_NOEXTERN 122 %enddef -%define SWIGWARN_DEPRECATED_NODEFAULT 123 %enddef -/* Unused since 4.1.0: #define WARN_DEPRECATED_TYPEMAP_LANG 124 */ -%define SWIGWARN_DEPRECATED_INPUT_FILE 125 %enddef -%define SWIGWARN_DEPRECATED_NESTED_WORKAROUND 126 %enddef - -/* -- Preprocessor -- */ - -%define SWIGWARN_PP_MISSING_FILE 201 %enddef -%define SWIGWARN_PP_EVALUATION 202 %enddef -%define SWIGWARN_PP_INCLUDEALL_IMPORTALL 203 %enddef -%define SWIGWARN_PP_CPP_WARNING 204 %enddef -%define SWIGWARN_PP_CPP_ERROR 205 %enddef -%define SWIGWARN_PP_UNEXPECTED_TOKENS 206 %enddef - -/* -- C/C++ Parser -- */ - -%define SWIGWARN_PARSE_CLASS_KEYWORD 301 %enddef -%define SWIGWARN_PARSE_REDEFINED 302 %enddef -%define SWIGWARN_PARSE_EXTEND_UNDEF 303 %enddef -%define SWIGWARN_PARSE_UNSUPPORTED_VALUE 304 %enddef -%define SWIGWARN_PARSE_BAD_VALUE 305 %enddef -%define SWIGWARN_PARSE_PRIVATE 306 %enddef -%define SWIGWARN_PARSE_BAD_DEFAULT 307 %enddef -%define SWIGWARN_PARSE_NAMESPACE_ALIAS 308 %enddef -%define SWIGWARN_PARSE_PRIVATE_INHERIT 309 %enddef -%define SWIGWARN_PARSE_TEMPLATE_REPEAT 310 %enddef -%define SWIGWARN_PARSE_TEMPLATE_PARTIAL 311 %enddef -%define SWIGWARN_PARSE_UNNAMED_NESTED_CLASS 312 %enddef -%define SWIGWARN_PARSE_UNDEFINED_EXTERN 313 %enddef -%define SWIGWARN_PARSE_KEYWORD 314 %enddef -%define SWIGWARN_PARSE_USING_UNDEF 315 %enddef -%define SWIGWARN_PARSE_MODULE_REPEAT 316 %enddef -%define SWIGWARN_PARSE_TEMPLATE_SP_UNDEF 317 %enddef -%define SWIGWARN_PARSE_TEMPLATE_AMBIG 318 %enddef -%define SWIGWARN_PARSE_NO_ACCESS 319 %enddef -%define SWIGWARN_PARSE_EXPLICIT_TEMPLATE 320 %enddef -%define SWIGWARN_PARSE_BUILTIN_NAME 321 %enddef -%define SWIGWARN_PARSE_REDUNDANT 322 %enddef -%define SWIGWARN_PARSE_REC_INHERITANCE 323 %enddef -%define SWIGWARN_PARSE_NESTED_TEMPLATE 324 %enddef -%define SWIGWARN_PARSE_NAMED_NESTED_CLASS 325 %enddef -%define SWIGWARN_PARSE_EXTEND_NAME 326 %enddef -%define SWIGWARN_PARSE_EXTERN_TEMPLATE 327 %enddef - -%define SWIGWARN_CPP11_LAMBDA 340 %enddef -%define SWIGWARN_CPP11_ALIAS_DECLARATION 341 %enddef /* redundant now */ -%define SWIGWARN_CPP11_ALIAS_TEMPLATE 342 %enddef /* redundant now */ -%define SWIGWARN_CPP11_VARIADIC_TEMPLATE 343 %enddef - -%define SWIGWARN_IGNORE_OPERATOR_NEW 350 %enddef /* new */ -%define SWIGWARN_IGNORE_OPERATOR_DELETE 351 %enddef /* delete */ -%define SWIGWARN_IGNORE_OPERATOR_PLUS 352 %enddef /* + */ -%define SWIGWARN_IGNORE_OPERATOR_MINUS 353 %enddef /* - */ -%define SWIGWARN_IGNORE_OPERATOR_MUL 354 %enddef /* * */ -%define SWIGWARN_IGNORE_OPERATOR_DIV 355 %enddef /* / */ -%define SWIGWARN_IGNORE_OPERATOR_MOD 356 %enddef /* % */ -%define SWIGWARN_IGNORE_OPERATOR_XOR 357 %enddef /* ^ */ -%define SWIGWARN_IGNORE_OPERATOR_AND 358 %enddef /* & */ -%define SWIGWARN_IGNORE_OPERATOR_OR 359 %enddef /* | */ -%define SWIGWARN_IGNORE_OPERATOR_NOT 360 %enddef /* ~ */ -%define SWIGWARN_IGNORE_OPERATOR_LNOT 361 %enddef /* ! */ -%define SWIGWARN_IGNORE_OPERATOR_EQ 362 %enddef /* = */ -%define SWIGWARN_IGNORE_OPERATOR_LT 363 %enddef /* < */ -%define SWIGWARN_IGNORE_OPERATOR_GT 364 %enddef /* > */ -%define SWIGWARN_IGNORE_OPERATOR_PLUSEQ 365 %enddef /* += */ -%define SWIGWARN_IGNORE_OPERATOR_MINUSEQ 366 %enddef /* -= */ -%define SWIGWARN_IGNORE_OPERATOR_MULEQ 367 %enddef /* *= */ -%define SWIGWARN_IGNORE_OPERATOR_DIVEQ 368 %enddef /* /= */ -%define SWIGWARN_IGNORE_OPERATOR_MODEQ 369 %enddef /* %= */ -%define SWIGWARN_IGNORE_OPERATOR_XOREQ 370 %enddef /* ^= */ -%define SWIGWARN_IGNORE_OPERATOR_ANDEQ 371 %enddef /* &= */ -%define SWIGWARN_IGNORE_OPERATOR_OREQ 372 %enddef /* |= */ -%define SWIGWARN_IGNORE_OPERATOR_LSHIFT 373 %enddef /* << */ -%define SWIGWARN_IGNORE_OPERATOR_RSHIFT 374 %enddef /* >> */ -%define SWIGWARN_IGNORE_OPERATOR_LSHIFTEQ 375 %enddef /* <<= */ -%define SWIGWARN_IGNORE_OPERATOR_RSHIFTEQ 376 %enddef /* >>= */ -%define SWIGWARN_IGNORE_OPERATOR_EQUALTO 377 %enddef /* == */ -%define SWIGWARN_IGNORE_OPERATOR_NOTEQUAL 378 %enddef /* != */ -%define SWIGWARN_IGNORE_OPERATOR_LTEQUAL 379 %enddef /* <= */ -%define SWIGWARN_IGNORE_OPERATOR_GTEQUAL 380 %enddef /* >= */ -%define SWIGWARN_IGNORE_OPERATOR_LAND 381 %enddef /* && */ -%define SWIGWARN_IGNORE_OPERATOR_LOR 382 %enddef /* || */ -%define SWIGWARN_IGNORE_OPERATOR_PLUSPLUS 383 %enddef /* ++ */ -%define SWIGWARN_IGNORE_OPERATOR_MINUSMINUS 384 %enddef /* -- */ -%define SWIGWARN_IGNORE_OPERATOR_COMMA 385 %enddef /* , */ -%define SWIGWARN_IGNORE_OPERATOR_ARROWSTAR 386 %enddef /* ->* */ -%define SWIGWARN_IGNORE_OPERATOR_ARROW 387 %enddef /* -> */ -%define SWIGWARN_IGNORE_OPERATOR_CALL 388 %enddef /* () */ -%define SWIGWARN_IGNORE_OPERATOR_INDEX 389 %enddef /* [] */ -%define SWIGWARN_IGNORE_OPERATOR_UPLUS 390 %enddef /* + */ -%define SWIGWARN_IGNORE_OPERATOR_UMINUS 391 %enddef /* - */ -%define SWIGWARN_IGNORE_OPERATOR_UMUL 392 %enddef /* * */ -%define SWIGWARN_IGNORE_OPERATOR_UAND 393 %enddef /* & */ -%define SWIGWARN_IGNORE_OPERATOR_NEWARR 394 %enddef /* new [] */ -%define SWIGWARN_IGNORE_OPERATOR_DELARR 395 %enddef /* delete [] */ -%define SWIGWARN_IGNORE_OPERATOR_REF 396 %enddef /* operator *() */ -%define SWIGWARN_IGNORE_OPERATOR_LTEQUALGT 397 %enddef /* <=> */ - -/* please leave 350-399 free for WARN_IGNORE_OPERATOR_* */ - -/* -- Type system and typemaps -- */ - -%define SWIGWARN_TYPE_UNDEFINED_CLASS 401 %enddef -%define SWIGWARN_TYPE_INCOMPLETE 402 %enddef -%define SWIGWARN_TYPE_ABSTRACT 403 %enddef -%define SWIGWARN_TYPE_REDEFINED 404 %enddef -%define SWIGWARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405 %enddef - -%define SWIGWARN_TYPEMAP_SOURCETARGET 450 %enddef /* No longer issued */ -%define SWIGWARN_TYPEMAP_CHARLEAK 451 %enddef -%define SWIGWARN_TYPEMAP_SWIGTYPE 452 %enddef /* No longer issued */ -%define SWIGWARN_TYPEMAP_APPLY_UNDEF 453 %enddef -%define SWIGWARN_TYPEMAP_SWIGTYPELEAK 454 %enddef -%define SWIGWARN_TYPEMAP_WCHARLEAK 455 %enddef - -%define SWIGWARN_TYPEMAP_IN_UNDEF 460 %enddef -%define SWIGWARN_TYPEMAP_OUT_UNDEF 461 %enddef -%define SWIGWARN_TYPEMAP_VARIN_UNDEF 462 %enddef -%define SWIGWARN_TYPEMAP_VAROUT_UNDEF 463 %enddef -%define SWIGWARN_TYPEMAP_CONST_UNDEF 464 %enddef -%define SWIGWARN_TYPEMAP_UNDEF 465 %enddef -%define SWIGWARN_TYPEMAP_VAR_UNDEF 466 %enddef -%define SWIGWARN_TYPEMAP_TYPECHECK 467 %enddef -%define SWIGWARN_TYPEMAP_THROW 468 %enddef -%define SWIGWARN_TYPEMAP_DIRECTORIN_UNDEF 469 %enddef -%define SWIGWARN_TYPEMAP_THREAD_UNSAFE 470 %enddef /* mostly used in directorout typemaps */ -%define SWIGWARN_TYPEMAP_DIRECTOROUT_UNDEF 471 %enddef -%define SWIGWARN_TYPEMAP_TYPECHECK_UNDEF 472 %enddef -%define SWIGWARN_TYPEMAP_DIRECTOROUT_PTR 473 %enddef -%define SWIGWARN_TYPEMAP_OUT_OPTIMAL_IGNORED 474 %enddef -%define SWIGWARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE 475 %enddef -%define SWIGWARN_TYPEMAP_INITIALIZER_LIST 476 %enddef -%define SWIGWARN_TYPEMAP_DIRECTORTHROWS_UNDEF 477 %enddef - -/* -- Fragments -- */ -%define SWIGWARN_FRAGMENT_NOT_FOUND 490 %enddef - -/* -- General code generation -- */ - -%define SWIGWARN_LANG_OVERLOAD_DECL 501 %enddef -%define SWIGWARN_LANG_OVERLOAD_CONSTRUCT 502 %enddef -%define SWIGWARN_LANG_IDENTIFIER 503 %enddef -%define SWIGWARN_LANG_RETURN_TYPE 504 %enddef -%define SWIGWARN_LANG_VARARGS 505 %enddef -%define SWIGWARN_LANG_VARARGS_KEYWORD 506 %enddef -%define SWIGWARN_LANG_NATIVE_UNIMPL 507 %enddef -%define SWIGWARN_LANG_DEREF_SHADOW 508 %enddef -%define SWIGWARN_LANG_OVERLOAD_SHADOW 509 %enddef -%define SWIGWARN_LANG_FRIEND_IGNORE 510 %enddef -%define SWIGWARN_LANG_OVERLOAD_KEYWORD 511 %enddef -%define SWIGWARN_LANG_OVERLOAD_CONST 512 %enddef -%define SWIGWARN_LANG_CLASS_UNNAMED 513 %enddef -%define SWIGWARN_LANG_DIRECTOR_VDESTRUCT 514 %enddef -%define SWIGWARN_LANG_DISCARD_CONST 515 %enddef -%define SWIGWARN_LANG_OVERLOAD_IGNORED 516 %enddef -%define SWIGWARN_LANG_DIRECTOR_ABSTRACT 517 %enddef -%define SWIGWARN_LANG_PORTABILITY_FILENAME 518 %enddef -%define SWIGWARN_LANG_TEMPLATE_METHOD_IGNORE 519 %enddef -%define SWIGWARN_LANG_SMARTPTR_MISSING 520 %enddef -%define SWIGWARN_LANG_ILLEGAL_DESTRUCTOR 521 %enddef -%define SWIGWARN_LANG_EXTEND_CONSTRUCTOR 522 %enddef -%define SWIGWARN_LANG_EXTEND_DESTRUCTOR 523 %enddef -%define SWIGWARN_LANG_EXPERIMENTAL 524 %enddef -%define SWIGWARN_LANG_DIRECTOR_FINAL 525 %enddef -%define SWIGWARN_LANG_USING_NAME_DIFFERENT 526 %enddef - -/* -- Doxygen comments -- */ - -%define SWIGWARN_DOXYGEN_UNKNOWN_COMMAND 560 %enddef -%define SWIGWARN_DOXYGEN_UNEXPECTED_END_OF_COMMENT 561 %enddef -%define SWIGWARN_DOXYGEN_COMMAND_EXPECTED 562 %enddef -%define SWIGWARN_DOXYGEN_HTML_ERROR 563 %enddef -%define SWIGWARN_DOXYGEN_COMMAND_ERROR 564 %enddef -%define SWIGWARN_DOXYGEN_UNKNOWN_CHARACTER 565 %enddef -%define SWIGWARN_DOXYGEN_UNEXPECTED_ITERATOR_VALUE 566 %enddef - -/* -- Reserved (600-699) -- */ - -/* -- Language module specific warnings (700 - 899) -- */ - - -%define SWIGWARN_D_TYPEMAP_CTYPE_UNDEF 700 %enddef -%define SWIGWARN_D_TYPEMAP_IMTYPE_UNDEF 701 %enddef -%define SWIGWARN_D_TYPEMAP_DTYPE_UNDEF 702 %enddef -%define SWIGWARN_D_MULTIPLE_INHERITANCE 703 %enddef -%define SWIGWARN_D_TYPEMAP_CLASSMOD_UNDEF 704 %enddef -%define SWIGWARN_D_TYPEMAP_DBODY_UNDEF 705 %enddef -%define SWIGWARN_D_TYPEMAP_DOUT_UNDEF 706 %enddef -%define SWIGWARN_D_TYPEMAP_DIN_UNDEF 707 %enddef -%define SWIGWARN_D_TYPEMAP_DDIRECTORIN_UNDEF 708 %enddef -%define SWIGWARN_D_TYPEMAP_DCONSTRUCTOR_UNDEF 709 %enddef -%define SWIGWARN_D_EXCODE_MISSING 710 %enddef -%define SWIGWARN_D_CANTHROW_MISSING 711 %enddef -%define SWIGWARN_D_NO_DIRECTORCONNECT_ATTR 712 %enddef -%define SWIGWARN_D_NAME_COLLISION 713 %enddef - -/* please leave 700-719 free for D */ - -%define SWIGWARN_SCILAB_TRUNCATED_NAME 720 %enddef - -/* please leave 720-739 free for Scilab */ - -%define SWIGWARN_PYTHON_INDENT_MISMATCH 740 %enddef - -/* please leave 740-749 free for Python */ - -%define SWIGWARN_R_MISSING_RTYPECHECK_TYPEMAP 750 %enddef - -/* please leave 750-759 free for R */ - -%define SWIGWARN_RUBY_WRONG_NAME 801 %enddef -%define SWIGWARN_RUBY_MULTIPLE_INHERITANCE 802 %enddef - -/* please leave 800-809 free for Ruby */ - -%define SWIGWARN_JAVA_TYPEMAP_JNI_UNDEF 810 %enddef -%define SWIGWARN_JAVA_TYPEMAP_JTYPE_UNDEF 811 %enddef -%define SWIGWARN_JAVA_TYPEMAP_JSTYPE_UNDEF 812 %enddef -%define SWIGWARN_JAVA_MULTIPLE_INHERITANCE 813 %enddef -%define SWIGWARN_JAVA_TYPEMAP_GETCPTR_UNDEF 814 %enddef -%define SWIGWARN_JAVA_TYPEMAP_CLASSMOD_UNDEF 815 %enddef -%define SWIGWARN_JAVA_TYPEMAP_JAVABODY_UNDEF 816 %enddef -%define SWIGWARN_JAVA_TYPEMAP_JAVAOUT_UNDEF 817 %enddef -%define SWIGWARN_JAVA_TYPEMAP_JAVAIN_UNDEF 818 %enddef -%define SWIGWARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF 819 %enddef -%define SWIGWARN_JAVA_TYPEMAP_JAVADIRECTOROUT_UNDEF 820 %enddef -%define SWIGWARN_JAVA_TYPEMAP_INTERFACECODE_UNDEF 821 %enddef -%define SWIGWARN_JAVA_COVARIANT_RET 822 %enddef -%define SWIGWARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF 823 %enddef -%define SWIGWARN_JAVA_TYPEMAP_DIRECTORIN_NODESC 824 %enddef -%define SWIGWARN_JAVA_NO_DIRECTORCONNECT_ATTR 825 %enddef -%define SWIGWARN_JAVA_NSPACE_WITHOUT_PACKAGE 826 %enddef -%define SWIGWARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF 827 %enddef - -/* please leave 810-829 free for Java */ - -%define SWIGWARN_CSHARP_TYPEMAP_CTYPE_UNDEF 830 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_CSTYPE_UNDEF 831 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF 832 %enddef -%define SWIGWARN_CSHARP_MULTIPLE_INHERITANCE 833 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_GETCPTR_UNDEF 834 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF 835 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_CSBODY_UNDEF 836 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_CSOUT_UNDEF 837 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_CSIN_UNDEF 838 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF 839 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_CSDIRECTOROUT_UNDEF 840 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_INTERFACECODE_UNDEF 841 %enddef -%define SWIGWARN_CSHARP_COVARIANT_RET 842 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_CSCONSTRUCT_UNDEF 843 %enddef -%define SWIGWARN_CSHARP_EXCODE 844 %enddef -%define SWIGWARN_CSHARP_CANTHROW 845 %enddef -%define SWIGWARN_CSHARP_NO_DIRECTORCONNECT_ATTR 846 %enddef -%define SWIGWARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF 847 %enddef - -/* please leave 830-849 free for C# */ - -/* 850-860 were used by Modula 3 (removed in SWIG 4.1.0) - avoid reusing for now */ - -%define SWIGWARN_PHP_MULTIPLE_INHERITANCE 870 %enddef -%define SWIGWARN_PHP_UNKNOWN_PRAGMA 871 %enddef -%define SWIGWARN_PHP_PUBLIC_BASE 872 %enddef - -/* please leave 870-889 free for PHP */ - -%define SWIGWARN_GO_NAME_CONFLICT 890 %enddef - -/* please leave 890-899 free for Go */ - -/* -- User defined warnings (900 - 999) -- */ - diff --git a/contrib/tools/swig/Lib/swigwarnings.swg b/contrib/tools/swig/Lib/swigwarnings.swg deleted file mode 100644 index 63ae4c65a92..00000000000 --- a/contrib/tools/swig/Lib/swigwarnings.swg +++ /dev/null @@ -1,131 +0,0 @@ -/* - Include the internal swig macro codes. These macros correspond to - the one found in Source/Include/swigwarn.h plus the 'SWIG' prefix. - - For example, in the include file 'swigwarn.h' you will find - - #define WARN_TYPEMAP_CHARLEAK ... - - and in the 'swigwarn.swg' interface, you will see - - %define SWIGWARN_TYPEMAP_CHARLEAK ... - - This code can be used in warning filters as follows: - - %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK); - - Warnings messages used in typemaps. Message names will be the same - as those in Lib/swigwarn.swg but with the suffix _MSG. - - For example, for the code SWIGWARN_TYPEMAP_CHARLEAK, once you use - - %typemapmsg(CHARLEAK,<msg>); - - you use the message in your typemap as - - %typemap(varin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) char * - - while you suppress the warning using - - %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK); - - as described above. -*/ - -/* ----------------------------------------------------------------------------- - * SWIG warning codes - * ----------------------------------------------------------------------------- */ - -%include <swigwarn.swg> - -/* ----------------------------------------------------------------------------- - * Auxiliary macros - * ----------------------------------------------------------------------------- */ - -/* Macro to define warning messages */ -#define %_warningmsg(Val, Msg...) `Val`":"Msg -#define %warningmsg(Val, Msg...) %_warningmsg(Val, Msg) - -/* ----------------------------------------------------------------------------- - * Typemap related warning messages - * ----------------------------------------------------------------------------- */ - -%define SWIGWARN_TYPEMAP_CHARLEAK_MSG "451:Setting a const char * variable may leak memory." %enddef -%define SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG "454:Setting a pointer/reference variable may leak memory." %enddef -%define SWIGWARN_TYPEMAP_WCHARLEAK_MSG "455:Setting a const wchar_t * variable may leak memory." %enddef -%define SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG "470:Thread/reentrant unsafe wrapping, consider returning by value instead." %enddef -%define SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG "473:Returning a pointer or reference in a director method is not recommended." %enddef -%define SWIGWARN_TYPEMAP_INITIALIZER_LIST_MSG "476:Initialization using std::initializer_list." %enddef - -/* ----------------------------------------------------------------------------- - * Operator related warning messages - * ----------------------------------------------------------------------------- */ - -%define SWIGWARN_IGNORE_OPERATOR_NEW_MSG "350:operator new ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_DELETE_MSG "351:operator delete ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_PLUS_MSG "352:operator+ ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_MINUS_MSG "353:operator- ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_MUL_MSG "354:operator* ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_DIV_MSG "355:operator/ ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_MOD_MSG "356:operator% ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_XOR_MSG "357:operator^ ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_AND_MSG "358:operator& ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_OR_MSG "359:operator| ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_NOT_MSG "360:operator~ ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_LNOT_MSG "361:operator! ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_EQ_MSG "362:operator= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_LT_MSG "363:operator< ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_GT_MSG "364:operator> ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_PLUSEQ_MSG "365:operator+= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_MINUSEQ_MSG "366:operator-= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_MULEQ_MSG "367:operator*= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_DIVEQ_MSG "368:operator/= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_MODEQ_MSG "369:operator%= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_XOREQ_MSG "370:operator^= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_ANDEQ_MSG "371:operator&= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_OREQ_MSG "372:operator|= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_LSHIFT_MSG "373:operator<< ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_RSHIFT_MSG "374:operator>> ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_LSHIFTEQ_MSG "375:operator<<= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_RSHIFTEQ_MSG "376:operator>>= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_EQUALTO_MSG "377:operator== ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_NOTEQUAL_MSG "378:operator!= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_LTEQUAL_MSG "379:operator<= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_GTEQUAL_MSG "380:operator>= ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_LAND_MSG "381:operator&& ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_LOR_MSG "382:operator|| ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_PLUSPLUS_MSG "383:operator++ ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_MINUSMINUS_MSG "384:operator-- ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_COMMA_MSG "385:operator-- ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_ARROWSTAR_MSG "386:operator->* ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_ARROW_MSG "387:operator-> ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_CALL_MSG "388:operator() ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_INDEX_MSG "389:operator[] ignored (consider using %%extend)" %enddef -%define SWIGWARN_IGNORE_OPERATOR_UPLUS_MSG "390:operator+ ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_UMINUS_MSG "391:operator- ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_UMUL_MSG "392:operator* ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_UAND_MSG "393:operator& ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_NEWARR_MSG "394:operator new[] ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_DELARR_MSG "395:operator delete[] ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_REF_MSG "396:operator*() ignored" %enddef -%define SWIGWARN_IGNORE_OPERATOR_LTEQUALGT_MSG "397:operator<=> ignored" %enddef - -#define %ignoreoperator(Oper) %ignorewarn(SWIGWARN_IGNORE_OPERATOR_##Oper##_MSG) - -/* ----------------------------------------------------------------------------- - * Macros for keyword and built-in names - * ----------------------------------------------------------------------------- */ - -#define %keywordwarn(msg...) %namewarn(%warningmsg(SWIGWARN_PARSE_KEYWORD, msg)) -#define %builtinwarn(msg...) %namewarn(%warningmsg(SWIGWARN_PARSE_BUILTIN_NAME, msg), %$isfunction) - - -/* ----------------------------------------------------------------------------- - * Warning filter feature - * ----------------------------------------------------------------------------- */ - -#define %_warnfilter(filter...) %feature("warnfilter",`filter`) -#define %warnfilter(filter...) %_warnfilter(filter) - - - diff --git a/contrib/tools/swig/Lib/typemaps/README b/contrib/tools/swig/Lib/typemaps/README deleted file mode 100644 index 65134578d35..00000000000 --- a/contrib/tools/swig/Lib/typemaps/README +++ /dev/null @@ -1,54 +0,0 @@ -Still in development, but if you are interested into looking around, -start with - - - swigtypemaps.swg - -which is the head file. Also read the docs for %fragments in - - fragments.swg - -and follow the definitions in one of the supported languages: - - python, perl, ruby, tcl - - - - -/* ----------------------------------------------------------------------------- - * Internal typemap specializations - * ----------------------------------------------------------------------------- */ - - -carrays.swg Implement the carrays.i library -cdata.swg Implement the cdata.i library -cmalloc.swg Implement the cmalloc.i library -cpointer.swg Implement the cpointer.i library -cstring.swg Implement the cstring.i library typemaps for char * -cwstring.swg Implement the cstring.i library typemaps for wchar_t * -exception.swg Implement the exception.i library -implicit.swg Allow the use of implicit C++ constructors - -string.swg Typemaps for char * string -wstring.swg Typemaps for wchar_t * string -std_string.swg Typemaps for std::string -std_wstring.swg Typemaps for std::wstring -swigtype.swg Typemaps for the SWIGTYPE type -void.swg Typemaps for the 'void' type -enumint.swg Typemaps for enums treated as 'int' -swigobject.swg Typemaps for the SWIG_Object as in PyObject, Tcl_Obj, etc. -misctypes.swg Typemaps for miscellaneos types (size_t, ptrdiff_t, etc) -ptrtypes.swg Typemaps for types with a 'ptr' behavior -valtypes.swg Typemaps for 'by value' types -inoutlist.swg IN/OUTPUT/INOUT typemaps, where the OUTPUT values are returned in a list -primtypes.swg Common macros to manage primitive types (short,int,double,etc) - -cstrings.swg Common macros to implemented the cstring/cwstring libraries -std_strings.swg Common macros to implemented the std::string/std::wstring typemaps -strings.swg Common macros and typemaps for string and wstring (char *, wchar_t *) - -swigmacros.swg Basic macros -fragments.swg Macros for fragment manipulations - - -typemaps.swg The old typemaps.i library, not needed anymore diff --git a/contrib/tools/swig/Lib/typemaps/enumint.swg b/contrib/tools/swig/Lib/typemaps/enumint.swg deleted file mode 100644 index d048bb6bf70..00000000000 --- a/contrib/tools/swig/Lib/typemaps/enumint.swg +++ /dev/null @@ -1,39 +0,0 @@ -/* ------------------------------------------------------------ - * Enums mapped as integer values - * ------------------------------------------------------------ */ - -%apply int { enum SWIGTYPE }; -%apply const int& { const enum SWIGTYPE & }; -%apply const int& { const enum SWIGTYPE && }; - -%typemap(in,fragment=SWIG_AsVal_frag(int),noblock=1) const enum SWIGTYPE & (int val, int ecode, $basetype temp) { - ecode = SWIG_AsVal(int)($input, &val); - if (!SWIG_IsOK(ecode)) { - %argument_fail(ecode, "$type", $symname, $argnum); - } else { - temp = %static_cast(val,$basetype); - $1 = &temp; - } -} - -%typemap(in,fragment=SWIG_AsVal_frag(int),noblock=1) const enum SWIGTYPE && (int val, int ecode, $basetype temp) { - ecode = SWIG_AsVal(int)($input, &val); - if (!SWIG_IsOK(ecode)) { - %argument_fail(ecode, "$type", $symname, $argnum); - } else { - temp = %static_cast(val,$basetype); - $1 = &temp; - } -} - -%typemap(varin,fragment=SWIG_AsVal_frag(int),noblock=1) enum SWIGTYPE { - if (sizeof(int) != sizeof($1)) { - %variable_fail(SWIG_AttributeError,"$type", "arch, read-only $name"); - } else { - int ecode = SWIG_AsVal(int)($input, %reinterpret_cast(&$1,int*)); - if (!SWIG_IsOK(ecode)) { - %variable_fail(ecode, "$type", "$name"); - } - } -} - diff --git a/contrib/tools/swig/Lib/typemaps/exception.swg b/contrib/tools/swig/Lib/typemaps/exception.swg deleted file mode 100644 index aece8326f50..00000000000 --- a/contrib/tools/swig/Lib/typemaps/exception.swg +++ /dev/null @@ -1,87 +0,0 @@ -/* ----------------------------------------------------------------------------- - * exceptions.swg - * - * This SWIG library file provides language independent exception handling - * ----------------------------------------------------------------------------- */ - -%include <typemaps/swigmacros.swg> - - -/* macros for error manipulation */ -#define %nullref_fmt() "invalid null reference " -#define %varfail_fmt(_type,_name) "in variable '"`_name`"' of type '"`_type`"'" -#ifndef %argfail_fmt -#define %argfail_fmt(_type,_name,_argn) "in method '" `_name` "', argument " `_argn`" of type '" `_type`"'" -#endif -#define %outfail_fmt(_type) "in output value of type '"_type"'" -#ifndef %argnullref_fmt -#define %argnullref_fmt(_type,_name,_argn) %nullref_fmt() %argfail_fmt(_type, _name, _argn) -#endif -#define %varnullref_fmt(_type,_name) %nullref_fmt() %varfail_fmt(_type, _name) -#define %outnullref_fmt(_type) %nullref_fmt() %outfail_fmt(_type) -#define %releasenotownedfail_fmt(_type,_name,_argn) "in method '" `_name` "', cannot release ownership as memory is not owned for argument " `_argn`" of type '" `_type`"'" - -/* setting an error */ -#define %error(code,msg...) SWIG_Error(code, msg) -#define %type_error(msg...) SWIG_Error(SWIG_TypeError, msg) - - - -%insert("runtime") { - -%define_as(SWIG_exception_fail(code, msg), %block(%error(code, msg); SWIG_fail)) - -%define_as(SWIG_contract_assert(expr, msg), do { if (!(expr)) { %error(SWIG_RuntimeError, msg); SWIG_fail; } } while (0)) - -} - -#ifdef __cplusplus -/* - You can use the SWIG_CATCH_STDEXCEPT macro with the %exception - directive as follows: - - %exception { - try { - $action - } - catch (my_except& e) { - ... - } - SWIG_CATCH_STDEXCEPT // catch std::exception - catch (...) { - SWIG_exception_fail(SWIG_UnknownError, "Unknown exception"); - } - } -*/ - -%fragment("<stdexcept>"); - -%define SWIG_CATCH_STDEXCEPT - /* catching std::exception */ - catch (std::invalid_argument& e) { - SWIG_exception_fail(SWIG_ValueError, e.what() ); - } catch (std::domain_error& e) { - SWIG_exception_fail(SWIG_ValueError, e.what() ); - } catch (std::overflow_error& e) { - SWIG_exception_fail(SWIG_OverflowError, e.what() ); - } catch (std::out_of_range& e) { - SWIG_exception_fail(SWIG_IndexError, e.what() ); - } catch (std::length_error& e) { - SWIG_exception_fail(SWIG_IndexError, e.what() ); - } catch (std::runtime_error& e) { - SWIG_exception_fail(SWIG_RuntimeError, e.what() ); - } catch (std::exception& e) { - SWIG_exception_fail(SWIG_SystemError, e.what() ); - } -%enddef -%define SWIG_CATCH_UNKNOWN - catch (std::exception& e) { - SWIG_exception_fail(SWIG_SystemError, e.what() ); - } - catch (...) { - SWIG_exception_fail(SWIG_UnknownError, "unknown exception"); - } -%enddef - - -#endif /* __cplusplus */ diff --git a/contrib/tools/swig/Lib/typemaps/fragments.swg b/contrib/tools/swig/Lib/typemaps/fragments.swg deleted file mode 100644 index e76a694eea7..00000000000 --- a/contrib/tools/swig/Lib/typemaps/fragments.swg +++ /dev/null @@ -1,231 +0,0 @@ -/* - Fragments - ========= - See the "Typemap fragments" section in the documentation for understanding - fragments. Below is some info on how fragments and automatic type - specialization is used. - - Macros that make the automatic generation of typemaps easier are provided. - - Consider the following code: - - %fragment(SWIG_From_frag(bool), "header") { - static PyObject* - SWIG_From_dec(bool)(bool value) - { - PyObject *obj = value ? Py_True : Py_False; - Py_INCREF(obj); - return obj; - } - } - - %typemap(out, fragment=SWIG_From_frag(bool)) bool { - $result = SWIG_From(bool)($1)); - } - - Here the macros - - SWIG_From_frag => fragment - SWIG_From_dec => declaration - SWIG_From => call - - allow you to define/include a fragment, and declare and call the - 'from-bool' method as needed. In the simpler case, these macros - just return something like - - SWIG_From_frag(bool) => "SWIG_From_bool" - SWIG_From_dec(bool) => SWIG_From_bool - SWIG_From(bool) => SWIG_From_bool - - But they are specialized for the different languages requirements, - such as perl or tcl that requires passing the interpreter pointer, - and also they can manage C++ ugly types, for example: - - SWIG_From_frag(std::complex<double>) => "SWIG_From_std_complex_Sl_double_Sg_" - SWIG_From_dec(std::complex<double>) => SWIG_From_std_complex_Sl_double_Sg_ - SWIG_From(std::complex<double>) => SWIG_From_std_complex_Sl_double_Sg_ - - - Hence, to declare methods to use with typemaps, always use the - SWIG_From* macros. In the same way, the SWIG_AsVal* and SWIG_AsPtr* - set of macros are provided. - -*/ - - -/* ----------------------------------------------------------------------------- - * Define the basic macros to 'normalize' the type fragments - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_AS_DECL_ARGS -#define SWIG_AS_DECL_ARGS -#endif - -#ifndef SWIG_FROM_DECL_ARGS -#define SWIG_FROM_DECL_ARGS -#endif - -#ifndef SWIG_AS_CALL_ARGS -#define SWIG_AS_CALL_ARGS -#endif - -#ifndef SWIG_FROM_CALL_ARGS -#define SWIG_FROM_CALL_ARGS -#endif - -#define %fragment_name(Name, Type...) %string_name(Name) "_" {Type} - -#define SWIG_Traits_frag(Type...) %fragment_name(Traits, Type) -#define SWIG_AsPtr_frag(Type...) %fragment_name(AsPtr, Type) -#define SWIG_AsVal_frag(Type...) %fragment_name(AsVal, Type) -#define SWIG_From_frag(Type...) %fragment_name(From, Type) - -#define SWIG_AsVal_name(Type...) %symbol_name(AsVal, Type) -#define SWIG_AsPtr_name(Type...) %symbol_name(AsPtr, Type) -#define SWIG_From_name(Type...) %symbol_name(From, Type) - -#define SWIG_AsVal_dec(Type...) SWIG_AsVal_name(Type) SWIG_AS_DECL_ARGS -#define SWIG_AsPtr_dec(Type...) SWIG_AsPtr_name(Type) SWIG_AS_DECL_ARGS -#define SWIG_From_dec(Type...) SWIG_From_name(Type) SWIG_FROM_DECL_ARGS - -#define SWIG_AsVal(Type...) SWIG_AsVal_name(Type) SWIG_AS_CALL_ARGS -#define SWIG_AsPtr(Type...) SWIG_AsPtr_name(Type) SWIG_AS_CALL_ARGS -#define SWIG_From(Type...) SWIG_From_name(Type) SWIG_FROM_CALL_ARGS - -/* ------------------------------------------------------------ - * common fragments - * ------------------------------------------------------------ */ - -%fragment("SWIG_isfinite","header",fragment="<math.h>,<float.h>") %{ -/* Getting isfinite working pre C99 across multiple platforms is non-trivial. Users can provide SWIG_isfinite on older platforms. */ -#ifndef SWIG_isfinite -/* isfinite() is a macro for C99 */ -# if defined(isfinite) -# define SWIG_isfinite(X) (isfinite(X)) -# elif defined(__cplusplus) && __cplusplus >= 201103L -/* Use a template so that this works whether isfinite() is std::isfinite() or - * in the global namespace. The reality seems to vary between compiler - * versions. - * - * Make sure namespace std exists to avoid compiler warnings. - * - * extern "C++" is required as this fragment can end up inside an extern "C" { } block - */ -namespace std { } -extern "C++" template<typename T> -inline int SWIG_isfinite_func(T x) { - using namespace std; - return isfinite(x); -} -# define SWIG_isfinite(X) (SWIG_isfinite_func(X)) -# elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) -# define SWIG_isfinite(X) (__builtin_isfinite(X)) -# elif defined(_MSC_VER) -# define SWIG_isfinite(X) (_finite(X)) -# elif defined(__sun) && defined(__SVR4) -# include <ieeefp.h> -# define SWIG_isfinite(X) (finite(X)) -# endif -#endif -%} - -%fragment("SWIG_Float_Overflow_Check","header",fragment="<float.h>,SWIG_isfinite") %{ -/* Accept infinite as a valid float value unless we are unable to check if a value is finite */ -#ifdef SWIG_isfinite -# define SWIG_Float_Overflow_Check(X) ((X < -FLT_MAX || X > FLT_MAX) && SWIG_isfinite(X)) -#else -# define SWIG_Float_Overflow_Check(X) ((X < -FLT_MAX || X > FLT_MAX)) -#endif -%} - -/* ----------------------------------------------------------------------------- - * special macros for fragments - * ----------------------------------------------------------------------------- */ - -/* Macros to derive numeric types */ - -%define %numeric_type_from(Type, Base) -%fragment(SWIG_From_frag(Type),"header", - fragment=SWIG_From_frag(Base)) { -SWIGINTERNINLINE SWIG_Object -SWIG_From_dec(Type)(Type value) -{ - return SWIG_From(Base)(value); -} -} -%enddef - -%define %numeric_type_asval(Type, Base, Frag, OverflowCond) -%fragment(SWIG_AsVal_frag(Type),"header", - fragment=Frag, - fragment=SWIG_AsVal_frag(Base)) { -SWIGINTERN int -SWIG_AsVal_dec(Type)(SWIG_Object obj, Type *val) -{ - Base v; - int res = SWIG_AsVal(Base)(obj, &v); - if (SWIG_IsOK(res)) { - if (OverflowCond) { - return SWIG_OverflowError; - } else { - if (val) *val = %numeric_cast(v, Type); - } - } - return res; -} -} -%enddef - -#define %numeric_signed_type_asval(Type, Base, Frag, Min, Max) \ -%numeric_type_asval(Type, Base, Frag, (v < Min || v > Max)) - -#define %numeric_unsigned_type_asval(Type, Base, Frag, Max) \ -%numeric_type_asval(Type, Base, Frag, (v > Max)) - - -/* Macro for 'signed long' derived types */ - -%define %numeric_slong(Type, Frag, Min, Max) -%numeric_type_from(Type, long) -%numeric_signed_type_asval(Type, long, Frag , Min, Max) -%enddef - -/* Macro for 'unsigned long' derived types */ - -%define %numeric_ulong(Type, Frag, Max) -%numeric_type_from(Type, unsigned long) -%numeric_unsigned_type_asval(Type, unsigned long, Frag, Max) -%enddef - - -/* Macro for floating point derived types (original macro) */ - -%define %numeric_double(Type, Frag, Min, Max) -%numeric_type_from(Type, double) -%numeric_signed_type_asval(Type, double, Frag , Min, Max) -%enddef - -/* Macro for floating point derived types */ - -%define %numeric_float(Type, Frag, OverflowCond) -%numeric_type_from(Type, double) -%numeric_type_asval(Type, double, Frag, OverflowCond) -%enddef - - -/* Macros for missing fragments */ - -%define %ensure_fragment(Fragment) -%fragment(`Fragment`,"header") { -%#error "SWIG language implementation must provide the Fragment fragment" -} -%enddef - -%define %ensure_type_fragments(Type) -%fragment(SWIG_From_frag(Type),"header") { -%#error "SWIG language implementation must provide a SWIG_From_frag(Type) fragment" -} -%fragment(SWIG_AsVal_frag(Type),"header") { -%#error "SWIG language implementation must provide a SWIG_AsVal_frag(Type) fragment" -} -%enddef diff --git a/contrib/tools/swig/Lib/typemaps/inoutlist.swg b/contrib/tools/swig/Lib/typemaps/inoutlist.swg deleted file mode 100644 index 23fda85f3a8..00000000000 --- a/contrib/tools/swig/Lib/typemaps/inoutlist.swg +++ /dev/null @@ -1,296 +0,0 @@ -/* ------------------------------------------------------------ - * - * Define the IN/OUTPUT typemaps assuming the output parameters are - * returned in a list, i.e., they are not directly modified. - * - * The user should provide the %append_output(result, obj) method, - * via a macro, which append a particular object to the result. - * - * - * In Tcl, for example, the file is used as: - * - * #define %append_output(obj) Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),obj); - * %include <typemaps/inoutlist.swg> - * - * while in Python it is used as: - * - * #define %append_output(obj) $result = SWIG_Python_AppendResult($result, obj) - * %include <typemaps/inoutlist.swg> - * - * where the method SWIG_Python_AppendResult is defined inside the - * %append_output fragment. - * - * If you forget to define %append_output, this file will generate - * an error. - * - * ------------------------------------------------------------ */ - - -// -// Uncomment the following definition if you don't want the in/out -// typemaps by default, ie, you prefer to use typemaps.i. -// -//#define SWIG_INOUT_NODEF - -// -// Use the following definition to enable the INPUT parameters to -// accept both 'by value' and 'pointer' objects. -// -#define SWIG_INPUT_ACCEPT_PTRS - -// ------------------------------------------------------------------------ -// Pointer handling -// -// These mappings provide support for input/output arguments and common -// uses for C/C++ pointers. -// ------------------------------------------------------------------------ - -// INPUT typemaps. -// These remap a C pointer to be an "INPUT" value which is passed by value -// instead of reference. - -/* -The following methods can be applied to turn a pointer into a simple -"input" value. That is, instead of passing a pointer to an object, -you would use a real value instead. - -To use these, suppose you had a C function like this : - - double fadd(double *a, double *b) { - return *a+*b; - } - -You could wrap it with SWIG as follows : - - double fadd(double *INPUT, double *INPUT); - -or you can use the %apply directive : - - %apply double *INPUT { double *a, double *b }; - double fadd(double *a, double *b); - -*/ -#if defined(SWIG_INPUT_ACCEPT_PTRS) -#define %check_input_ptr(input,arg,desc,disown) (SWIG_IsOK((res = SWIG_ConvertPtr(input,%as_voidptrptr(arg),desc,disown)))) -#else -#define %check_input_ptr(input,arg,desc,disown) (SWIG_IsOK((res = SWIG_ERROR))) -#endif - -%define %_value_input_typemap(code, asval_meth, asval_frag, Type) - %typemap(in,noblock=1,fragment=asval_frag) Type *INPUT ($*ltype temp, int res = 0) { - if (!%check_input_ptr($input,&$1,$descriptor,$disown)) { - Type val; - int ecode = asval_meth($input, &val); - if (!SWIG_IsOK(ecode)) { - %argument_fail(ecode, "$*ltype",$symname, $argnum); - } - temp = %static_cast(val, $*ltype); - $1 = &temp; - res = SWIG_AddTmpMask(ecode); - } - } - %typemap(in,noblock=1,fragment=asval_frag) Type &INPUT($*ltype temp, int res = 0) { - if (!%check_input_ptr($input,&$1,$descriptor,$disown)) { - Type val; - int ecode = asval_meth($input, &val); - if (!SWIG_IsOK(ecode)) { - %argument_fail(ecode, "$*ltype",$symname, $argnum); - } - temp = %static_cast(val, $*ltype); - $1 = &temp; - res = SWIG_AddTmpMask(ecode); - } - } - %typemap(freearg,noblock=1,match="in") Type *INPUT, Type &INPUT { - if (SWIG_IsNewObj(res$argnum)) %delete($1); - } - %typemap(typecheck,noblock=1,precedence=code,fragment=asval_frag) Type *INPUT, Type &INPUT { - void *ptr = 0; - int res = asval_meth($input, 0); - $1 = SWIG_CheckState(res); - if (!$1) { - $1 = %check_input_ptr($input,&ptr,$1_descriptor,0); - } - } -%enddef - -%define %_ptr_input_typemap(code,asptr_meth,asptr_frag,Type) - %typemap(in,noblock=1,fragment=asptr_frag) Type *INPUT(int res = 0) { - res = asptr_meth($input, &$1); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type",$symname, $argnum); - } - res = SWIG_AddTmpMask(res); - } - %typemap(in,noblock=1,fragment=asptr_frag) Type &INPUT(int res = 0) { - res = asptr_meth($input, &$1); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type",$symname, $argnum); - } - if (!$1) { - %argument_nullref("$type",$symname, $argnum); - } - res = SWIG_AddTmpMask(res); - } - %typemap(freearg,noblock=1,match="in") Type *INPUT, Type &INPUT { - if (SWIG_IsNewObj(res$argnum)) %delete($1); - } - %typemap(typecheck,noblock=1,precedence=code,fragment=asptr_frag) Type *INPUT, Type &INPUT { - int res = asptr_meth($input, (Type**)0); - $1 = SWIG_CheckState(res); - } -%enddef - -// OUTPUT typemaps. These typemaps are used for parameters that -// are output only. The output value is appended to the result as -// a list element. - -/* -The following methods can be applied to turn a pointer into an "output" -value. When calling a function, no input value would be given for -a parameter, but an output value would be returned. In the case of -multiple output values, they are returned in the form of a list. - - -For example, suppose you were trying to wrap the modf() function in the -C math library which splits x into integral and fractional parts (and -returns the integer part in one of its parameters): - - double modf(double x, double *ip); - -You could wrap it with SWIG as follows : - - double modf(double x, double *OUTPUT); - -or you can use the %apply directive : - - %apply double *OUTPUT { double *ip }; - double modf(double x, double *ip); - -The output of the function would be a list containing both output -values. - -*/ - -%define %_value_output_typemap(from_meth, from_frag, Type) - %typemap(in,numinputs=0,noblock=1) - Type *OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ), - Type &OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ) { - $1 = &temp; - } - %typemap(argout,noblock=1,fragment=from_frag) Type *OUTPUT, Type &OUTPUT { - if (SWIG_IsTmpObj(res$argnum)) { - %append_output(from_meth((*$1))); - } else { - int new_flags = SWIG_IsNewObj(res$argnum) ? (SWIG_POINTER_OWN | %newpointer_flags) : %newpointer_flags; - %append_output(SWIG_NewPointerObj((void*)($1), $1_descriptor, new_flags)); - } - } -%enddef - - -// INOUT -// Mappings for an argument that is both an input and output -// parameter - -/* -The following methods can be applied to make a function parameter both -an input and output value. This combines the behavior of both the -"INPUT" and "OUTPUT" methods described earlier. Output values are -returned in the form of a list. - -For example, suppose you were trying to wrap the following function : - - void neg(double *x) { - *x = -(*x); - } - -You could wrap it with SWIG as follows : - - void neg(double *INOUT); - -or you can use the %apply directive : - - %apply double *INOUT { double *x }; - void neg(double *x); - -Unlike C, this mapping does not directly modify the input value. -Rather, the modified input value shows up as the return value of the -function. Thus, to apply this function to a variable you might do -this : - - x = neg(x) - -Note : previous versions of SWIG used the symbol 'BOTH' to mark -input/output arguments. This is still supported, but will be slowly -phased out in future releases. - -*/ - -%define %_value_inout_typemap(Type) - %typemap(in) Type *INOUT = Type *INPUT; - %typemap(in) Type &INOUT = Type &INPUT; - %typemap(typecheck) Type *INOUT = Type *INPUT; - %typemap(typecheck) Type &INOUT = Type &INPUT; - %typemap(argout) Type *INOUT = Type *OUTPUT; - %typemap(argout) Type &INOUT = Type &OUTPUT; -%enddef - - -%define %_ptr_inout_typemap(Type) - %_value_inout_typemap(%arg(Type)) - %typemap(typecheck) Type *INOUT = Type *INPUT; - %typemap(typecheck) Type &INOUT = Type &INPUT; - %typemap(freearg) Type *INOUT = Type *INPUT; - %typemap(freearg) Type &INOUT = Type &INPUT; -%enddef - -#ifndef SWIG_INOUT_NODEF - -%define %value_input_typemap(code,asval_meth, asval_frag, Type...) - %_value_input_typemap(%arg(code),%arg(asval_meth),%arg(asval_frag),%arg(Type)) -%enddef - -%define %ptr_input_typemap(code,asval_meth,asval_frag,Type...) - %_ptr_input_typemap(%arg(code),%arg(asval_meth),%arg(asval_frag),%arg(Type)) -%enddef - -%define %value_output_typemap(from_meth,from_frag,Type...) - %_value_output_typemap(%arg(from_meth),%arg(from_frag),%arg(Type)) -%enddef - -#define %value_inout_typemap(Type...) %_value_inout_typemap(%arg(Type)) -#define %ptr_inout_typemap(Type...) %_ptr_inout_typemap(%arg(Type)) - -#else /* You need to include typemaps.i */ - - -#define %value_output_typemap(Type...) -#define %value_input_typemap(Type...) -#define %value_inout_typemap(Type...) -#define %ptr_input_typemap(Type...) -#define %ptr_inout_typemap(Type...) - -#endif /* SWIG_INOUT_DEFAULT */ - -/*---------------------------------------------------------------------- - Front ends. - - use the following macros to define your own IN/OUTPUT/INOUT typemaps - - ------------------------------------------------------------------------*/ -%define %typemaps_inout(Code, AsValMeth, FromMeth, AsValFrag, FromFrag, Type...) - %_value_input_typemap(%arg(Code), %arg(AsValMeth), - %arg(AsValFrag), %arg(Type)); - %_value_output_typemap(%arg(FromMeth), %arg(FromFrag), %arg(Type)); - %_value_inout_typemap(%arg(Type)); -%enddef - -%define %typemaps_inoutn(Code,Type...) - %typemaps_inout(%arg(Code), - %arg(SWIG_AsVal(Type)), - %arg(SWIG_From(Type)), - %arg(SWIG_AsVal_frag(Type)), - %arg(SWIG_From_frag(Type)), - %arg(Type)); -%enddef diff --git a/contrib/tools/swig/Lib/typemaps/misctypes.swg b/contrib/tools/swig/Lib/typemaps/misctypes.swg deleted file mode 100644 index 09c81d74335..00000000000 --- a/contrib/tools/swig/Lib/typemaps/misctypes.swg +++ /dev/null @@ -1,21 +0,0 @@ - -/* ------------------------------------------------------------ - * --- ANSI/Posix C/C++ types --- - * ------------------------------------------------------------ */ - - -#ifdef __cplusplus - -%apply size_t { std::size_t }; -%apply const size_t& { const std::size_t& }; - -%apply ptrdiff_t { std::ptrdiff_t }; -%apply const ptrdiff_t& { const std::ptrdiff_t& }; - -#ifndef SWIG_INOUT_NODEF -%apply size_t& { std::size_t& }; -%apply ptrdiff_t& { std::ptrdiff_t& }; -#endif - -#endif - diff --git a/contrib/tools/swig/Lib/typemaps/primtypes.swg b/contrib/tools/swig/Lib/typemaps/primtypes.swg deleted file mode 100644 index dd80eb775e3..00000000000 --- a/contrib/tools/swig/Lib/typemaps/primtypes.swg +++ /dev/null @@ -1,367 +0,0 @@ -/* ------------------------------------------------------------ - * Primitive type fragments and macros - * ------------------------------------------------------------ */ - -/* - This file provide fragments and macros for the C/C++ primitive types. - - The file defines default fragments for the following types: - - bool - signed char - unsigned char - signed wchar_t // in C++ - unsigned wchar_t // in C++ - short - unsigned short - int - unsigned int - float - size_t - ptrdiff_t - - which can always be redefined in the swig target language if needed. - - The fragments for the following types, however, always need to be - defined in the target language: - - long - unsigned long - long long - unsigned long long - double - - If they are not provided, an #error directive will appear in the - wrapped code. - - -------------------------------------------------------------------- - - This file provides the macro - - %typemaps_primitive(CheckCode, Type) - - which generates the typemaps for a primitive type with a given - checkcode. It is assumed that the primitive type is 'normalized' and - the corresponding SWIG_AsVal(Type) and SWIG_From(Type) methods are - provided via fragments. - - - The following auxiliary macros (explained with bash pseudo code) are - also defined: - - %apply_ctypes(Macro) - for i in C Type - do - Macro($i) - done - - %apply_cpptypes(Macro) - for i in C++ Type - do - Macro($i) - done - - %apply_ctypes_2(Macro2) - for i in C Type - do - for j in C Type - do - Macro_2($i, $j) - done - done - - %apply_cpptypes_2(Macro2) - for i in C++ Type - do - for j in C++ Type - do - Macro_2($i, $j) - done - done - - %apply_checkctypes(Macro2) - for i in Check Type - do - Macro2(%checkcode($i), $i) - done - -*/ - - -/* ------------------------------------------------------------ - * Primitive type fragments - * ------------------------------------------------------------ */ -/* boolean */ - -%fragment(SWIG_From_frag(bool),"header",fragment=SWIG_From_frag(long)) { -SWIGINTERN SWIG_Object -SWIG_From_dec(bool)(bool value) -{ - return SWIG_From(long)(value ? 1 : 0); -} -} - -%fragment(SWIG_AsVal_frag(bool),"header",fragment=SWIG_AsVal_frag(long)) { -SWIGINTERN int -SWIG_AsVal_dec(bool)(SWIG_Object obj, bool *val) -{ - long v; - int res = SWIG_AsVal(long)(obj, val ? &v : 0); - if (SWIG_IsOK(res)) { - if (val) *val = v ? true : false; - return res; - } - return SWIG_TypeError; -} -} - -/* signed/unsigned char */ - -%numeric_slong(signed char, "<limits.h>", SCHAR_MIN, SCHAR_MAX) -%numeric_ulong(unsigned char, "<limits.h>", UCHAR_MAX) - -/* short/unsigned short */ - -%numeric_slong(short, "<limits.h>", SHRT_MIN, SHRT_MAX) -%numeric_ulong(unsigned short, "<limits.h>", USHRT_MAX) - -/* int/unsigned int */ - -%numeric_slong(int, "<limits.h>", INT_MIN, INT_MAX) -%numeric_ulong(unsigned int, "<limits.h>", UINT_MAX) - -/* signed/unsigned wchar_t */ - -#ifdef __cplusplus -%numeric_slong(signed wchar_t, "<wchar.h>", WCHAR_MIN, WCHAR_MAX) -%numeric_ulong(unsigned wchar_t, "<wchar.h>", UWCHAR_MAX) -#endif - -/* float */ - -%numeric_float(float, "SWIG_Float_Overflow_Check", SWIG_Float_Overflow_Check(v)) - -/* long/unsigned long */ - -%ensure_type_fragments(long) -%ensure_type_fragments(unsigned long) - -/* long long/unsigned long long */ - -%fragment("SWIG_LongLongAvailable","header", fragment="<limits.h>") %{ -#if defined(LLONG_MAX) && !defined(SWIG_LONG_LONG_AVAILABLE) -# define SWIG_LONG_LONG_AVAILABLE -#endif -%} - -%ensure_type_fragments(long long) -%ensure_type_fragments(unsigned long long) - -/* double */ - -%ensure_type_fragments(double) - -/* size_t */ - -%fragment(SWIG_From_frag(size_t),"header",fragment=SWIG_From_frag(unsigned long),fragment=SWIG_From_frag(unsigned long long)) { -SWIGINTERNINLINE SWIG_Object -SWIG_From_dec(size_t)(size_t value) -{ -%#ifdef SWIG_LONG_LONG_AVAILABLE - if (sizeof(size_t) <= sizeof(unsigned long)) { -%#endif - return SWIG_From(unsigned long)(%numeric_cast(value, unsigned long)); -%#ifdef SWIG_LONG_LONG_AVAILABLE - } else { - /* assume sizeof(size_t) <= sizeof(unsigned long long) */ - return SWIG_From(unsigned long long)(%numeric_cast(value, unsigned long long)); - } -%#endif -} -} - -%fragment(SWIG_AsVal_frag(size_t),"header",fragment=SWIG_AsVal_frag(unsigned long),fragment=SWIG_AsVal_frag(unsigned long long)) { -SWIGINTERNINLINE int -SWIG_AsVal_dec(size_t)(SWIG_Object obj, size_t *val) -{ - int res = SWIG_TypeError; -%#ifdef SWIG_LONG_LONG_AVAILABLE - if (sizeof(size_t) <= sizeof(unsigned long)) { -%#endif - unsigned long v; - res = SWIG_AsVal(unsigned long)(obj, val ? &v : 0); - if (SWIG_IsOK(res) && val) *val = %numeric_cast(v, size_t); -%#ifdef SWIG_LONG_LONG_AVAILABLE - } else if (sizeof(size_t) <= sizeof(unsigned long long)) { - unsigned long long v; - res = SWIG_AsVal(unsigned long long)(obj, val ? &v : 0); - if (SWIG_IsOK(res) && val) *val = %numeric_cast(v, size_t); - } -%#endif - return res; -} -} - -/* ptrdiff_t */ - -%fragment(SWIG_From_frag(ptrdiff_t),"header",fragment=SWIG_From_frag(long),fragment=SWIG_From_frag(long long)) { -SWIGINTERNINLINE SWIG_Object -SWIG_From_dec(ptrdiff_t)(ptrdiff_t value) -{ -%#ifdef SWIG_LONG_LONG_AVAILABLE - if (sizeof(ptrdiff_t) <= sizeof(long)) { -%#endif - return SWIG_From(long)(%numeric_cast(value, long)); -%#ifdef SWIG_LONG_LONG_AVAILABLE - } else { - /* assume sizeof(ptrdiff_t) <= sizeof(long long) */ - return SWIG_From(long long)(%numeric_cast(value, long long)); - } -%#endif -} -} - -%fragment(SWIG_AsVal_frag(ptrdiff_t),"header",fragment=SWIG_AsVal_frag(long),fragment=SWIG_AsVal_frag(long long)) { -SWIGINTERNINLINE int -SWIG_AsVal_dec(ptrdiff_t)(SWIG_Object obj, ptrdiff_t *val) -{ - int res = SWIG_TypeError; -%#ifdef SWIG_LONG_LONG_AVAILABLE - if (sizeof(ptrdiff_t) <= sizeof(long)) { -%#endif - long v; - res = SWIG_AsVal(long)(obj, val ? &v : 0); - if (SWIG_IsOK(res) && val) *val = %numeric_cast(v, ptrdiff_t); -%#ifdef SWIG_LONG_LONG_AVAILABLE - } else if (sizeof(ptrdiff_t) <= sizeof(long long)) { - long long v; - res = SWIG_AsVal(long long)(obj, val ? &v : 0); - if (SWIG_IsOK(res) && val) *val = %numeric_cast(v, ptrdiff_t); - } -%#endif - return res; -} -} - - -%fragment("SWIG_CanCastAsInteger","header", - fragment=SWIG_AsVal_frag(double), - fragment="<float.h>", - fragment="<math.h>") { -SWIGINTERNINLINE int -SWIG_CanCastAsInteger(double *d, double min, double max) { - double x = *d; - if ((min <= x && x <= max)) { - double fx = floor(x); - double cx = ceil(x); - double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ - if ((errno == EDOM) || (errno == ERANGE)) { - errno = 0; - } else { - double summ, reps, diff; - if (rd < x) { - diff = x - rd; - } else if (rd > x) { - diff = rd - x; - } else { - return 1; - } - summ = rd + x; - reps = diff/summ; - if (reps < 8*DBL_EPSILON) { - *d = rd; - return 1; - } - } - } - return 0; -} -} - -/* ------------------------------------------------------------ - * Generate the typemaps for primitive type - * ------------------------------------------------------------ */ - -#define %typemaps_primitive(Code, Type) %typemaps_asvalfromn(%arg(Code), Type) - -/* ------------------------------------------------------------ - * Primitive Type Macros - * ------------------------------------------------------------ */ - -/* useful macros to derive typemap declarations from primitive types */ - -%define _apply_macro(macro, arg2, arg1...) -#if #arg1 != "" -macro(%arg(arg1),arg2); -#else -macro(arg2); -#endif -%enddef - -/* Apply macro to the C-types */ -%define %apply_ctypes(Macro, Arg2...) -_apply_macro(Macro, bool , Arg2); -_apply_macro(Macro, signed char , Arg2); -_apply_macro(Macro, unsigned char , Arg2); -_apply_macro(Macro, short , Arg2); -_apply_macro(Macro, unsigned short , Arg2); -_apply_macro(Macro, int , Arg2); -_apply_macro(Macro, unsigned int , Arg2); -_apply_macro(Macro, long , Arg2); -_apply_macro(Macro, unsigned long , Arg2); -_apply_macro(Macro, long long , Arg2); -_apply_macro(Macro, unsigned long long , Arg2); -_apply_macro(Macro, float , Arg2); -_apply_macro(Macro, double , Arg2); -_apply_macro(Macro, char , Arg2); -_apply_macro(Macro, wchar_t , Arg2); -_apply_macro(Macro, size_t , Arg2); -_apply_macro(Macro, ptrdiff_t , Arg2); -%enddef - -/* apply the Macro2(Type1, Type2) to all C types */ -#define %apply_ctypes_2(Macro2) %apply_ctypes(%apply_ctypes, Macro2) - - -/* apply the Macro(Type) to all C++ types */ -%define %apply_cpptypes(Macro, Arg2...) -%apply_ctypes(Macro, Arg2) -_apply_macro(Macro, std::size_t, Arg2); -_apply_macro(Macro, std::ptrdiff_t, Arg2); -_apply_macro(Macro, std::string, Arg2); -_apply_macro(Macro, std::wstring, Arg2); -_apply_macro(Macro, std::complex<float>, Arg2); -_apply_macro(Macro, std::complex<double>, Arg2); -%enddef - -/* apply the Macro2(Type1, Type2) to all C++ types */ -#define %apply_cpptypes_2(Macro2) %apply_cpptypes(%apply_cpptypes, Macro2) - -/* apply the Macro2(CheckCode,Type) to all Checked Types */ -%define %apply_checkctypes(Macro2) -Macro2(%checkcode(BOOL), bool); -Macro2(%checkcode(INT8), signed char); -Macro2(%checkcode(UINT8), unsigned char); -Macro2(%checkcode(INT16), short); -Macro2(%checkcode(UINT16), unsigned short); -Macro2(%checkcode(INT32), int); -Macro2(%checkcode(UINT32), unsigned int); -Macro2(%checkcode(INT64), long); -Macro2(%checkcode(UINT64), unsigned long); -Macro2(%checkcode(INT128), long long); -Macro2(%checkcode(UINT128), unsigned long long); -Macro2(%checkcode(FLOAT), float); -Macro2(%checkcode(DOUBLE), double); -Macro2(%checkcode(CHAR), char); -Macro2(%checkcode(UNICHAR), wchar_t); -Macro2(%checkcode(SIZE), size_t); -Macro2(%checkcode(PTRDIFF), ptrdiff_t); -%enddef - - -/* ------------------------------------------------------------ - * Generate the typemaps for all the primitive types with checkcode - * ------------------------------------------------------------ */ - -%apply_checkctypes(%typemaps_primitive); - diff --git a/contrib/tools/swig/Lib/typemaps/ptrtypes.swg b/contrib/tools/swig/Lib/typemaps/ptrtypes.swg deleted file mode 100644 index ca54fcdc265..00000000000 --- a/contrib/tools/swig/Lib/typemaps/ptrtypes.swg +++ /dev/null @@ -1,208 +0,0 @@ -/* ----------------------------------------------------------------------------- - * ptrtypes.swg - * - * Value typemaps (Type, const Type&) for "Ptr" types, such as swig - * wrapped classes, that define the AsPtr/From methods - * - * To apply them, just use one of the following macros: - * - * %typemaps_asptr(CheckCode, AsPtrMeth, AsPtrFrag, Type) - * %typemaps_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, Type) - * - * or the simpler and normalize form: - * - * %typemaps_asptrfromn(CheckCode, Type) - * - * Also, you can use the individual typemap definitions: - * - * %ptr_in_typemap(asptr_meth,frag,Type) - * %ptr_varin_typemap(asptr_meth,frag,Type) - * %ptr_typecheck_typemap(check,asptr_meth,frag,Type) - * %ptr_directorout_typemap(asptr_meth,frag,Type) - * ----------------------------------------------------------------------------- */ - -%include <typemaps/valtypes.swg> - -/* in */ - -%define %ptr_in_typemap(asptr_meth,frag,Type...) - %typemap(in,fragment=frag) Type { - Type *ptr = (Type *)0; - int res = asptr_meth($input, &ptr); - if (!SWIG_IsOK(res) || !ptr) { - %argument_fail((ptr ? res : SWIG_TypeError), "$type", $symname, $argnum); - } - $1 = *ptr; - if (SWIG_IsNewObj(res)) %delete(ptr); - } - %typemap(freearg) Type "" - %typemap(in,fragment=frag) const Type & (int res = SWIG_OLDOBJ) { - Type *ptr = (Type *)0; - res = asptr_meth($input, &ptr); - if (!SWIG_IsOK(res)) { %argument_fail(res,"$type",$symname, $argnum); } - if (!ptr) { %argument_nullref("$type",$symname, $argnum); } - $1 = ptr; - } - %typemap(freearg,noblock=1) const Type & { - if (SWIG_IsNewObj(res$argnum)) %delete($1); - } -%enddef - -/* varin */ - -%define %ptr_varin_typemap(asptr_meth,frag,Type...) - %typemap(varin,fragment=frag) Type { - Type *ptr = (Type *)0; - int res = asptr_meth($input, &ptr); - if (!SWIG_IsOK(res) || !ptr) { - %variable_fail((ptr ? res : SWIG_TypeError), "$type", "$name"); - } - $1 = *ptr; - if (SWIG_IsNewObj(res)) %delete(ptr); - } -%enddef - -#if defined(SWIG_DIRECTOR_TYPEMAPS) -/* directorout */ - -%define %ptr_directorout_typemap(asptr_meth,frag,Type...) - %typemap(directorargout,noblock=1,fragment=frag) Type *DIRECTOROUT ($*ltype temp, int swig_ores) { - Type *swig_optr = 0; - swig_ores = $result ? asptr_meth($result, &swig_optr) : 0; - if (!SWIG_IsOK(swig_ores) || !swig_optr) { - %dirout_fail((swig_optr ? swig_ores : SWIG_TypeError),"$type"); - } - temp = *swig_optr; - $1 = &temp; - if (SWIG_IsNewObj(swig_ores)) %delete(swig_optr); - } - - %typemap(directorout,noblock=1,fragment=frag) Type { - Type *swig_optr = 0; - int swig_ores = asptr_meth($input, &swig_optr); - if (!SWIG_IsOK(swig_ores) || !swig_optr) { - %dirout_fail((swig_optr ? swig_ores : SWIG_TypeError),"$type"); - } - $result = *swig_optr; - if (SWIG_IsNewObj(swig_ores)) %delete(swig_optr); - } - - %typemap(directorout,noblock=1,fragment=frag,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) Type* { - Type *swig_optr = 0; - int swig_ores = asptr_meth($input, &swig_optr); - if (!SWIG_IsOK(swig_ores)) { - %dirout_fail(swig_ores,"$type"); - } - $result = swig_optr; - if (SWIG_IsNewObj(swig_ores)) { - swig_acquire_ownership(swig_optr); - } - } - %typemap(directorfree,noblock=1) Type* - { - if (director) { - director->swig_release_ownership(%as_voidptr($input)); - } - } - - %typemap(directorout,noblock=1,fragment=frag,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) Type& { - Type *swig_optr = 0; - int swig_ores = asptr_meth($input, &swig_optr); - if (!SWIG_IsOK(swig_ores)) { - %dirout_fail(swig_ores,"$type"); - } else { - if (!swig_optr) { - %dirout_nullref("$type"); - } - } - $result = swig_optr; - if (SWIG_IsNewObj(swig_ores)) { - swig_acquire_ownership(swig_optr); - } - } - %typemap(directorfree,noblock=1) Type& - { - if (director) { - director->swig_release_ownership(%as_voidptr($input)); - } - } - - - %typemap(directorout,fragment=frag) Type &DIRECTOROUT = Type - -%enddef - -#else - -#define %ptr_directorout_typemap(asptr_meth,frag,Type...) - -#endif /* SWIG_DIRECTOR_TYPEMAPS */ - -/* typecheck */ - -%define %ptr_typecheck_typemap(check,asptr_meth,frag,Type...) -%typemap(typecheck,noblock=1,precedence=check,fragment=frag) Type * { - int res = asptr_meth($input, (Type**)(0)); - $1 = SWIG_CheckState(res); -} - -%typemap(typecheck,noblock=1,precedence=check,fragment=frag) Type, const Type& { - int res = asptr_meth($input, (Type**)(0)); - $1 = SWIG_CheckState(res); -} -%enddef - - -/*--------------------------------------------------------------------- - * typemap definition for types with asptr method - *---------------------------------------------------------------------*/ - -%define %typemaps_asptr(CheckCode, AsPtrMeth, AsPtrFrag, Type...) - %fragment(SWIG_AsVal_frag(Type),"header",fragment=SWIG_AsPtr_frag(Type)) { - SWIGINTERNINLINE int - SWIG_AsVal(Type)(SWIG_Object obj, Type *val) - { - Type *v = (Type *)0; - int res = SWIG_AsPtr(Type)(obj, &v); - if (!SWIG_IsOK(res)) return res; - if (v) { - if (val) *val = *v; - if (SWIG_IsNewObj(res)) { - %delete(v); - res = SWIG_DelNewMask(res); - } - return res; - } - return SWIG_ERROR; - } - } - %ptr_in_typemap(%arg(AsPtrMeth), %arg(AsPtrFrag), Type); - %ptr_varin_typemap(%arg(AsPtrMeth), %arg(AsPtrFrag), Type); - %ptr_directorout_typemap(%arg(AsPtrMeth), %arg(AsPtrFrag), Type); - %ptr_typecheck_typemap(%arg(CheckCode), %arg(AsPtrMeth),%arg(AsPtrFrag), Type); - %ptr_input_typemap(%arg(CheckCode),%arg(AsPtrMeth),%arg(AsPtrFrag),Type); -%enddef - -/*--------------------------------------------------------------------- - * typemap definition for types with asptr/from methods - *---------------------------------------------------------------------*/ - -%define %typemaps_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, Type...) - %typemaps_asptr(%arg(CheckCode), %arg(AsPtrMeth), %arg(AsPtrFrag), Type) - %typemaps_from(%arg(FromMeth), %arg(FromFrag), Type); - %value_output_typemap(%arg(FromMeth), %arg(FromFrag), Type); - %ptr_inout_typemap(Type); -%enddef - -/*--------------------------------------------------------------------- - * typemap definition for types with for 'normalized' asptr/from methods - *---------------------------------------------------------------------*/ - -%define %typemaps_asptrfromn(CheckCode, Type...) -%typemaps_asptrfrom(%arg(CheckCode), - %arg(SWIG_AsPtr(Type)), - %arg(SWIG_From(Type)), - %arg(SWIG_AsPtr_frag(Type)), - %arg(SWIG_From_frag(Type)), - Type); -%enddef diff --git a/contrib/tools/swig/Lib/typemaps/string.swg b/contrib/tools/swig/Lib/typemaps/string.swg deleted file mode 100644 index 72f4aa5b561..00000000000 --- a/contrib/tools/swig/Lib/typemaps/string.swg +++ /dev/null @@ -1,36 +0,0 @@ -%ensure_fragment(SWIG_AsCharPtrAndSize) -%ensure_fragment(SWIG_FromCharPtrAndSize) - -%types(char *); - -%fragment("SWIG_pchar_descriptor","header") { -SWIGINTERN swig_type_info* -SWIG_pchar_descriptor(void) -{ - static int init = 0; - static swig_type_info* info = 0; - if (!init) { - info = SWIG_TypeQuery("_p_char"); - init = 1; - } - return info; -} -} - -%fragment("SWIG_strnlen","header",fragment="SWIG_FromCharPtrAndSize") { -SWIGINTERN size_t -SWIG_strnlen(const char* s, size_t maxlen) -{ - const char *p; - for (p = s; maxlen-- && *p; p++) - ; - return p - s; -} -} - -%include <typemaps/strings.swg> -%typemaps_string(%checkcode(STRING), %checkcode(CHAR), - SWIGWARN_TYPEMAP_CHARLEAK_MSG, - char, Char, SWIG_AsCharPtrAndSize, SWIG_FromCharPtrAndSize, - strlen, SWIG_strnlen, - "<limits.h>", CHAR_MIN, CHAR_MAX) diff --git a/contrib/tools/swig/Lib/typemaps/strings.swg b/contrib/tools/swig/Lib/typemaps/strings.swg deleted file mode 100644 index 1237d98dfde..00000000000 --- a/contrib/tools/swig/Lib/typemaps/strings.swg +++ /dev/null @@ -1,658 +0,0 @@ -// -// Use the macro SWIG_PRESERVE_CARRAY_SIZE if you prefer to preserve -// the size of char arrays, ie -// ------------------------------------------ -// C Side => Language Side -// ------------------------------------------ -// char name[5] = "hola" => 'hola\0' -// -// the default behaviour is -// -// char name[5] = "hola" => 'hola' -// -// -//#define SWIG_PRESERVE_CARRAY_SIZE - -/* ------------------------------------------------------------ - * String typemaps for type Char (char or wchar_t) - * ------------------------------------------------------------ */ - -%define %_typemap_string(StringCode, - Char, - WarningLeakMsg, - SWIG_AsCharPtrAndSize, - SWIG_FromCharPtrAndSize, - SWIG_CharPtrLen, - SWIG_CharBufLen, - SWIG_AsCharPtr, - SWIG_FromCharPtr, - SWIG_AsCharArray, - SWIG_NewCopyCharArray, - SWIG_DeleteCharArray) - -/* in */ - -%typemap(in,noblock=1,fragment=#SWIG_AsCharPtr) - Char * (int res, Char *buf = 0, int alloc = 0), - const Char * (int res, Char *buf = 0, int alloc = 0) { - res = SWIG_AsCharPtr($input, &buf, &alloc); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type",$symname, $argnum); - } - $1 = %reinterpret_cast(buf, $1_ltype); -} -%typemap(freearg,noblock=1,match="in") Char *, const Char * { - if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum); -} - -%typemap(in,noblock=1,fragment=#SWIG_AsCharPtr) Char const*& (int res, Char *buf = 0, int alloc = 0) { - res = SWIG_AsCharPtr($input, &buf, &alloc); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type",$symname, $argnum); - } - $1 = &buf; -} -%typemap(freearg, noblock=1,match="in") Char const*& { - if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum); -} - -/* out */ - -%typemap(out,noblock=1,fragment=#SWIG_FromCharPtr) Char *, const Char * { - %set_output(SWIG_FromCharPtr((const Char *)$1)); -} - - -%typemap(out,noblock=1,fragment=#SWIG_FromCharPtr) Char const*& { - %set_output(SWIG_FromCharPtr(*$1)); -} - -%typemap(newfree,noblock=1) Char * { - SWIG_DeleteCharArray($1); -} - -/* varin */ - -%typemap(varin,fragment=#SWIG_AsCharPtrAndSize) Char * { - Char *cptr = 0; size_t csize = 0; int alloc = SWIG_NEWOBJ; - int res = SWIG_AsCharPtrAndSize($input, &cptr, &csize, &alloc); - if (!SWIG_IsOK(res)) { - %variable_fail(res,"$type","$name"); - } - SWIG_DeleteCharArray($1); - if (alloc == SWIG_NEWOBJ) { - $1 = cptr; - } else { - $1 = csize ? ($1_type)SWIG_NewCopyCharArray(cptr, csize, Char) : 0; - } -} - -%typemap(varin,fragment=#SWIG_AsCharPtrAndSize,warning=WarningLeakMsg) const Char * { - Char *cptr = 0; size_t csize = 0; int alloc = SWIG_NEWOBJ; - int res = SWIG_AsCharPtrAndSize($input, &cptr, &csize, &alloc); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } - if (alloc == SWIG_NEWOBJ) { - $1 = cptr; - } else { - $1 = csize ? ($1_type)SWIG_NewCopyCharArray(cptr, csize, Char) : 0; - } -} - -/* varout */ - -%typemap(varout,noblock=1,fragment=#SWIG_FromCharPtr) Char *, const Char * { - %set_varoutput(SWIG_FromCharPtr($1)); -} - -/* memberin */ - -%typemap(memberin,noblock=1) Char * { - SWIG_DeleteCharArray($1); - if ($input) { - size_t size = SWIG_CharPtrLen(%reinterpret_cast($input, const Char *)) + 1; - $1 = ($1_type)SWIG_NewCopyCharArray(%reinterpret_cast($input, const Char *), size, Char); - } else { - $1 = 0; - } -} - -%typemap(memberin,noblock=1,warning=WarningLeakMsg) const Char * { - if ($input) { - size_t size = SWIG_CharPtrLen(%reinterpret_cast(%reinterpret_cast($input, const Char *), const Char *)) + 1; - $1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char); - } else { - $1 = 0; - } -} - -/* globalin */ - -%typemap(globalin,noblock=1) Char * { - SWIG_DeleteCharArray($1); - if ($input) { - size_t size = SWIG_CharPtrLen(%reinterpret_cast(%reinterpret_cast($input, const Char *), const Char *)) + 1; - $1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char); - } else { - $1 = 0; - } -} - -%typemap(globalin,noblock=1,warning=WarningLeakMsg) const Char * { - if ($input) { - size_t size = SWIG_CharPtrLen($input) + 1; - $1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char); - } else { - $1 = 0; - } -} - -/* constant */ - -%typemap(constcode,noblock=1,fragment=#SWIG_FromCharPtr) - Char *, Char const*, Char * const, Char const* const { - %set_constant("$symname", SWIG_FromCharPtr($value)); -} - - -#if defined(SWIG_DIRECTOR_TYPEMAPS) - -/* directorin */ - -%typemap(directorin,noblock=1,fragment=#SWIG_FromCharPtr) - Char *, Char const*, Char *const, Char const *const, - Char const *&, Char *const &, Char const *const & { - $input = SWIG_FromCharPtr((const Char *)$1); -} - - -/* directorout */ - -%typemap(directorout,noblock=1,fragment=#SWIG_AsCharPtr,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) Char * (int res, Char *buf = 0, int alloc = SWIG_NEWOBJ) { - res = SWIG_AsCharPtr($input, &buf, &alloc); - if (!SWIG_IsOK(res)) { - %dirout_fail(res, "$type"); - } - if (alloc == SWIG_NEWOBJ) { - swig_acquire_ownership_array(buf); - } - $result = %reinterpret_cast(buf, $1_ltype); -} -%typemap(directorfree,noblock=1) Char * -{ - if (director) { - director->swig_release_ownership(%as_voidptr($input)); - } -} - - -%typemap(directorout,noblock=1,fragment=#SWIG_AsCharPtr,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) Char *const& (int res, Char *buf = 0, int alloc = SWIG_NEWOBJ), Char const*const& (int res, Char *buf = 0, int alloc = SWIG_NEWOBJ) { - res = SWIG_AsCharPtr($input, &buf, &alloc); - if (!SWIG_IsOK(res)) { - %dirout_fail(res, "$type"); - } - static $*1_ltype tmp = buf; - $result = &tmp; - if (alloc == SWIG_NEWOBJ) { - swig_acquire_ownership_array(buf); - } -} -%typemap(directorfree,noblock=1) - Char * const&, Char const* const& { - if (director) { - director->swig_release_ownership(%as_voidptr(*$input)); - } -} - -#endif /* SWIG_DIRECTOR_TYPEMAPS */ - -/* typecheck */ - -%typemap(typecheck,noblock=1,precedence=StringCode, - fragment=#SWIG_AsCharPtr) Char *, const Char *, Char const*& { - int res = SWIG_AsCharPtr($input, 0, 0); - $1 = SWIG_CheckState(res); -} - - -/* throws */ - -%typemap(throws,noblock=1,fragment=#SWIG_FromCharPtr) Char * { - %raise(SWIG_FromCharPtr($1), "$type", 0); -} - - -/* ------------------------------------------------------------ - * Unknown size const Character array Char[ANY] handling - * ------------------------------------------------------------ */ - -%apply Char * { Char [] }; -%apply const Char * { const Char [] }; - -%typemap(varin,noblock=1,warning="462:Unable to set variable of type Char []") Char [] -{ - %variable_fail(SWIG_AttributeError, "$type", "read-only $name"); -} - - -/* ------------------------------------------------------------ - * Fixed size Character array Char[ANY] handling - * ------------------------------------------------------------ */ - -/* memberin and globalin typemaps */ - -%typemap(memberin,noblock=1) Char [ANY] -{ - if ($input) memcpy($1,$input,$1_dim0*sizeof(Char)); - else memset($1,0,$1_dim0*sizeof(Char)); -} - -%typemap(globalin,noblock=1) Char [ANY] -{ - if ($input) memcpy($1,$input,$1_dim0*sizeof(Char)); - else memset($1,0,$1_dim0*sizeof(Char)); -} - -/* in */ - -%typemap(in,noblock=1,fragment=#SWIG_AsCharArray) - Char [ANY] (Char temp[$1_dim0], int res), - const Char [ANY](Char temp[$1_dim0], int res) -{ - res = SWIG_AsCharArray($input, temp, $1_dim0); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type",$symname, $argnum); - } - $1 = %reinterpret_cast(temp, $1_ltype); -} -%typemap(freearg) Char [ANY], const Char [ANY] "" - -%typemap(in,noblock=1,fragment=#SWIG_AsCharArray) const Char (&)[ANY] (Char temp[$1_dim0], int res) -{ - res = SWIG_AsCharArray($input, temp, $1_dim0); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type",$symname, $argnum); - } - $1 = &temp; -} -%typemap(freearg) const Char (&)[ANY] "" - -%typemap(out,fragment=#SWIG_FromCharPtrAndSize,fragment=#SWIG_CharBufLen) - Char [ANY], const Char[ANY] -{ -%#ifndef SWIG_PRESERVE_CARRAY_SIZE - size_t size = SWIG_CharBufLen($1, $1_dim0); -%#else - size_t size = $1_dim0; -%#endif - %set_output(SWIG_FromCharPtrAndSize($1, size)); -} - -/* varin */ - -%typemap(varin,fragment=#SWIG_AsCharArray) Char [ANY] -{ - int res = SWIG_AsCharArray($input, $1, $1_dim0); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } -} - -/* varout */ - -%typemap(varout,fragment=#SWIG_CharBufLen) - Char [ANY], const Char [ANY] { -%#ifndef SWIG_PRESERVE_CARRAY_SIZE - size_t size = SWIG_CharBufLen($1, $1_dim0); -%#else - size_t size = $1_dim0; -%#endif - %set_varoutput(SWIG_FromCharPtrAndSize($1, size)); -} - -/* constant */ - -%typemap(constcode,fragment=#SWIG_CharBufLen) - Char [ANY], const Char [ANY] -{ -%#ifndef SWIG_PRESERVE_CARRAY_SIZE - size_t size = SWIG_CharBufLen($1, $1_dim0); -%#else - size_t size = $value_dim0; -%#endif - %set_constant("$symname", SWIG_FromCharPtrAndSize($value,size)); -} - - -#if defined(SWIG_DIRECTOR_TYPEMAPS) - -/* directorin */ -%typemap(directorin,fragment=#SWIG_CharBufLen) - Char [ANY], const Char [ANY] -{ -%#ifndef SWIG_PRESERVE_CARRAY_SIZE - size_t size = SWIG_CharBufLen($1, $1_dim0); -%#else - size_t size = $1_dim0; -%#endif - $input = SWIG_FromCharPtrAndSize($1, size); -} - -/* directorout */ - -%typemap(directorout,noblock=1,fragment=#SWIG_AsCharArray) - Char [ANY] (Char temp[$result_dim0]), - const Char [ANY] (Char temp[$result_dim0], int res) -{ - res = SWIG_AsCharArray($input, temp, $result_dim0); - if (!SWIG_IsOK(res)) { - %dirout_fail(res, "$type"); - } - $result = temp; -} - -#endif /* SWIG_DIRECTOR_TYPEMAPS */ - -/* typecheck */ - -%typemap(typecheck,noblock=1,precedence=StringCode, - fragment=#SWIG_AsCharArray) - Char [ANY], const Char[ANY] { - int res = SWIG_AsCharArray($input, (Char *)0, $1_dim0); - $1 = SWIG_CheckState(res); -} - - -/* throws */ - -%typemap(throws,fragment=#SWIG_CharBufLen) - Char [ANY], const Char[ANY] -{ -%#ifndef SWIG_PRESERVE_CARRAY_SIZE - size_t size = SWIG_CharBufLen($1, $1_dim0); -%#else - size_t size = $1_dim0; -%#endif - %raise(SWIG_FromCharPtrAndSize($1, size), "$type", 0); -} - -/* ------------------------------------------------------------------- - * --- Really fix size Char arrays, including '\0'chars at the end --- - * ------------------------------------------------------------------- */ - -%typemap(varout,noblock=1,fragment=#SWIG_FromCharPtrAndSize) - Char FIXSIZE[ANY], const Char FIXSIZE[ANY] -{ - %set_varoutput(SWIG_FromCharPtrAndSize($1, $1_dim0)); -} - -%typemap(out,noblock=1,fragment=#SWIG_FromCharPtrAndSize) - Char FIXSIZE[ANY], const Char FIXSIZE[ANY] -{ - %set_output(SWIG_FromCharPtrAndSize($1, $1_dim0)); -} - -#if defined(SWIG_DIRECTOR_TYPEMAPS) - -%typemap(directorin,noblock=1,fragment=#SWIG_FromCharPtrAndSize) - Char FIXSIZE[ANY], const Char FIXSIZE[ANY] -{ - $input = SWIG_FromCharPtrAndSize($1, $1_dim0); -} - -#endif /* SWIG_DIRECTOR_TYPEMAPS */ - -%typemap(throws,noblock=1,fragment=#SWIG_FromCharPtrAndSize) - Char FIXSIZE[ANY], const Char FIXSIZE[ANY] { - %raise(SWIG_FromCharPtrAndSize($1, $1_dim0), "$type", 0); -} - -/* ------------------------------------------------------------ - * --- String & length --- - * ------------------------------------------------------------ */ - -/* Here len doesn't include the '0' terminator */ -%typemap(in,noblock=1,fragment=#SWIG_AsCharPtrAndSize) - (Char *STRING, size_t LENGTH) (int res, Char *buf = 0, size_t size = 0, int alloc = 0), - (const Char *STRING, size_t LENGTH) (int res, Char *buf = 0, size_t size = 0, int alloc = 0) -{ - res = SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type",$symname, $argnum); - } - $1 = %reinterpret_cast(buf, $1_ltype); - $2 = %numeric_cast(size - 1, $2_ltype); -} -%typemap(freearg,noblock=1,match="in") (Char *STRING, size_t LENGTH) { - if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum); -} -/* old 'int' form */ -%typemap(in) (Char *STRING, int LENGTH) = (Char *STRING, size_t LENGTH); -%typemap(freearg) (Char *STRING, int LENGTH) = (Char *STRING, size_t LENGTH); - - -/* Here size includes the '0' terminator */ -%typemap(in,noblock=1,fragment=#SWIG_AsCharPtrAndSize) - (Char *STRING, size_t SIZE) (int res, Char *buf = 0, size_t size = 0, int alloc = 0), - (const Char *STRING, size_t SIZE) (int res, Char *buf = 0, size_t size = 0, int alloc = 0) -{ - res = SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type",$symname, $argnum); - } - $1 = %reinterpret_cast(buf, $1_ltype); - $2 = %numeric_cast(size, $2_ltype); -} -%typemap(freearg,noblock=1,match="in") (Char *STRING, size_t SIZE) { - if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum); -} -/* old 'int' form */ -%typemap(in) (Char *STRING, int SIZE) = (Char *STRING, size_t SIZE); -%typemap(freearg) (Char *STRING, int SIZE) = (Char *STRING, size_t SIZE); - - -/* reverse order versions */ - -/* Here len doesn't include the '0' terminator */ -%typemap(in,noblock=1,fragment=#SWIG_AsCharPtrAndSize) - (size_t LENGTH, Char *STRING) (int res, Char *buf = 0, size_t size = 0, int alloc = 0), - (size_t LENGTH, const Char *STRING) (int res, Char *buf = 0, size_t size = 0, int alloc = 0) -{ - res = SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type",$symname, $argnum); - } - $2 = %reinterpret_cast(buf, $2_ltype) ; - $1 = %numeric_cast(size - 1, $1_ltype) ; -} -%typemap(freearg, noblock=1, match="in") (size_t LENGTH, Char *STRING) { - if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum); -} -/* old 'int' form */ -%typemap(in) (int LENGTH, Char *STRING) = (size_t LENGTH, Char *STRING); -%typemap(freearg) (int LENGTH, Char *STRING) = (size_t LENGTH, Char *STRING); - -/* Here size includes the '0' terminator */ -%typemap(in,noblock=1,fragment=#SWIG_AsCharPtrAndSize) - (size_t SIZE, Char *STRING) (int res, Char *buf = 0, size_t size = 0, int alloc = 0), - (size_t SIZE, const Char *STRING) (int res, Char *buf = 0, size_t size = 0, int alloc = 0) -{ - res = SWIG_AsCharPtrAndSize($input, &buf, &size, &alloc); - if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type",$symname, $argnum); - } - $2 = %reinterpret_cast(buf, $2_ltype) ; - $1 = %numeric_cast(size, $1_ltype) ; -} -%typemap(freearg, noblock=1, match="in") (size_t SIZE, Char *STRING) { - if (alloc$argnum == SWIG_NEWOBJ) SWIG_DeleteCharArray(buf$argnum); -} -/* old 'int' form */ -%typemap(in) (int SIZE, Char *STRING) = (size_t SIZE, Char *STRING); -%typemap(freearg) (int SIZE, Char *STRING) = (size_t SIZE, Char *STRING); - - -%enddef - - -/* ------------------------------------------------------------ - * --- String fragment methods --- - * ------------------------------------------------------------ */ - -#ifndef %_typemap2_string -%define %_typemap2_string(StringCode, CharCode, - WarningLeakMsg, - Char, CharName, - SWIG_AsCharPtrAndSize, - SWIG_FromCharPtrAndSize, - SWIG_CharPtrLen, - SWIG_CharBufLen, - SWIG_NewCopyCharArray, - SWIG_DeleteCharArray, - FragLimits, CHAR_MIN, CHAR_MAX) - -%fragment("SWIG_From"#CharName"Ptr","header",fragment=#SWIG_FromCharPtrAndSize) { -SWIGINTERNINLINE SWIG_Object -SWIG_From##CharName##Ptr(const Char *cptr) -{ - return SWIG_FromCharPtrAndSize(cptr, (cptr ? SWIG_CharPtrLen(cptr) : 0)); -} -} - -%fragment("SWIG_From"#CharName"Array","header",fragment=#SWIG_FromCharPtrAndSize) { -SWIGINTERNINLINE SWIG_Object -SWIG_From##CharName##Array(const Char *cptr, size_t size) -{ - return SWIG_FromCharPtrAndSize(cptr, size); -} -} - -%fragment("SWIG_As" #CharName "Ptr","header",fragment=#SWIG_AsCharPtrAndSize) { -%define_as(SWIG_As##CharName##Ptr(obj, val, alloc), SWIG_AsCharPtrAndSize(obj, val, NULL, alloc)) -} - -%fragment("SWIG_As" #CharName "Array","header",fragment=#SWIG_AsCharPtrAndSize) { -SWIGINTERN int -SWIG_As##CharName##Array(SWIG_Object obj, Char *val, size_t size) -{ - Char* cptr = 0; size_t csize = 0; int alloc = SWIG_OLDOBJ; - int res = SWIG_AsCharPtrAndSize(obj, &cptr, &csize, &alloc); - if (SWIG_IsOK(res)) { - /* special case of single char conversion when we don't need space for NUL */ - if (size == 1 && csize == 2 && cptr && !cptr[1]) --csize; - if (csize <= size) { - if (val) { - if (csize) memcpy(val, cptr, csize*sizeof(Char)); - if (csize < size) memset(val + csize, 0, (size - csize)*sizeof(Char)); - } - if (alloc == SWIG_NEWOBJ) { - SWIG_DeleteCharArray(cptr); - res = SWIG_DelNewMask(res); - } - return res; - } - if (alloc == SWIG_NEWOBJ) SWIG_DeleteCharArray(cptr); - } - return SWIG_TypeError; -} -} - -/* Char */ - -%fragment(SWIG_From_frag(Char),"header",fragment=#SWIG_FromCharPtrAndSize) { -SWIGINTERNINLINE SWIG_Object -SWIG_From_dec(Char)(Char c) -{ - return SWIG_FromCharPtrAndSize(&c,1); -} -} - -%fragment(SWIG_AsVal_frag(Char),"header", - fragment="SWIG_As"#CharName"Array", - fragment=FragLimits, - fragment=SWIG_AsVal_frag(long)) { -SWIGINTERN int -SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val) -{ - int res = SWIG_As##CharName##Array(obj, val, 1); - if (!SWIG_IsOK(res)) { - long v; - res = SWIG_AddCast(SWIG_AsVal(long)(obj, &v)); - if (SWIG_IsOK(res)) { - if ((CHAR_MIN <= v) && (v <= CHAR_MAX)) { - if (val) *val = %numeric_cast(v, Char); - } else { - res = SWIG_OverflowError; - } - } - } - return res; -} -} - -%_typemap_string(StringCode, - Char, - WarningLeakMsg, - SWIG_AsCharPtrAndSize, - SWIG_FromCharPtrAndSize, - SWIG_CharPtrLen, - SWIG_CharBufLen, - SWIG_As##CharName##Ptr, - SWIG_From##CharName##Ptr, - SWIG_As##CharName##Array, - SWIG_NewCopyCharArray, - SWIG_DeleteCharArray) - -%enddef -#endif - -/* ------------------------------------------------------------ - * String typemaps and fragments, with default allocators - * ------------------------------------------------------------ */ - -%define %typemaps_string(StringCode, CharCode, - WarningLeakMsg, - Char, CharName, - SWIG_AsCharPtrAndSize, - SWIG_FromCharPtrAndSize, - SWIG_CharPtrLen, - SWIG_CharBufLen, - FragLimits, CHAR_MIN, CHAR_MAX) -%_typemap2_string(StringCode, CharCode, - WarningLeakMsg, - Char, CharName, - SWIG_AsCharPtrAndSize, - SWIG_FromCharPtrAndSize, - SWIG_CharPtrLen, - SWIG_CharBufLen, - %new_copy_array, - %delete_array, - FragLimits, CHAR_MIN, CHAR_MAX) -%enddef - -/* ------------------------------------------------------------ - * String typemaps and fragments, with custom allocators - * ------------------------------------------------------------ */ - -%define %typemaps_string_alloc(StringCode, CharCode, - WarningLeakMsg, - Char, CharName, - SWIG_AsCharPtrAndSize, - SWIG_FromCharPtrAndSize, - SWIG_CharPtrLen, - SWIG_CharBufLen, - SWIG_NewCopyCharArray, - SWIG_DeleteCharArray, - FragLimits, CHAR_MIN, CHAR_MAX) -%_typemap2_string(StringCode, CharCode, - WarningLeakMsg, - Char, CharName, - SWIG_AsCharPtrAndSize, - SWIG_FromCharPtrAndSize, - SWIG_CharPtrLen, - SWIG_CharBufLen, - SWIG_NewCopyCharArray, - SWIG_DeleteCharArray, - FragLimits, CHAR_MIN, CHAR_MAX) -%enddef diff --git a/contrib/tools/swig/Lib/typemaps/swigmacros.swg b/contrib/tools/swig/Lib/typemaps/swigmacros.swg deleted file mode 100644 index b772eb04b3e..00000000000 --- a/contrib/tools/swig/Lib/typemaps/swigmacros.swg +++ /dev/null @@ -1,228 +0,0 @@ -/* ----------------------------------------------------------------------------- - * SWIG API. Portion only visible from SWIG - * ----------------------------------------------------------------------------- */ -/* - This file implements the internal macros of the 'SWIG API', which - are useful to implement all the SWIG target languages. - - Basic preprocessor macros: - -------------------------- - - %arg(Arg) Safe argument wrap - %str(Arg) Stringify the argument - %begin_block Begin an execution block - %end_block End an execution block - %block(Block) Execute Block as an execution block - %define_as(Def, Val) Define 'Def' as 'Val', expanding Def and Val first - %ifcplusplus(V1, V2) if C++ Mode; then V1; else V2; fi - - - Casting Operations: - ------------------- - - SWIG provides the following casting macros, which implement the - corresponding C++ casting operations: - - %const_cast(a, Type) const_cast<Type >(a) - %static_cast(a, Type) static_cast<Type >(a) - %reinterpret_cast(a, Type) reinterpret_cast<Type >(a) - %numeric_cast(a, Type) static_cast<Type >(a) - %as_voidptr(a) const_cast<void *>(static_cast<const void *>(a)) - %as_voidptrptr(a) reinterpret_cast<void **>(a) - - or their C unsafe versions. In C++ we use the safe version unless - SWIG_NO_CPLUSPLUS_CAST is defined - - - Memory allocation: - ------------------ - - These allocation/freeing macros are safe to use in C or C++ and - dispatch the proper new/delete/delete[] or free/malloc calls as - needed. - - %new_instance(Type) Allocate a new instance of given Type - %new_copy(value,Type) Allocate and initialize a new instance with 'value' - %new_array(size,Type) Allocate a new array with given size and Type and zero initialize - %new_copy_array(cptr,size,Type) Allocate and initialize a new array from 'cptr' - %delete(cptr) Delete an instance - %delete_array(cptr) Delete an array - - - Auxiliary loop macros: - ---------------------- - - %formacro(Macro, Args...) or %formacro_1(Macro, Args...) - for i in Args - do - Macro($i) - done - - %formacro_2(Macro2, Args...) - for i,j in Args - do - Macro2($i, $j) - done - - - Flags and conditional macros: - ----------------------------- - - %mark_flag(flag) - flag := True - - %evalif(flag,expr) - if flag; then - expr - fi - - %evalif_2(flag1 flag2,expr) - if flag1 and flag2; then - expr - fi - - -*/ -/* ----------------------------------------------------------------------------- - * Basic preprocessor macros - * ----------------------------------------------------------------------------- */ - -#define %arg(Arg...) Arg -#define %str(Arg) `Arg` -#ifndef %begin_block -# define %begin_block do { -#endif -#ifndef %end_block -# define %end_block } while(0) -#endif -#define %block(Block...) %begin_block Block; %end_block - -/* define a new macro */ -%define %define_as(Def, Val...)%#define Def Val %enddef - -/* include C++ or else value */ -%define %ifcplusplus(cppval, nocppval) -#ifdef __cplusplus -cppval -#else -nocppval -#endif -%enddef - -/* ----------------------------------------------------------------------------- - * Casting operators - * ----------------------------------------------------------------------------- */ - -#if defined(__cplusplus) && !defined(SWIG_NO_CPLUSPLUS_CAST) -# define %const_cast(a,Type...) const_cast< Type >(a) -# define %static_cast(a,Type...) static_cast< Type >(a) -# define %reinterpret_cast(a,Type...) reinterpret_cast< Type >(a) -# define %numeric_cast(a,Type...) static_cast< Type >(a) -#else /* C case */ -# define %const_cast(a,Type...) (Type)(a) -# define %static_cast(a,Type...) (Type)(a) -# define %reinterpret_cast(a,Type...) (Type)(a) -# define %numeric_cast(a,Type...) (Type)(a) -#endif /* __cplusplus */ - - -#define %as_voidptr(a) SWIG_as_voidptr(a) -#define %as_voidptrptr(a) SWIG_as_voidptrptr(a) - -%insert("header") { -%define_as(SWIG_as_voidptr(a), %const_cast(%static_cast(a,const void *), void *)) -%define_as(SWIG_as_voidptrptr(a), ((void)%as_voidptr(*a),%reinterpret_cast(a, void**))) -} - - -/* ----------------------------------------------------------------------------- - * Allocating/freeing elements - * ----------------------------------------------------------------------------- */ - -#if defined(__cplusplus) -# define %new_instance(Type...) (new Type()) -# define %new_copy(val,Type...) (new Type(%static_cast(val, const Type&))) -# define %new_array(size,Type...) (new Type[size]()) -# define %new_copy_array(ptr,size,Type...) %reinterpret_cast(memcpy(new Type[size], ptr, sizeof(Type)*(size)), Type*) -# define %delete(cptr) delete cptr -# define %delete_array(cptr) delete[] cptr -#else /* C case */ -# define %new_instance(Type...) (Type *)calloc(1,sizeof(Type)) -# define %new_copy(val,Type...) (Type *)memcpy(%new_instance(Type),&val,sizeof(Type)) -# define %new_array(size,Type...) (Type *)calloc(size, sizeof(Type)) -# define %new_copy_array(ptr,size,Type...) (Type *)memcpy(malloc((size)*sizeof(Type)), ptr, sizeof(Type)*(size)) -# define %delete(cptr) free((char*)cptr) -# define %delete_array(cptr) free((char*)cptr) -#endif /* __cplusplus */ - -/* ----------------------------------------------------------------------------- - * SWIG names and mangling - * ----------------------------------------------------------------------------- */ - -#define %mangle(Type...) #@Type -#define %descriptor(Type...) SWIGTYPE_ ## #@Type -#define %string_name(Name) "SWIG_" %str(Name) -#define %symbol_name(Name, Type...) SWIG_ ## Name ## _ #@Type -#define %checkcode(Code) SWIG_TYPECHECK_ ## Code - - -/* ----------------------------------------------------------------------------- - * Auxiliary loop macros - * ----------------------------------------------------------------------------- */ - - -/* for loop for macro with one argument */ -%define %_formacro_1(macro, arg1,...)macro(arg1) -#if #__VA_ARGS__ != "__fordone__" -%_formacro_1(macro, __VA_ARGS__) -#endif -%enddef - -/* for loop for macro with one argument */ -%define %formacro_1(macro,...)%_formacro_1(macro,__VA_ARGS__,__fordone__)%enddef -%define %formacro(macro,...)%_formacro_1(macro,__VA_ARGS__,__fordone__)%enddef - -/* for loop for macro with two arguments */ -%define %_formacro_2(macro, arg1, arg2, ...)macro(arg1, arg2) -#if #__VA_ARGS__ != "__fordone__" -%_formacro_2(macro, __VA_ARGS__) -#endif -%enddef - -/* for loop for macro with two arguments */ -%define %formacro_2(macro,...)%_formacro_2(macro, __VA_ARGS__, __fordone__)%enddef - -/* ----------------------------------------------------------------------------- - * SWIG flags - * ----------------------------------------------------------------------------- */ - -/* - mark a flag, ie, define a macro name but ignore it in - the interface. - - the flag can be later used with %evalif -*/ - -%define %mark_flag(x) %define x 1 %enddef %enddef - - -/* - %evalif and %evalif_2 are use to evaluate or process - an expression if the given predicate is 'true' (1). -*/ -%define %_evalif(_x,_expr) -#if _x == 1 -_expr -#endif -%enddef - -%define %_evalif_2(_x,_y,_expr) -#if _x == 1 && _y == 1 -_expr -#endif -%enddef - -%define %evalif(_x,_expr...) %_evalif(%arg(_x),%arg(_expr)) %enddef - -%define %evalif_2(_x,_y,_expr...) %_evalif_2(%arg(_x),%arg(_y),%arg(_expr)) %enddef - diff --git a/contrib/tools/swig/Lib/typemaps/swigobject.swg b/contrib/tools/swig/Lib/typemaps/swigobject.swg deleted file mode 100644 index 26c6ba8edf0..00000000000 --- a/contrib/tools/swig/Lib/typemaps/swigobject.swg +++ /dev/null @@ -1,37 +0,0 @@ -/* ------------------------------------------------------------ - * Language Object * - Just pass straight through unmodified - * ------------------------------------------------------------ */ - -%typemap(in) SWIG_Object "$1 = $input;" - -%typemap(in,noblock=1) SWIG_Object const & ($*ltype temp) -{ - temp = %static_cast($input, $*ltype); - $1 = &temp; -} - -%typemap(out,noblock=1) SWIG_Object { - %set_output($1); -} - -%typemap(out,noblock=1) SWIG_Object const & { - %set_output(*$1); -} - -%typecheck(SWIG_TYPECHECK_SWIGOBJECT) SWIG_Object "$1 = ($input != 0);"; - -%typemap(throws,noblock=1) SWIG_Object { - %raise($1, "$type", 0); -} - -%typemap(constcode,noblock=1) SWIG_Object { - %set_constant("$symname", $value); -} - -#if defined(SWIG_DIRECTOR_TYPEMAPS) - -%typemap(directorin) SWIG_Object "$input = $1;" -%typemap(directorout) SWIG_Object "$result = $input;" - -#endif /* SWIG_DIRECTOR_TYPEMAPS */ - diff --git a/contrib/tools/swig/Lib/typemaps/swigtype.swg b/contrib/tools/swig/Lib/typemaps/swigtype.swg deleted file mode 100644 index 69f83794d23..00000000000 --- a/contrib/tools/swig/Lib/typemaps/swigtype.swg +++ /dev/null @@ -1,710 +0,0 @@ -/* ----------------------------------------------------------------------------- - * --- Input arguments --- - * ----------------------------------------------------------------------------- */ -/* Pointers and arrays */ -%typemap(in, noblock=1) SWIGTYPE *(void *argp = 0, int res = 0) { - res = SWIG_ConvertPtr($input, &argp,$descriptor, $disown | %convertptr_flags); - if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); - } - $1 = %reinterpret_cast(argp, $ltype); -} -%typemap(freearg) SWIGTYPE * "" - -%typemap(in, noblock=1) SWIGTYPE [] (void *argp = 0, int res = 0) { - res = SWIG_ConvertPtr($input, &argp,$descriptor, $disown | %convertptr_flags); - if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); - } - $1 = %reinterpret_cast(argp, $ltype); -} -%typemap(freearg) SWIGTYPE [] "" - - -%typemap(in, noblock=1) SWIGTYPE *const& (void *argp = 0, int res = 0, $*1_ltype temp) { - res = SWIG_ConvertPtr($input, &argp, $*descriptor, $disown | %convertptr_flags); - if (!SWIG_IsOK(res)) { - %argument_fail(res, "$*ltype", $symname, $argnum); - } - temp = %reinterpret_cast(argp, $*ltype); - $1 = %reinterpret_cast(&temp, $1_ltype); -} -%typemap(freearg) SWIGTYPE *const& "" - - -/* Reference */ -%typemap(in, noblock=1) SWIGTYPE & (void *argp = 0, int res = 0) { - res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags); - if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); - } - if (!argp) { %argument_nullref("$type", $symname, $argnum); } - $1 = %reinterpret_cast(argp, $ltype); -} -%typemap(freearg) SWIGTYPE & "" - -#if defined(__cplusplus) && defined(%implicitconv_flag) -%typemap(in,noblock=1,implicitconv=1) const SWIGTYPE & (void *argp = 0, int res = 0) { - res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags | %implicitconv_flag); - if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); - } - if (!argp) { %argument_nullref("$type", $symname, $argnum); } - $1 = %reinterpret_cast(argp, $ltype); -} -%typemap(freearg,noblock=1,match="in",implicitconv=1) const SWIGTYPE & -{ - if (SWIG_IsNewObj(res$argnum)) %delete($1); -} -#endif - -/* Rvalue reference */ -%typemap(in, noblock=1, fragment="<memory>") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) { - res = SWIG_ConvertPtr($input, &argp, $descriptor, SWIG_POINTER_RELEASE | %convertptr_flags); - if (!SWIG_IsOK(res)) { - if (res == SWIG_ERROR_RELEASE_NOT_OWNED) { - %releasenotowned_fail(res, "$type", $symname, $argnum); - } else { - %argument_fail(res, "$type", $symname, $argnum); - } - } - if (!argp) { %argument_nullref("$type", $symname, $argnum); } - $1 = %reinterpret_cast(argp, $ltype); - rvrdeleter.reset($1); -} -%typemap(freearg) SWIGTYPE && "" - -/* By value */ -#if defined(__cplusplus) && defined(%implicitconv_flag) -%typemap(in,implicitconv=1) SWIGTYPE (void *argp, int res = 0) { - res = SWIG_ConvertPtr($input, &argp, $&descriptor, %convertptr_flags | %implicitconv_flag); - if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); - } - if (!argp) { - %argument_nullref("$type", $symname, $argnum); - } else { - $<ype temp = %reinterpret_cast(argp, $<ype); - $1 = *temp; - if (SWIG_IsNewObj(res)) %delete(temp); - } -} -#else -%typemap(in) SWIGTYPE (void *argp, int res = 0) { - res = SWIG_ConvertPtr($input, &argp, $&descriptor, %convertptr_flags); - if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); - } - if (!argp) { - %argument_nullref("$type", $symname, $argnum); - } else { - $1 = *(%reinterpret_cast(argp, $<ype)); - } -} -#endif - - -/* ----------------------------------------------------------------------------- - * --- Output arguments --- - * ----------------------------------------------------------------------------- */ - -/* Pointers, references */ -%typemap(out,noblock=1) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE[] { - %set_output(SWIG_NewPointerObj(%as_voidptr($1), $descriptor, $owner | %newpointer_flags)); -} - -%typemap(out, noblock=1) SWIGTYPE *const& { - %set_output(SWIG_NewPointerObj(%as_voidptr(*$1), $*descriptor, $owner | %newpointer_flags)); -} - -/* Return by value */ -#ifdef __cplusplus -%typemap(out, noblock=1) SWIGTYPE { - %set_output(SWIG_NewPointerObj((new $1_ltype($1)), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags)); -} -#else -%typemap(out, noblock=1) SWIGTYPE { - %set_output(SWIG_NewPointerObj(%new_copy($1, $1_ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags)); -} -#endif - -/* ----------------------------------------------------------------------------- - * --- Variable input --- - * ----------------------------------------------------------------------------- */ - -/* memberin/globalin/varin, for fix arrays. */ - -%typemap(memberin) SWIGTYPE [ANY] { - if ($input) { - size_t ii = 0; - for (; ii < (size_t)$1_dim0; ++ii) *($1_basetype *)&$1[ii] = *(($1_basetype *)$input + ii); - } else { - %variable_nullref("$type","$name"); - } -} - -%typemap(globalin) SWIGTYPE [ANY] { - if ($input) { - size_t ii = 0; - for (; ii < (size_t)$1_dim0; ++ii) *($1_basetype *)&$1[ii] = *(($1_basetype *)$input + ii); - } else { - %variable_nullref("$type","$name"); - } -} - -%typemap(varin) SWIGTYPE [ANY] { - $basetype *inp = 0; - int res = SWIG_ConvertPtr($input, %as_voidptrptr(&inp), $descriptor, %convertptr_flags); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } else if (inp) { - size_t ii = 0; - for (; ii < (size_t)$1_dim0; ++ii) *($1_basetype *)&$1[ii] = *(($1_basetype *)inp + ii); - } else { - %variable_nullref("$type", "$name"); - } -} - - -/* memberin/globalin/varin, for fix double arrays. */ - -%typemap(memberin) SWIGTYPE [ANY][ANY] { - if ($input) { - size_t ii = 0; - for (; ii < (size_t)$1_dim0; ++ii) { - if ($input[ii]) { - size_t jj = 0; - for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = $input[ii][jj]; - } else { - %variable_nullref("$type","$name"); - } - } - } else { - %variable_nullref("$type","$name"); - } -} - -%typemap(globalin) SWIGTYPE [ANY][ANY] { - if ($input) { - size_t ii = 0; - for (; ii < (size_t)$1_dim0; ++ii) { - if ($input[ii]) { - size_t jj = 0; - for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = $input[ii][jj]; - } else { - %variable_nullref("$type","$name"); - } - } - } else { - %variable_nullref("$type","$name"); - } -} - -%typemap(varin) SWIGTYPE [ANY][ANY] { - $basetype (*inp)[$1_dim1] = 0; - int res = SWIG_ConvertPtr($input, %as_voidptrptr(&inp), $descriptor, %convertptr_flags); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } else if (inp) { - size_t ii = 0; - for (; ii < (size_t)$1_dim0; ++ii) { - if (inp[ii]) { - size_t jj = 0; - for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = inp[ii][jj]; - } else { - %variable_nullref("$type", "$name"); - } - } - } else { - %variable_nullref("$type", "$name"); - } -} - -/* Pointers, references, and variable size arrays */ - -%typemap(varin,warning=SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) SWIGTYPE * { - void *argp = 0; - int res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } - $1 = %reinterpret_cast(argp, $ltype); -} - -%typemap(varin,noblock=1,warning="462:Unable to set dimensionless array variable") SWIGTYPE [] -{ - %variable_fail(SWIG_AttributeError, "$type", "read-only $name"); -} - -%typemap(varin,warning=SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) SWIGTYPE & { - void *argp = 0; - int res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } - if (!argp) { - %variable_nullref("$type", "$name"); - } - $1 = *(%reinterpret_cast(argp, $ltype)); -} - -%typemap(varin,warning=SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) SWIGTYPE && { - void *argp = 0; - int res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } - if (!argp) { - %variable_nullref("$type", "$name"); - } - $1 = *(%reinterpret_cast(argp, $ltype)); -} - -#if defined(__cplusplus) && defined(%implicitconv_flag) -%typemap(varin,implicitconv=1) SWIGTYPE { - void *argp = 0; - int res = SWIG_ConvertPtr($input, &argp, $&descriptor, %convertptr_flags | %implicitconv_flag); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } - if (!argp) { - %variable_nullref("$type", "$name"); - } else { - $&type temp; - temp = %reinterpret_cast(argp, $&type); - $1 = *temp; - if (SWIG_IsNewObj(res)) %delete(temp); - } -} -#else -%typemap(varin) SWIGTYPE { - void *argp = 0; - int res = SWIG_ConvertPtr($input, &argp, $&descriptor, %convertptr_flags); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } - if (!argp) { - %variable_nullref("$type", "$name"); - } else { - $1 = *(%reinterpret_cast(argp, $&type)); - } -} -#endif - -/* ----------------------------------------------------------------------------- - * --- Variable output --- - * ----------------------------------------------------------------------------- */ - -/* Pointers and arrays */ -%typemap(varout, noblock=1) SWIGTYPE * { - %set_varoutput(SWIG_NewPointerObj(%as_voidptr($1), $descriptor, %newpointer_flags)); -} - -%typemap(varout, noblock=1) SWIGTYPE [] { - %set_varoutput(SWIG_NewPointerObj(%as_voidptr($1), $descriptor, %newpointer_flags)); -} - -/* References */ -%typemap(varout, noblock=1) SWIGTYPE & { - %set_varoutput(SWIG_NewPointerObj(%as_voidptr(&$1), $descriptor, %newpointer_flags)); -} - -%typemap(varout, noblock=1) SWIGTYPE && { - %set_varoutput(SWIG_NewPointerObj(%as_voidptr(&$1), $descriptor, %newpointer_flags)); -} - -/* Value */ -%typemap(varout, noblock=1) SWIGTYPE { - %set_varoutput(SWIG_NewPointerObj(%as_voidptr(&$1), $&descriptor, %newpointer_flags)); -} - -/* ------------------------------------------------------------ - * --- Typechecking rules --- - * ------------------------------------------------------------ */ - -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE * { - void *vptr = 0; - int res = SWIG_ConvertPtr($input, &vptr, $descriptor, 0); - $1 = SWIG_CheckState(res); -} - -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE *const& { - void *vptr = 0; - int res = SWIG_ConvertPtr($input, &vptr, $*descriptor, 0); - $1 = SWIG_CheckState(res); -} - -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE & { - void *vptr = 0; - int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL); - $1 = SWIG_CheckState(res); -} - -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE && { - void *vptr = 0; - int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL); - $1 = SWIG_CheckState(res); -} - -#if defined(__cplusplus) && defined(%implicitconv_flag) -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) const SWIGTYPE & { - int res = SWIG_ConvertPtr($input, 0, $descriptor, SWIG_POINTER_NO_NULL | %implicitconv_flag); - $1 = SWIG_CheckState(res); -} - -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) const SWIGTYPE && { - int res = SWIG_ConvertPtr($input, 0, $descriptor, SWIG_POINTER_NO_NULL | %implicitconv_flag); - $1 = SWIG_CheckState(res); -} - -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1,implicitconv=1) SWIGTYPE { - int res = SWIG_ConvertPtr($input, 0, $&descriptor, SWIG_POINTER_NO_NULL | %implicitconv_flag); - $1 = SWIG_CheckState(res); -} -#else -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) const SWIGTYPE & { - void *vptr = 0; - int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL); - $1 = SWIG_CheckState(res); -} - -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) const SWIGTYPE && { - void *vptr = 0; - int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL); - $1 = SWIG_CheckState(res); -} - -%typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE { - void *vptr = 0; - int res = SWIG_ConvertPtr($input, &vptr, $&descriptor, SWIG_POINTER_NO_NULL); - $1 = SWIG_CheckState(res); -} -#endif - -/* ----------------------------------------------------------------------------- - * --- Director typemaps --- * - * ----------------------------------------------------------------------------- */ - -#if defined(SWIG_DIRECTOR_TYPEMAPS) - -/* directorin */ - -%typemap(directorin,noblock=1) SWIGTYPE { - $input = SWIG_NewPointerObj((new $1_ltype(SWIG_STD_MOVE($1))), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags); -} - -%typemap(directorin,noblock=1) SWIGTYPE * { - $input = SWIG_NewPointerObj(%as_voidptr($1), $descriptor, %newpointer_flags); -} - -%typemap(directorin,noblock=1) SWIGTYPE *const& { - $input = SWIG_NewPointerObj(%as_voidptr($1), $*descriptor, %newpointer_flags); -} - -%typemap(directorin,noblock=1) SWIGTYPE & { - $input = SWIG_NewPointerObj(%as_voidptr(&$1), $descriptor, %newpointer_flags); -} - -%typemap(directorin,noblock=1) SWIGTYPE && { - $input = SWIG_NewPointerObj(%as_voidptr(&$1_name), $descriptor, %newpointer_flags); -} - -/* directorout */ - -#if defined(__cplusplus) && defined(%implicitconv_flag) -%typemap(directorout,noblock=1,implicitconv=1) SWIGTYPE (void * swig_argp, int swig_res = 0) { - swig_res = SWIG_ConvertPtr($input,&swig_argp,$&descriptor, %convertptr_flags | %implicitconv_flag); - if (!SWIG_IsOK(swig_res)) { - %dirout_fail(swig_res,"$type"); - } - $result = *(%reinterpret_cast(swig_argp, $<ype)); - if (SWIG_IsNewObj(swig_res)) %delete(%reinterpret_cast(swig_argp, $<ype)); -} -#else -%typemap(directorout,noblock=1) SWIGTYPE (void * swig_argp, int swig_res = 0) { - swig_res = SWIG_ConvertPtr($input,&swig_argp,$&descriptor, %convertptr_flags); - if (!SWIG_IsOK(swig_res)) { - %dirout_fail(swig_res,"$type"); - } - $result = *(%reinterpret_cast(swig_argp, $<ype)); -} -#endif - -%typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) - SWIGTYPE *(void *swig_argp, int swig_res, swig_owntype own) { - swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor, %convertptr_flags | SWIG_POINTER_DISOWN, &own); - if (!SWIG_IsOK(swig_res)) { - %dirout_fail(swig_res,"$type"); - } - $result = %reinterpret_cast(swig_argp, $ltype); - swig_acquire_ownership_obj(%as_voidptr($result), own /* & TODO: SWIG_POINTER_OWN */); -} -%typemap(directorfree,noblock=1,match="directorout") SWIGTYPE * { - if (director) { - SWIG_AcquirePtr($result, director->swig_release_ownership(%as_voidptr($input))); - } -} - -%typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) - SWIGTYPE *const&(void *swig_argp, int swig_res, swig_owntype own) { - swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $*descriptor, %convertptr_flags | SWIG_POINTER_DISOWN, &own); - if (!SWIG_IsOK(swig_res)) { - %dirout_fail(swig_res,"$type"); - } - $1_ltype swig_temp = new $*1_ltype(($*1_ltype)swig_argp); - swig_acquire_ownership(swig_temp); - $result = swig_temp; -} -%typemap(directorfree,noblock=1,match="directorout") SWIGTYPE *const& { - if (director) { - SWIG_AcquirePtr($result, director->swig_release_ownership(%as_voidptr(*$input))); - } -} - -%typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) - SWIGTYPE &(void *swig_argp, int swig_res, swig_owntype own) { - swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor, %convertptr_flags | SWIG_POINTER_DISOWN, &own); - if (!SWIG_IsOK(swig_res)) { - %dirout_fail(swig_res,"$type"); - } - if (!swig_argp) { %dirout_nullref("$type"); } - $result = %reinterpret_cast(swig_argp, $ltype); - swig_acquire_ownership_obj(%as_voidptr($result), own /* & TODO: SWIG_POINTER_OWN */); -} -%typemap(directorfree,noblock=1,match="directorout") SWIGTYPE & { - if (director) { - SWIG_AcquirePtr($result, director->swig_release_ownership(%as_voidptr($input))); - } -} - -%typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) - SWIGTYPE &&(void *swig_argp, int swig_res, swig_owntype own) { - swig_res = SWIG_ConvertPtrAndOwn($input, &swig_argp, $descriptor, %convertptr_flags | SWIG_POINTER_DISOWN, &own); - if (!SWIG_IsOK(swig_res)) { - %dirout_fail(swig_res,"$type"); - } - if (!swig_argp) { %dirout_nullref("$type"); } - $result = %reinterpret_cast(swig_argp, $ltype); - swig_acquire_ownership_obj(%as_voidptr($result), own /* & TODO: SWIG_POINTER_OWN */); -} -%typemap(directorfree,noblock=1,match="directorout") SWIGTYPE && { - if (director) { - SWIG_AcquirePtr($result, director->swig_release_ownership(%as_voidptr($input))); - } -} - -#endif /* SWIG_DIRECTOR_TYPEMAPS */ - - -/* ------------------------------------------------------------ - * --- Constants --- - * ------------------------------------------------------------ */ - -%typemap(constcode,noblock=1) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] { - %set_constant("$symname", SWIG_NewPointerObj(%as_voidptr($value),$descriptor,%newpointer_flags)); -} - -%typemap(constcode,noblock=1) SWIGTYPE { - %set_constant("$symname", SWIG_NewPointerObj(%as_voidptr(&$value),$&descriptor,%newpointer_flags)); -} - -/* ------------------------------------------------------------ - * --- Exception handling --- - * ------------------------------------------------------------ */ - -%typemap(throws,noblock=1) SWIGTYPE { - %raise(SWIG_NewPointerObj(%new_copy($1, $1_ltype),$&descriptor,SWIG_POINTER_OWN), "$type", $&descriptor); -} - -%typemap(throws,noblock=1) SWIGTYPE * { - %raise(SWIG_NewPointerObj(%as_voidptr($1),$descriptor,0), "$type", $descriptor); -} - -%typemap(throws,noblock=1) SWIGTYPE [ANY] { - %raise(SWIG_NewPointerObj(%as_voidptr($1),$descriptor,0), "$type", $descriptor); -} - -%typemap(throws,noblock=1) SWIGTYPE & { - %raise(SWIG_NewPointerObj(%as_voidptr(&$1),$descriptor,0), "$type", $descriptor); -} - -%typemap(throws,noblock=1) SWIGTYPE && { - %raise(SWIG_NewPointerObj(%as_voidptr(&$1),$descriptor,0), "$type", $descriptor); -} - -%typemap(throws,noblock=1) (...) { - SWIG_exception_fail(SWIG_RuntimeError,"unknown exception"); -} - -/* ------------------------------------------------------------ - * --- CLASS::* typemaps --- - * ------------------------------------------------------------ */ - -%typemap(in) SWIGTYPE (CLASS::*) { - int res = SWIG_ConvertMember($input, %as_voidptr(&$1), sizeof($1),$descriptor); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type",$symname, $argnum); - } -} - -%typemap(out,noblock=1) SWIGTYPE (CLASS::*) { - %set_output(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($1), $descriptor)); -} - -%typemap(varin) SWIGTYPE (CLASS::*) { - int res = SWIG_ConvertMember($input,%as_voidptr(&$1), sizeof($1), $descriptor); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } -} - -%typemap(varout,noblock=1) SWIGTYPE (CLASS::*) { - %set_varoutput(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($1), $descriptor)); -} - -%typemap(constcode,noblock=1) SWIGTYPE (CLASS::*) { - %set_constant("$symname", SWIG_NewMemberObj(%as_voidptr(&$value), sizeof($value), $descriptor)); -} - -#if defined(SWIG_DIRECTOR_TYPEMAPS) - -/* directorin */ - -%typemap(directorin,noblock=1) SWIGTYPE (CLASS::*) { - $input = SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($1), $descriptor); -} - -/* directorout */ - -%typemap(directorout) SWIGTYPE (CLASS::*) { - int swig_res = SWIG_ConvertMember($input,%as_voidptr(&$result), sizeof($result), $descriptor); - if (!SWIG_IsOK(swig_res)) { - %dirout_fail(swig_res,"$type"); - } -} -#endif - -%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } -%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } - -/* ------------------------------------------------------------ - * --- function ptr typemaps --- - * ------------------------------------------------------------ */ - -/* - ISO C++ doesn't allow direct casting of a function ptr to a object - ptr. So, maybe the ptr sizes are not the same, and we need to take - some providences. - */ -%typemap(in) SWIGTYPE ((*)(ANY)) { - int res = SWIG_ConvertFunctionPtr($input, (void**)(&$1), $descriptor); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type",$symname, $argnum); - } -} - -%typecheck(SWIG_TYPECHECK_POINTER,noblock=1) SWIGTYPE ((*)(ANY)) { - void *ptr = 0; - int res = SWIG_ConvertFunctionPtr($input, &ptr, $descriptor); - $1 = SWIG_CheckState(res); -} - - -%typemap(out, noblock=1) SWIGTYPE ((*)(ANY)) { - %set_output(SWIG_NewFunctionPtrObj((void *)($1), $descriptor)); -} - -%typemap(varin) SWIGTYPE ((*)(ANY)) { - int res = SWIG_ConvertFunctionPtr($input, (void**)(&$1), $descriptor); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } -} - -%typemap(varout,noblock=1) SWIGTYPE ((*)(ANY)) { - %set_varoutput(SWIG_NewFunctionPtrObj((void *)($1), $descriptor)); -} - -%typemap(constcode, noblock=1) SWIGTYPE ((*)(ANY)){ - %set_constant("$symname", SWIG_NewFunctionPtrObj((void *)$value, $descriptor)); -} -%typemap(constcode) SWIGTYPE ((* const)(ANY)) = SWIGTYPE ((*)(ANY)); - -#if defined(SWIG_DIRECTOR_TYPEMAPS) - -/* directorin */ - -%typemap(directorin,noblock=1) SWIGTYPE ((*)(ANY)) { - $input = SWIG_NewFunctionPtrObj((void*)($1), $descriptor); -} - -/* directorout */ - -%typemap(directorout) SWIGTYPE ((*)(ANY)) { - int swig_res = SWIG_ConvertFunctionPtr($input,(void**)(&$result),$descriptor); - if (!SWIG_IsOK(swig_res)) { - %dirout_fail(swig_res,"$type"); - } -} -#endif - -%apply SWIGTYPE ((*)(ANY)) { SWIGTYPE ((* const)(ANY)) } - -%apply SWIGTYPE * { SWIGTYPE *const } - -/* ------------------------------------------------------------ - * --- Special typemaps --- - * ------------------------------------------------------------ */ - -/* DISOWN typemap */ - -%typemap(in, noblock=1) SWIGTYPE *DISOWN (int res = 0) { - res = SWIG_ConvertPtr($input, %as_voidptrptr(&$1), $descriptor, SWIG_POINTER_DISOWN | %convertptr_flags); - if (!SWIG_IsOK(res)) { - %argument_fail(res,"$type", $symname, $argnum); - } -} - -%typemap(varin) SWIGTYPE *DISOWN { - void *temp = 0; - int res = SWIG_ConvertPtr($input, &temp, $descriptor, SWIG_POINTER_DISOWN | %convertptr_flags); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } - $1 = ($ltype) temp; -} - -/* DYNAMIC typemap */ - -%typemap(out,noblock=1) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { - %set_output(SWIG_NewPointerObj(%as_voidptr($1), SWIG_TypeDynamicCast($descriptor, %as_voidptrptr(&$1)), $owner | %newpointer_flags)); -} - -/* INSTANCE typemap */ - -#ifdef __cplusplus -%typemap(out,noblock=1) SWIGTYPE INSTANCE { - %set_output(SWIG_NewInstanceObj((new $1_ltype($1)), $&1_descriptor, SWIG_POINTER_OWN | %newinstance_flags)); -} -#else -%typemap(out,noblock=1) SWIGTYPE INSTANCE { - %set_output(SWIG_NewInstanceObj(%new_copy($1, $1_ltype), $&1_descriptor, SWIG_POINTER_OWN | %newinstance_flags)); -} -#endif - -%typemap(out,noblock=1) SWIGTYPE *INSTANCE, SWIGTYPE &INSTANCE, SWIGTYPE INSTANCE[] { - %set_output(SWIG_NewInstanceObj(%as_voidptr($1), $1_descriptor, $owner | %newinstance_flags)); -} - -%typemap(varout,noblock=1) SWIGTYPE *INSTANCE, SWIGTYPE INSTANCE[] { - %set_varoutput(SWIG_NewInstanceObj(%as_voidptr($1), $1_descriptor, %newinstance_flags)); -} - -%typemap(varout,noblock=1) SWIGTYPE &INSTANCE { - %set_varoutput(SWIG_NewInstanceObj(%as_voidptr($1), $1_descriptor, %newinstance_flags)); -} - -%typemap(varout,noblock=1) SWIGTYPE INSTANCE { - %set_varoutput(SWIG_NewInstanceObj(%as_voidptr(&$1), $&1_descriptor, %newinstance_flags)); -} - diff --git a/contrib/tools/swig/Lib/typemaps/swigtypemaps.swg b/contrib/tools/swig/Lib/typemaps/swigtypemaps.swg deleted file mode 100644 index 733e5acd0fc..00000000000 --- a/contrib/tools/swig/Lib/typemaps/swigtypemaps.swg +++ /dev/null @@ -1,168 +0,0 @@ -/* ----------------------------------------------------------------------------- - * swigtypemaps.swg - * - * Unified Typemap Library frontend - * ----------------------------------------------------------------------------- */ - -/* - This file provides the frontend to the Unified Typemap Library. - - When using this library in a SWIG target language, you need to - define a minimum set of fragments, specialize a couple of macros, - and then include this file. - - Typically you will create a 'mytypemaps.swg' file in each target - language, where you will have the following sections: - - === mytypemaps.swg === - - // Fragment section - %include <typemaps/fragments.swg> - <include target language fragments> - - // Unified typemap section - <specialized the typemap library macros> - %include <typemaps/swigtypemaps.swg> - - // Local typemap section - <add/replace extra target language typemaps> - - === mytypemaps.swg === - - While we add more docs, please take a look at the following cases - to see how you specialized the unified typemap library for a new - target language: - - Lib/python/pytypemaps.swg - Lib/tcl/tcltypemaps.swg - Lib/ruby/rubytypemaps.swg - Lib/perl5/perltypemaps.swg - -*/ - -#define SWIGUTL SWIGUTL - -/* ----------------------------------------------------------------------------- - * Language specialization section. - * - * Tune these macros for each language as needed. - * ----------------------------------------------------------------------------- */ - -/* - The SWIG target language object must be provided. - For example in python you define: - - #define SWIG_Object PyObject * -*/ - -#if !defined(SWIG_Object) -#error "SWIG_Object must be defined as the SWIG target language object" -#endif - -/*==== flags for new/convert methods ====*/ - - -#ifndef %convertptr_flags -%define %convertptr_flags 0 %enddef -#endif - -#ifndef %newpointer_flags -%define %newpointer_flags 0 %enddef -#endif - -#ifndef %newinstance_flags -%define %newinstance_flags 0 %enddef -#endif - -/*==== set output ====*/ - -#ifndef %set_output -/* simple set output operation */ -#define %set_output(obj) $result = obj -#endif - -/*==== set variable output ====*/ - -#ifndef %set_varoutput -/* simple set varoutput operation */ -#define %set_varoutput(obj) $result = obj -#endif - -/*==== append output ====*/ - -#ifndef %append_output -#if defined(SWIG_AppendOutput) -/* simple append operation */ -#define %append_output(obj) $result = SWIG_AppendOutput($result,obj) -#else -#error "Language must define SWIG_AppendOutput or %append_output" -#endif -#endif - -/*==== set constant ====*/ - -#ifndef %set_constant -#if defined(SWIG_SetConstant) -/* simple set constant operation */ -#define %set_constant(name,value) SWIG_SetConstant(name,value) -#else -#error "Language must define SWIG_SetConstant or %set_constant" -#endif -#endif - -/*==== raise an exception ====*/ - -#ifndef %raise -#if defined(SWIG_Raise) -/* simple raise operation */ -#define %raise(obj, type, desc) SWIG_Raise(obj, type, desc); SWIG_fail -#else -#error "Language must define SWIG_Raise or %raise" -#endif -#endif - -/*==== director output exception ====*/ - -#if defined(SWIG_DIRECTOR_TYPEMAPS) -#ifndef SWIG_DirOutFail -#define SWIG_DirOutFail(code, msg) Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(code), msg) -#endif -#endif - - -/* ----------------------------------------------------------------------------- - * Language independent definitions - * ----------------------------------------------------------------------------- */ - -#define %error_block(Block...) %block(Block) -#define %default_code(code) SWIG_ArgError(code) -#define %argument_fail(code, type, name, argn) SWIG_exception_fail(%default_code(code), %argfail_fmt(type, name, argn)) -#define %argument_nullref(type, name, argn) SWIG_exception_fail(SWIG_ValueError, %argnullref_fmt(type, name, argn)) -#define %variable_fail(code, type, name) SWIG_exception_fail(%default_code(code), %varfail_fmt(type, name)) -#define %variable_nullref(type, name) SWIG_exception_fail(SWIG_ValueError, %varnullref_fmt(type, name)) -#define %releasenotowned_fail(code, type, name, argn) SWIG_exception_fail(%default_code(code), %releasenotownedfail_fmt(type, name, argn)) - -#if defined(SWIG_DIRECTOR_TYPEMAPS) -#define %dirout_fail(code, type) SWIG_DirOutFail(%default_code(code), %outfail_fmt(type)) -#define %dirout_nullref(type) SWIG_DirOutFail(SWIG_ValueError, %outnullref_fmt(type)) -#endif - -/* ----------------------------------------------------------------------------- - * All the typemaps - * ----------------------------------------------------------------------------- */ - - -%include <typemaps/fragments.swg> -%include <typemaps/exception.swg> -%include <typemaps/swigtype.swg> -%include <typemaps/void.swg> -%include <typemaps/swigobject.swg> -%include <typemaps/valtypes.swg> -%include <typemaps/ptrtypes.swg> -%include <typemaps/inoutlist.swg> -%include <typemaps/primtypes.swg> -%include <typemaps/string.swg> -%include <typemaps/misctypes.swg> -%include <typemaps/enumint.swg> - - diff --git a/contrib/tools/swig/Lib/typemaps/typemaps.swg b/contrib/tools/swig/Lib/typemaps/typemaps.swg deleted file mode 100644 index 4629e8dfa0f..00000000000 --- a/contrib/tools/swig/Lib/typemaps/typemaps.swg +++ /dev/null @@ -1,157 +0,0 @@ -/* ----------------------------------------------------------------------------- - * typemaps.swg - * - * Tcl Pointer handling - * - * These mappings provide support for input/output arguments and common - * uses for C/C++ pointers. - * ----------------------------------------------------------------------------- */ - -// INPUT typemaps. -// These remap a C pointer to be an "INPUT" value which is passed by value -// instead of reference. - -/* -The following methods can be applied to turn a pointer into a simple -"input" value. That is, instead of passing a pointer to an object, -you would use a real value instead. - - int *INPUT - short *INPUT - long *INPUT - long long *INPUT - unsigned int *INPUT - unsigned short *INPUT - unsigned long *INPUT - unsigned long long *INPUT - unsigned char *INPUT - bool *INPUT - float *INPUT - double *INPUT - -To use these, suppose you had a C function like this : - - double fadd(double *a, double *b) { - return *a+*b; - } - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - double fadd(double *INPUT, double *INPUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *INPUT { double *a, double *b }; - double fadd(double *a, double *b); - -*/ - -// OUTPUT typemaps. These typemaps are used for parameters that -// are output only. The output value is appended to the result as -// a list element. - -/* -The following methods can be applied to turn a pointer into an "output" -value. When calling a function, no input value would be given for -a parameter, but an output value would be returned. In the case of -multiple output values, they are returned in the form of a Tcl tuple. - - int *OUTPUT - short *OUTPUT - long *OUTPUT - long long *OUTPUT - unsigned int *OUTPUT - unsigned short *OUTPUT - unsigned long *OUTPUT - unsigned long long *OUTPUT - unsigned char *OUTPUT - bool *OUTPUT - float *OUTPUT - double *OUTPUT - -For example, suppose you were trying to wrap the modf() function in the -C math library which splits x into integral and fractional parts (and -returns the integer part in one of its parameters).K: - - double modf(double x, double *ip); - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - double modf(double x, double *OUTPUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *OUTPUT { double *ip }; - double modf(double x, double *ip); - -The Tcl output of the function would be a tuple containing both -output values. - -*/ - -// INOUT -// Mappings for an argument that is both an input and output -// parameter - -/* -The following methods can be applied to make a function parameter both -an input and output value. This combines the behavior of both the -"INPUT" and "OUTPUT" methods described earlier. Output values are -returned in the form of a Tcl tuple. - - int *INOUT - short *INOUT - long *INOUT - long long *INOUT - unsigned int *INOUT - unsigned short *INOUT - unsigned long *INOUT - unsigned long long *INOUT - unsigned char *INOUT - bool *INOUT - float *INOUT - double *INOUT - -For example, suppose you were trying to wrap the following function : - - void neg(double *x) { - *x = -(*x); - } - -You could wrap it with SWIG as follows : - - %include <typemaps.i> - void neg(double *INOUT); - -or you can use the %apply directive : - - %include <typemaps.i> - %apply double *INOUT { double *x }; - void neg(double *x); - -Unlike C, this mapping does not directly modify the input value (since -this makes no sense in Tcl). Rather, the modified input value shows -up as the return value of the function. Thus, to apply this function -to a Tcl variable you might do this : - - x = neg(x) - -Note : previous versions of SWIG used the symbol 'BOTH' to mark -input/output arguments. This is still supported, but will be slowly -phased out in future releases. - -*/ - - -#if defined(SWIG_INOUT_NODEF) - -%apply_checkctypes(%typemaps_inoutn) - -%apply size_t& { std::size_t& }; -%apply ptrdiff_t& { std::ptrdiff_t& }; - -#endif diff --git a/contrib/tools/swig/Lib/typemaps/valtypes.swg b/contrib/tools/swig/Lib/typemaps/valtypes.swg deleted file mode 100644 index f2f34acfca4..00000000000 --- a/contrib/tools/swig/Lib/typemaps/valtypes.swg +++ /dev/null @@ -1,215 +0,0 @@ -/*--------------------------------------------------------------------- - * Value typemaps (Type, const Type&) for value types, such as - * fundamental types (int, double), that define the AsVal/From - * methods. - * - * To apply them, just use one of the following macros: - * - * %typemaps_from(FromMeth, FromFrag, Type) - * %typemaps_asval(CheckCode, AsValMeth, AsValFrag, Type) - * %typemaps_asvalfrom(CheckCode, AsValMeth, FromMeth, AsValFrag, FromFrag, Type) - * - * or the simpler and normalize form: - * - * %typemaps_asvalfromn(CheckCode, Type) - * - * Also, you can use the individual typemap definitions: - * - * %value_in_typemap(asval_meth,frag,Type) - * %value_varin_typemap(asval_meth,frag,Type) - * %value_typecheck_typemap(checkcode,asval_meth,frag,Type) - * %value_directorout_typemap(asval_meth,frag,Type) - * - * %value_out_typemap(from_meth,frag,Type) - * %value_varout_typemap(from_meth,frag,Type) - * %value_constcode_typemap(from_meth,frag,Type) - * %value_directorin_typemap(from_meth,frag,Type) - * %value_throws_typemap(from_meth,frag,Type) - * - *---------------------------------------------------------------------*/ - -/* in */ - -%define %value_in_typemap(asval_meth,frag,Type...) - %typemap(in,noblock=1,fragment=frag) Type (Type val, int ecode = 0) { - ecode = asval_meth($input, &val); - if (!SWIG_IsOK(ecode)) { - %argument_fail(ecode, "$ltype", $symname, $argnum); - } - $1 = %static_cast(val,$ltype); - } - %typemap(freearg) Type "" - %typemap(in,noblock=1,fragment=frag) const Type & ($*ltype temp, Type val, int ecode = 0) { - ecode = asval_meth($input, &val); - if (!SWIG_IsOK(ecode)) { - %argument_fail(ecode, "$*ltype", $symname, $argnum); - } - temp = %static_cast(val, $*ltype); - $1 = &temp; - } - %typemap(freearg) const Type& "" -%enddef - -/* out */ - -%define %value_out_typemap(from_meth,frag,Type...) - %typemap(out,noblock=1,fragment=frag) Type, const Type { - %set_output(from_meth(%static_cast($1,Type))); - } - %typemap(out,noblock=1,fragment=frag) const Type& { - %set_output(from_meth(%static_cast(*$1,Type))); - } -%enddef - -/* varin */ - -%define %value_varin_typemap(asval_meth,frag,Type...) - %typemap(varin,fragment=frag) Type { - Type val; - int res = asval_meth($input, &val); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } - $1 = %static_cast(val,$ltype); - } -%enddef - -/* varout */ - -%define %value_varout_typemap(from_meth,frag,Type...) - %typemap(varout,noblock=1,fragment=frag) Type, const Type& { - %set_varoutput(from_meth(%static_cast($1,Type))); - } -%enddef - -/* constant installation code */ - -%define %value_constcode_typemap(from_meth,frag,Type...) - %typemap(constcode,noblock=1,fragment=frag) Type { - %set_constant("$symname", from_meth(%static_cast($value,Type))); - } -%enddef - - -#if defined(SWIG_DIRECTOR_TYPEMAPS) - -/* directorin */ - -%define %value_directorin_typemap(from_meth,frag,Type...) - %typemap(directorin,noblock=1,fragment=frag) Type *DIRECTORIN { - $input = from_meth(%static_cast(*$1,Type)); - } - %typemap(directorin,noblock=1,fragment=frag) Type, const Type& { - $input = from_meth(%static_cast($1,Type)); - } -%enddef - -/* directorout */ - -%define %value_directorout_typemap(asval_meth,frag,Type...) - %typemap(directorargout,noblock=1,fragment=frag) Type *DIRECTOROUT(Type swig_val, int swig_res) { - swig_res = asval_meth($result, &swig_val); - if (!SWIG_IsOK(swig_res)) { - %dirout_fail(swig_res, "$type"); - } - *$1 = swig_val; - } - %typemap(directorout,noblock=1,fragment=frag) Type { - Type swig_val; - int swig_res = asval_meth($input, &swig_val); - if (!SWIG_IsOK(swig_res)) { - %dirout_fail(swig_res, "$type"); - } - $result = %static_cast(swig_val,$type); - } - %typemap(directorout,noblock=1,fragment=frag,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) const Type& { - Type swig_val; - int swig_res = asval_meth($input, &swig_val); - if (!SWIG_IsOK(swig_res)) { - %dirout_fail(swig_res, "$type"); - } - $basetype *temp = new $basetype(($basetype)swig_val); - swig_acquire_ownership(temp); - $result = temp; - } - %typemap(directorfree,noblock=1) const Type & { - if (director) { - director->swig_release_ownership(%as_voidptr($input)); - } - } - %typemap(directorout,fragment=frag) Type &DIRECTOROUT = Type -%enddef - -#else - -#define %value_directorin_typemap(from_meth,frag,Type...) -#define %value_directorout_typemap(asval_meth,frag,Type...) - -#endif /* SWIG_DIRECTOR_TYPEMAPS */ - - -/* throws */ - -%define %value_throws_typemap(from_meth,frag,Type...) - %typemap(throws,noblock=1,fragment=frag) Type { - %raise(from_meth(%static_cast($1,Type)), "$type", 0); - } -%enddef - -/* typecheck */ - -%define %value_typecheck_typemap(check,asval_meth,frag,Type...) - %typemap(typecheck,precedence=check,fragment=frag) Type, const Type& { - int res = asval_meth($input, NULL); - $1 = SWIG_CheckState(res); - } -%enddef - -/*--------------------------------------------------------------------- - * typemap definition for types with AsVal methods - *---------------------------------------------------------------------*/ -%define %typemaps_asval(CheckCode, AsValMeth, AsValFrag, Type...) - %value_in_typemap(%arg(AsValMeth), %arg(AsValFrag), Type); - %value_varin_typemap(%arg(AsValMeth), %arg(AsValFrag), Type); - %value_directorout_typemap(%arg(AsValMeth), %arg(AsValFrag), Type); - %value_typecheck_typemap(%arg(CheckCode), %arg(AsValMeth), %arg(AsValFrag), Type); - %value_input_typemap(%arg(CheckCode), %arg(AsValMeth), %arg(AsValFrag), Type); -%enddef - - -/*--------------------------------------------------------------------- - * typemap definition for types with from method - *---------------------------------------------------------------------*/ -%define %typemaps_from(FromMeth, FromFrag, Type...) - %value_out_typemap(%arg(FromMeth), %arg(FromFrag), Type); - %value_varout_typemap(%arg(FromMeth), %arg(FromFrag), Type); - %value_constcode_typemap(%arg(FromMeth), %arg(FromFrag), Type); - %value_directorin_typemap(%arg(FromMeth), %arg(FromFrag), Type); - %value_throws_typemap(%arg(FromMeth), %arg(FromFrag), Type); - %value_output_typemap(%arg(FromMeth), %arg(FromFrag), Type); -%enddef - - -/*--------------------------------------------------------------------- - * typemap definition for types with alval/from method - *---------------------------------------------------------------------*/ - -%define %typemaps_asvalfrom(CheckCode, AsValMeth, FromMeth, - AsValFrag, FromFrag, Type...) - %typemaps_asval(%arg(CheckCode), %arg(AsValMeth), %arg(AsValFrag), Type); - %typemaps_from(%arg(FromMeth), %arg(FromFrag), Type); - %value_inout_typemap(Type); -%enddef - - -/*--------------------------------------------------------------------- - * typemap definition for types with for 'normalized' asval/from methods - *---------------------------------------------------------------------*/ -%define %typemaps_asvalfromn(CheckCode, Type...) - %typemaps_asvalfrom(%arg(CheckCode), - SWIG_AsVal(Type), - SWIG_From(Type), - %arg(SWIG_AsVal_frag(Type)), - %arg(SWIG_From_frag(Type)), - Type); -%enddef diff --git a/contrib/tools/swig/Lib/typemaps/void.swg b/contrib/tools/swig/Lib/typemaps/void.swg deleted file mode 100644 index 795992bf480..00000000000 --- a/contrib/tools/swig/Lib/typemaps/void.swg +++ /dev/null @@ -1,84 +0,0 @@ -/* ------------------------------------------------------------ - * Void * - Accepts any kind of pointer - * ------------------------------------------------------------ */ - -/* in */ - -%typemap(in,noblock=1) void * (int res) { - res = SWIG_ConvertPtr($input,%as_voidptrptr(&$1), 0, $disown); - if (!SWIG_IsOK(res)) { - %argument_fail(res, "$type", $symname, $argnum); - } -} -%typemap(freearg) void * "" - -%typemap(in,noblock=1) void * const& ($*ltype temp = 0, int res) { - res = SWIG_ConvertPtr($input, %as_voidptrptr(&temp), 0, $disown); - if (!SWIG_IsOK(res)) { - %argument_fail(res, "Stype", $symname, $argnum); - } - $1 = &temp; -} -%typemap(freearg) void * const& "" - - -/* out */ - -#if defined(VOID_Object) -%typemap(out,noblock=1) void { $result = VOID_Object; } -#else -%typemap(out,noblock=1) void {} -#endif - -/* varin */ - -%typemap(varin) void * { - void *temp = 0; - int res = SWIG_ConvertPtr($input, &temp, 0, SWIG_POINTER_DISOWN); - if (!SWIG_IsOK(res)) { - %variable_fail(res, "$type", "$name"); - } - $1 = ($1_ltype) temp; -} - -/* typecheck */ - -%typecheck(SWIG_TYPECHECK_VOIDPTR, noblock=1) void * -{ - void *ptr = 0; - int res = SWIG_ConvertPtr($input, &ptr, 0, 0); - $1 = SWIG_CheckState(res); -} - -#if defined(SWIG_DIRECTOR_TYPEMAPS) - -/* directorin */ - -%typemap(directorin,noblock=1) void *, void const*, void *const, void const *const, - void const *&, void *const &, void const *const & { - $input = SWIG_NewPointerObj(%as_voidptr($1), $descriptor, %newpointer_flags); -} - -/* directorout */ - -%typemap(directorout,noblock=1) void * (void *argp, int res) { - res = SWIG_ConvertPtr($input, &argp, 0, 0); - if (!SWIG_IsOK(res)) { - %dirout_fail(res,"$type"); - } - $result = %reinterpret_cast(argp, $ltype); -} - -%typemap(directorout,noblock=1,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) void * const& (void *argp, int res) { - res = SWIG_ConvertPtr($input, &argp, 0, $disown); - if (!SWIG_IsOK(res)) { - %dirout_fail(res,"$type"); - } - static $*ltype temp = %reinterpret_cast(argp, $*ltype); - $result = &temp; -} - - - -#endif /* SWIG_DIRECTOR_TYPEMAPS */ - diff --git a/contrib/tools/swig/README b/contrib/tools/swig/README deleted file mode 100644 index e499e7605e6..00000000000 --- a/contrib/tools/swig/README +++ /dev/null @@ -1,139 +0,0 @@ -SWIG (Simplified Wrapper and Interface Generator) - -Tagline: SWIG is a compiler that integrates C and C++ with languages - including Perl, Python, Tcl, Ruby, PHP, Java, C#, D, Go, Lua, - Octave, R, Scheme (Guile, MzScheme/Racket), Scilab, Ocaml. - SWIG can also export its parse tree into XML. - -SWIG reads annotated C/C++ header files and creates wrapper code (glue -code) in order to make the corresponding C/C++ libraries available to -the listed languages, or to extend C/C++ programs with a scripting -language. - -Up-to-date SWIG related information can be found at - - https://www.swig.org - -A SWIG FAQ and other hints can be found on the SWIG Wiki: - - https://github.com/swig/swig/wiki - -License -======= -Please see the LICENSE file for details of the SWIG license. For -further insight into the license including the license of SWIG's -output code, please visit - - https://www.swig.org/legal.html - -Release Notes -============= -Please see the CHANGES.current file for a detailed list of bug fixes and -new features for the current release. The CHANGES file contains bug fixes -and new features for older versions. A summary of changes in each release -can be found in the RELEASENOTES file. - -Documentation -============= -The Doc/Manual directory contains the most recent set of updated -documentation for this release. The documentation is available in -three different formats, each of which contains identical content. -These format are, pdf (Doc/Manual/SWIGDocumentation.pdf), single -page html (Doc/Manual/SWIGDocumentation.html) or multiple page html -(other files in Doc/Manual). Please select your chosen format and -copy/install to wherever takes your fancy. - -There is some technical developer documentation available in the -Doc/Devel subdirectory. This is not necessarily up-to-date, but it -has some information on SWIG internals. - -Documentation is also online at https://www.swig.org/doc.html. - -Backwards Compatibility -======================= -The developers strive their best to preserve backwards compatibility -between releases, but this is not always possible as the overriding -aim is to provide the best wrapping experience. Where backwards -compatibility is known to be broken, it is clearly marked as an -incompatibility in the CHANGES and CHANGES.current files. - -See the documentation for details of the SWIG_VERSION preprocessor -symbol if you have backward compatibility issues and need to use more -than one version of SWIG. - -Installation -============ -Please read the Doc/Manual/Preface.html#Preface_installation for -full installation instructions for Windows, Unix and Mac OS X -using the release tarball/zip file. The INSTALL file has generic -build and installation instructions for Unix users. -Users wishing to build and install code from Github should -visit https://swig.org/svn.html to obtain the more detailed -instructions required for building code obtained from Github - extra -steps are required compared to building from the release tarball. - -Testing -======= -The typical 'make -k check' can be performed on Unix operating systems. -Please read Doc/Manual/Preface.html#Preface_testing for details. - -Examples -======== -The Examples directory contains a variety of examples of using SWIG -and it has some browsable documentation. Simply point your browser to -the file "Example/index.html". - -The Examples directory also includes Visual C++ project 6 (.dsp) files for -building some of the examples on Windows. Later versions of Visual Studio -will convert these old style project files into a current solution file. - -Known Issues -============ -There are minor known bugs, details of which are in the bug tracker, see -https://www.swig.org/bugs.html. - -Troubleshooting -=============== -In order to operate correctly, SWIG relies upon a set of library -files. If after building SWIG, you get error messages like this, - - $ swig foo.i - :1. Unable to find 'swig.swg' - :3. Unable to find 'tcl8.swg' - -it means that SWIG has either been incorrectly configured or -installed. To fix this: - - 1. Make sure you remembered to do a 'make install' and that - the installation actually worked. Make sure you have - write permission on the install directory. - - 2. If that doesn't work, type 'swig -swiglib' to find out - where SWIG thinks its library is located. - - 3. If the location is not where you expect, perhaps - you supplied a bad option to configure. Use - ./configure --prefix=pathname to set the SWIG install - location. Also, make sure you don't include a shell - escape character such as ~ when you specify the path. - - 4. The SWIG library can be changed by setting the SWIG_LIB - environment variable. However, you really shouldn't - have to do this. - -If you are having other troubles, you might look at the SWIG Wiki at -https://github.com/swig/swig/wiki. - -Participate! -============ -Please report any errors and submit patches (if possible)! We only -have access to a limited variety of hardware (Linux, Solaris, OS-X, -and Windows). All contributions help. - -If you would like to join the SWIG development team or contribute a -language module to the distribution, please contact the swig-devel -mailing list, details at https://www.swig.org/mail.html. - - - -- The SWIG Maintainers - diff --git a/contrib/tools/swig/RELEASENOTES b/contrib/tools/swig/RELEASENOTES deleted file mode 100644 index 493f1995494..00000000000 --- a/contrib/tools/swig/RELEASENOTES +++ /dev/null @@ -1,494 +0,0 @@ -This file contains a brief overview of the changes made in each release. -A detailed description of changes are available in the CHANGES.current -and CHANGES files. - -Release Notes -============= -Detailed release notes are available with the release and are also -published on the SWIG web site at https://swig.org/release.html. - -SWIG-4.1.1 summary: -- Couple of stability fixes. -- Stability fix in ccache-swig when calculating hashes of inputs. -- Some template handling improvements. -- R - minor fixes plus deprecation for rtypecheck typemaps being optional. - -SWIG-4.1.0 summary: -- Add Javascript Node v12-v18 support, remove support prior to v6. -- Octave 6.0 to 6.4 support added. -- Add PHP 8 support. -- PHP wrapping is now done entirely via PHP's C API - no more .php wrapper. -- Perl 5.8.0 is now the oldest version SWIG supports. -- Python 3.3 is now the oldest Python 3 version SWIG supports. -- Python 3.9-3.11 support added. -- Various memory leak fixes in Python generated code. -- Scilab 5.5-6.1 support improved. -- Many improvements for each and every target language. -- Various preprocessor expression handling improvements. -- Improved C99, C++11, C++14, C++17 support. Start adding C++20 standard. -- Make SWIG much more move semantics friendly. -- Add C++ std::unique_ptr support. -- Few minor C++ template handling improvements. -- Various C++ using declaration fixes. -- Few fixes for handling Doxygen comments. -- GitHub Actions is now used instead of Travis CI for continuous integration. -- Add building SWIG using CMake as a secondary build system. -- Update optional SWIG build dependency for regex support from PCRE to PCRE2. - -SWIG-4.0.2 summary: -- A few fixes around doxygen comment handling. -- Ruby 2.7 support added. -- Various minor improvements to C#, D, Java, OCaml, Octave, Python, - R, Ruby. -- Considerable performance improvement running SWIG on large - interface files. - -SWIG-4.0.1 summary: -- SWIG now cleans up on error by removing all generated files. -- Add Python 3.8 support. -- Python Sphinx compatibility added for Doxygen comments. -- Some minor regressions introduced in 4.0.0 were fixed. -- Fix some C++17 compatibility problems in Python and Ruby generated - code. -- Minor improvements/fixes for C#, Java, Javascript, Lua, MzScheme, - Ocaml, Octave and Python. - -SWIG-4.0.0 summary: -- Support for Doxygen documentation comments which are parsed and - converted into JavaDoc or PyDoc comments. -- STL wrappers improved for C#, Java and Ruby. -- C++11 STL containers added for Java, Python and Ruby. -- Improved support for parsing C++11 and C++14 code. -- Various fixes for shared_ptr. -- Various C preprocessor corner case fixes. -- Corner case fixes for member function pointers. -- Python module overhaul by simplifying the generated code and turning - most optimizations on by default. -- %template improvements wrt scoping to align with C++ explicit - template instantiations. -- Added support for a command-line options file (sometimes called a - response file). -- Numerous enhancements and fixes for all supported target languages. -- SWIG now classifies the status of target languages into either - 'Experimental' or 'Supported' to indicate the expected maturity - level. -- Support for CFFI, Allegrocl, Chicken, CLISP, S-EXP, UFFI, Pike, - Modula3 has been removed. -- Octave 4.4-5.1 support added. -- PHP5 support removed, PHP7 is now the supported PHP version. -- Minimum Python version required is now 2.7, 3.2-3.7 are the only - other versions supported. -- Added support for Javascript NodeJS versions 2-10. -- OCaml support is much improved and updated, minimum OCaml version - required is now 3.12.0. - -SWIG-3.0.12 summary: -- Add support for Octave-4.2. -- Enhance %extend to support template functions. -- Language specific enhancements and fixes for C#, D, Guile, Java, PHP7. - -SWIG-3.0.11 summary: -- PHP 7 support added. -- C++11 alias templates and type aliasing support added. -- Minor fixes and enhancements for C# Go Guile Java Javascript Octave - PHP Python R Ruby Scilab XML. - -SWIG-3.0.10 summary: -- Regression fixes for smart pointers and importing Python modules. - -SWIG-3.0.9 summary: -- Add support for Python's implicit namespace packages. -- Fixes to support Go 1.6. -- C++11 std::array support added for Java. -- Improved C++ multiple inheritance support for Java/C# wrappers. -- Various other minor fixes and improvements for C#, D, Go, Java, - Javascript, Lua, Python, R, Ruby, Scilab. - -SWIG-3.0.8 summary: -- pdf documentation enhancements. -- Various Python 3.5 issues fixed. -- std::array support added for Ruby and Python. -- shared_ptr support added for Ruby. -- Minor improvements for CFFI, Go, Java, Perl, Python, Ruby. - -SWIG-3.0.7 summary: -- Add support for Octave-4.0.0. -- Remove potential Android security exploit in generated Java classes. -- Minor new features and bug fixes. - -SWIG-3.0.6 summary: -- Stability and regression fixes. -- Fixed parsing of C++ corner cases. -- Language improvements and bug fixes for C#, Go, Java, Lua, Python, R. - -SWIG-3.0.5 summary: -- Added support for Scilab. -- Important Python regression fix when wrapping C++ default arguments. -- Minor improvements for C#, Go, Octave, PHP and Python. - -SWIG-3.0.4 summary: -- Python regression fix when wrapping C++ default arguments. -- Improved error messages. - -SWIG-3.0.3 summary: -- Add support for C++11 strongly typed enumerations. -- Numerous bug fixes and minor enhancements for C#, D, Go, Java, - Javascript, PHP, Perl and Python wrappers. - -SWIG-3.0.2 summary: -- Bug fix during install and a couple of other minor changes. - -SWIG-3.0.1 summary: -- Javascript module added. This supports JavascriptCore (Safari/Webkit), - v8 (Chromium) and node.js currently. -- A few notable regressions introduced in 3.0.0 have been fixed - in - Lua, nested classes and parsing of operator <<. -- The usual round of bug fixes and minor improvements for: - C#, GCJ, Go, Java, Lua, PHP and Python. - -SWIG-3.0.0 summary: -- This is a major new release focusing primarily on C++ improvements. -- C++11 support added. Please see documentation for details of supported - features: https://www.swig.org/Doc3.0/CPlusPlus11.html -- Nested class support added. This has been taken full advantage of in - Java and C#. Other languages can use the nested classes, but require - further work for a more natural integration into the target language. - We urge folk knowledgeable in the other target languages to step - forward and help with this effort. -- Lua: improved metatables and support for %nspace. -- Go 1.3 support added. -- Python import improvements including relative imports. -- Python 3.3 support completed. -- Perl director support added. -- C# .NET 2 support is now the minimum. Generated using statements are - replaced by fully qualified names. -- Bug fixes and improvements to the following languages: - C#, Go, Guile, Java, Lua, Perl, PHP, Python, Octave, R, Ruby, Tcl -- Various other bug fixes and improvements affecting all languages. -- Note that this release contains some backwards incompatible changes - in some languages. -- Full detailed release notes are in the changes file. - -SWIG-2.0.12 summary: -- This is a maintenance release backporting some fixes from the pending - 3.0.0 release. -- Octave 3.8 support added. -- C++11 support for new versions of erase/insert in the STL containers. -- Compilation fixes on some systems for the generated Lua, PHP, Python - and R wrappers. - -SWIG-2.0.11 summary: -- Minor bug fixes and enhancements mostly in Python, but also - C#, Lua, Ocaml, Octave, Perl, PHP, Python, R, Ruby, Tcl. - -SWIG-2.0.10 summary: -- Ruby 1.9 support is now complete. -- Add support for Guile 2.0 and Guile 1.6 support (GH interface) has - been dropped. -- Various small language neutral improvements and fixes. -- Various bug fixes and minor improvements specific to C#, CFFI, D, - Java, Octave, PHP, Python, -- Minor bug fix in ccache-swig. -- Development has moved to Github with Travis continuous integration - testing - patches using https://github.com/swig/swig are welcome. - -SWIG-2.0.9 summary: -- Improved typemap matching. -- Ruby 1.9 support is much improved. -- Various bug fixes and minor improvements in C#, CFFI, Go, Java, - Modula3, Octave, Perl, Python, R, Ruby, Tcl and in ccache-swig. - -SWIG-2.0.8 summary: -- Fix a couple of regressions introduced in 2.0.5 and 2.0.7. -- Improved using declarations and using directives support. -- Minor fixes/enhancements for C#, Java, Octave, Perl and Python. - -SWIG-2.0.7 summary: -- Important regression fixes since 2.0.5 for typemaps in general and - in Python. -- Fixes and enhancements for Go, Java, Octave and PHP. - -SWIG-2.0.6 summary: -- Regression fix for Python STL wrappers on some systems. - -SWIG-2.0.5 summary: -- Official Android support added including documentation and examples. -- Improvements involving templates: - 1) Various fixes with templates and typedef types. - 2) Some template lookup problems fixed. - 3) Templated type fixes to use correct typemaps. -- Autodoc documentation generation improvements. -- Python STL container wrappers improvements including addition of - stepped slicing. -- Approximately 70 fixes and minor enhancements for the following - target languages: AllegroCL, C#, D, Go, Java, Lua, Ocaml, Octave, - Perl, PHP, Python, R, Ruby, Tcl, Xml. - -SWIG-2.0.4 summary: -- This is mainly a Python oriented release including support for Python - built-in types for superior performance with the new -builtin option. - The -builtin option is especially suitable for performance-critical - libraries and applications that call wrapped methods repeatedly. - See the python-specific chapter of the SWIG manual for more info. -- Python 3.2 support has also been added and various Python bugs have - been fixed. -- Octave 3.4 support has also been added. -- There are also the usual minor generic improvements, as well as bug - fixes and enhancements for D, Guile, Lua, Octave, Perl and Tcl. - -SWIG-2.0.3 summary: -- A bug fix release including a couple of fixes for regressions in the - 2.0 series. - -SWIG-2.0.2 summary: -- Support for the D language has been added. -- Various bug fixes and minor enhancements. -- Bug fixes particular to the Clisp, C#, Go, MzScheme, Ocaml, PHP, R, - Ruby target languages. - -SWIG-2.0.1 summary: -- Support for the Go language has been added. -- New regular expression (regex) encoder for renaming symbols based on - the Perl Compatible Regular Expressions (PCRE) library. -- Numerous fixes in reporting file and line numbers in error and warning - messages. -- Various bug fixes and improvements in the C#, Lua, Perl, PHP, Ruby - and Python language modules. - -SWIG-2.0.0 summary: -- License changes, see LICENSE file and https://www.swig.org/legal.html. -- Much better nested class/struct support. -- Much improved template partial specialization and explicit - specialization handling. -- Namespace support improved with the 'nspace' feature where namespaces - can be automatically translated into Java packages or C# namespaces. -- Improved typemap and symbol table debugging. -- Numerous subtle typemap matching rule changes when using the default - (SWIGTYPE) type. These now work much like C++ class template partial - specialization matching. -- Other small enhancements for typemaps. Typemap fragments are also now - official and documented. -- Warning and error display refinements. -- Wrapping of shared_ptr is improved and documented now. -- Numerous C++ unary scope operator (::) fixes. -- Better support for boolean expressions. -- Various bug fixes and improvements in the Allegrocl, C#, Java, Lua, - Octave, PHP, Python, R, Ruby and XML modules. - -SWIG-1.3.40 summary: -- SWIG now supports directors for PHP. -- PHP support improved in general. -- Octave 3.2 support added. -- Various bug fixes/enhancements for Allegrocl, C#, Java, Octave, Perl, - Python, Ruby and Tcl. -- Other generic fixes and minor new features. - -SWIG-1.3.39 summary: -- Some new small feature enhancements. -- Improved C# std::vector wrappers. -- Bug fixes: mainly Python, but also Perl, MzScheme, CFFI, Allegrocl - and Ruby - -SWIG-1.3.38 summary: -- Output directory regression fix and other minor bug fixes - -SWIG-1.3.37 summary: -- Python 3 support added -- SWIG now ships with a version of ccache that can be used with SWIG. - This enables the files generated by SWIG to be cached so that repeated - use of SWIG on unchanged input files speeds up builds quite considerably. -- PHP 4 support removed and PHP support improved in general -- Improved C# array support -- Numerous Allegro CL improvements -- Bug fixes/enhancements for Python, PHP, Java, C#, Chicken, Allegro CL, - CFFI, Ruby, Tcl, Perl, R, Lua. -- Other minor generic bug fixes and enhancements - -SWIG-1.3.36 summary: -- Enhancement to directors to wrap all protected members -- Optimisation feature for objects returned by value -- A few bugs fixes in the PHP, Java, Ruby, R, C#, Python, Lua and - Perl modules -- Other minor generic bug fixes - -SWIG-1.3.35 summary: -- Octave language module added -- Bug fixes in Python, Lua, Java, C#, Perl modules -- A few other generic bugs and runtime assertions fixed - -SWIG-1.3.34 summary: -- shared_ptr support for Python -- Support for latest R - version 2.6 -- Various minor improvements/bug fixes for R, Lua, Python, Java, C# -- A few other generic bug fixes, mainly for templates and using statements - -SWIG-1.3.33 summary: -- Fix regression for Perl where C++ wrappers would not compile -- Fix regression parsing macros - -SWIG-1.3.32 summary: -- shared_ptr support for Java and C# -- Enhanced STL support for Ruby -- Windows support for R -- Fixed long-standing memory leak in PHP Module -- Numerous fixes and minor enhancements for Allegrocl, C#, cffi, Chicken, Guile, - Java, Lua, Ocaml, Perl, PHP, Python, Ruby, Tcl. -- Improved warning support - -SWIG-1.3.31 summary: -- Python modern classes regression fix - -SWIG-1.3.30 summary: -- Python-2.5 support -- New language module: R -- Director support added for C# -- Numerous director fixes and improvements -- Improved mingw/msys support -- Better constants support in Guile and chicken modules -- Support for generating PHP5 class wrappers -- Important Java premature garbage collection fix -- Minor improvements/fixes in cffi, php, allegrocl, perl, chicken, lua, ruby, - ocaml, python, java, c# and guile language modules -- Many many other bug fixes - -SWIG-1.3.29 summary: -- Numerous important bug fixes -- Few minor new features -- Some performance improvements in generated code for Python - -SWIG-1.3.28 summary: -- More powerful renaming (%rename) capability. -- More user friendly warning handling. -- Add finer control for default constructors and destructors. We discourage - the use of the 'nodefault' option, which disables both constructors and - destructors, leading to possible memory leaks. Use instead 'nodefaultctor' - and/or 'nodefaultdtor'. -- Automatic copy constructor wrapper generation via the 'copyctor' option/feature. -- Better handling of Windows extensions and types. -- Better runtime error reporting. -- Add the %catches directive to catch and dispatch exceptions. -- Add the %naturalvar directive for more 'natural' variable wrapping. -- Better default handling of std::string variables using the %naturalvar directive. -- Add the %allowexcept and %exceptionvar directives to handle exceptions when - accessing a variable. -- Add the %delobject directive to mark methods that act like destructors. -- Add the -fastdispatch option to enable smaller and faster overload dispatch - mechanism. -- Template support for %rename, %feature and %typemap improved. -- Add/doc more debug options, such as -dump_module, -debug_typemaps, etc. -- Unified typemap library (UTL) potentially providing core typemaps for all - scripting languages based on the recently evolving Python typemaps. -- New language module: Common Lisp with CFFI. -- Python, Ruby, Perl and Tcl use the new UTL, many old reported and hidden - errors with typemaps are now fixed. -- Initial Java support for languages using the UTL via GCJ, you can now use - Java libraries in your favorite script language using gcj + swig. -- Tcl support for std::wstring. -- PHP4 module update, many error fixes and actively maintained again. -- Allegrocl support for C++, also enhanced C support. -- Ruby support for bang methods. -- Ruby support for user classes as native exceptions. -- Perl improved dispatching in overloaded functions via the new cast and rank - mechanism. -- Perl improved backward compatibility, 5.004 and later tested and working. -- Python improved backward compatibility, 1.5.2 and later tested and working. -- Python can use the same cast/rank mechanism via the -castmode option. -- Python implicit conversion mechanism similar to C++, via the %implicitconv - directive (replaces and improves the implicit.i library). -- Python threading support added. -- Python STL support improved, iterators are supported and STL containers can - use now the native PyObject type. -- Python many performance options and improvements, try the -O option to test - all of them. Python runtime benchmarks show up to 20 times better performance - compared to 1.3.27 and older versions. -- Python support for 'multi-inheritance' on the python side. -- Python simplified proxy classes, now swig doesn't need to generate the - additional 'ClassPtr' classes. -- Python extended support for smart pointers. -- Python better support for static member variables. -- Python backward compatibility improved, many projects that used to work - only with swig-1.3.21 to swig-1.3.24 are working again with swig-1.3.28 -- Python test-suite is now 'valgrinded' before release, and swig also - reports memory leaks due to missing destructors. -- Minor bug fixes and improvements to the Lua, Ruby, Java, C#, Python, Guile, - Chicken, Tcl and Perl modules. - -SWIG-1.3.27 summary: -- Fix bug in anonymous typedef structures which was leading to strange behaviour - -SWIG-1.3.26 summary: -- New language modules: Lua, CLISP and Common Lisp with UFFI. -- Big overhaul to the PHP module. -- Change to the way 'extern' is handled. -- Minor bug fixes specific to C#, Java, Modula3, Ocaml, Allegro CL, - XML, Lisp s-expressions, Tcl, Ruby and Python modules. -- Other minor improvements and bug fixes. - -SWIG-1.3.25 summary: -- Improved runtime type system. Speed of module loading improved in - modules with lots of types. SWIG_RUNTIME_VERSION has been increased - from 1 to 2, but the API is exactly the same; only internal changes - were made. -- The languages that use the runtime type system now support external - access to the runtime type system. -- Various improvements with typemaps and template handling. -- Fewer warnings in generated code. -- Improved colour documentation. -- Many C# module improvements (exception handling, prevention of early - garbage collection, C# attributes support added, more flexible type - marshalling/asymmetric types.) -- Minor improvements and bug fixes specific to the C#, Java, TCL, Guile, - Chicken, MzScheme, Perl, Php, Python, Ruby and Ocaml modules). -- Various other bug fixes and memory leak fixes. - -SWIG-1.3.24 summary: -- Improved enum handling -- More runtime library options -- More bugs fixes for templates and template default arguments, directors - and other areas. -- Better smart pointer support, including data members, static members - and %extend. - -SWIG-1.3.23 summary: -- Improved support for callbacks -- Python docstring support and better error handling -- C++ default argument support for Java and C# added. -- Improved c++ default argument support for the scripting languages plus - option to use original (compact) default arguments. -- %feature and %ignore/%rename bug fixes and mods - they might need default - arguments specified to maintain compatible behaviour when using the new - default arguments wrapping. -- Runtime library changes: Runtime code can now exist in more than one module - and so need not be compiled into just one module -- Further improved support for templates and namespaces -- Overloaded templated function support added -- More powerful default typemaps (mixed default typemaps) -- Some important %extend and director code bug fixes -- Guile now defaults to using SCM API. The old interface can be obtained by - the -gh option. -- Various minor improvements and bug fixes for C#, Chicken, Guile, Java, - MzScheme, Perl, Python and Ruby -- Improved dependencies generation for constructing Makefiles. - -SWIG-1.3.22 summary: -- Improved exception handling and translation of C errors or C++ - exceptions into target language exceptions. -- Improved enum support, mapping to built-in Java 1.5 enums and C# - enums or the typesafe enum pattern for these two languages. -- Python - much better STL support and support for std::wstring, - wchar_t and FILE *. -- Initial support for Modula3 and Allegro CL. -- 64 bit TCL support. -- Java and C#'s proxy classes are now nearly 100% generated from - typemaps and/or features for finer control on the generated code. -- SWIG runtime library support deprecation. -- Improved documentation. SWIG now additionally provides documentation - in the form of a single HTML page as well as a pdf document. -- Enhanced C++ friend declaration support. -- Better support for reference counted classes. -- Various %fragment improvements. -- RPM fixes. -- Various minor improvements and bug fixes for C#, Chicken, Guile, Java, - MzScheme, Perl, Php, Python, Ruby and XML. - - diff --git a/contrib/tools/swig/Source/CParse/cparse.h b/contrib/tools/swig/Source/CParse/cparse.h deleted file mode 100644 index 2b63f034d0f..00000000000 --- a/contrib/tools/swig/Source/CParse/cparse.h +++ /dev/null @@ -1,85 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * cparse.h - * - * SWIG parser module. - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_CPARSE_H -#define SWIG_CPARSE_H - -#include "swig.h" -#include "swigwarn.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* cscanner.c */ - extern String *cparse_file; - extern int cparse_line; - extern int cparse_cplusplus; - extern int cparse_cplusplusout; - extern int cparse_start_line; - extern String *cparse_unknown_directive; - extern int scan_doxygen_comments; - - extern void Swig_cparse_cplusplus(int); - extern void Swig_cparse_cplusplusout(int); - extern void scanner_file(File *); - extern void scanner_next_token(int); - extern void skip_balanced(int startchar, int endchar); - extern String *get_raw_text_balanced(int startchar, int endchar); - extern void skip_decl(void); - extern void scanner_check_typedef(void); - extern void scanner_ignore_typedef(void); - extern void scanner_last_id(int); - extern void scanner_clear_rename(void); - extern void scanner_set_location(String *file, int line); - extern void scanner_set_main_input_file(String *file); - extern String *scanner_get_main_input_file(void); - extern void Swig_cparse_follow_locators(int); - extern void start_inline(char *, int); - extern String *scanner_ccode; - extern int yylex(void); - -/* parser.y */ - extern SwigType *Swig_cparse_type(String *); - extern Node *Swig_cparse(File *); - extern Hash *Swig_cparse_features(void); - extern void SWIG_cparse_set_compact_default_args(int defargs); - extern int SWIG_cparse_template_reduce(int treduce); - -/* util.c */ - extern void Swig_cparse_replace_descriptor(String *s); - extern SwigType *Swig_cparse_smartptr(Node *n); - extern void cparse_normalize_void(Node *); - extern Parm *Swig_cparse_parm(String *s); - extern ParmList *Swig_cparse_parms(String *s, Node *file_line_node); - extern Node *Swig_cparse_new_node(const_String_or_char_ptr tag); - -/* templ.c */ - extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope); - extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms, Symtab *tscope); - extern void Swig_cparse_debug_templates(int); - -#ifdef __cplusplus -} -#endif -#define SWIG_WARN_NODE_BEGIN(Node) \ - { \ - String *wrnfilter = Node ? Getattr(Node,"feature:warnfilter") : 0; \ - if (wrnfilter) Swig_warnfilter(wrnfilter,1) -#define SWIG_WARN_NODE_END(Node) \ - if (wrnfilter) Swig_warnfilter(wrnfilter,0); \ - } - -#define COMPOUND_EXPR_VAL(dtype) \ - ((dtype).type == T_CHAR || (dtype).type == T_WCHAR ? (dtype).rawval : (dtype).val) -#endif diff --git a/contrib/tools/swig/Source/CParse/cscanner.c b/contrib/tools/swig/Source/CParse/cscanner.c deleted file mode 100644 index 2eb3f97749f..00000000000 --- a/contrib/tools/swig/Source/CParse/cscanner.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * scanner.c - * - * SWIG tokenizer. This file is a wrapper around the generic C scanner - * found in Swig/scanner.c. Extra logic is added both to accommodate the - * bison-based grammar and certain peculiarities of C++ parsing (e.g., - * operator overloading, typedef resolution, etc.). This code also splits - * C identifiers up into keywords and SWIG directives. - * ----------------------------------------------------------------------------- */ - -#include "cparse.h" -#include "parser.h" -#include <string.h> -#include <ctype.h> - -/* Scanner object */ -static Scanner *scan = 0; - -/* Global string containing C code. Used by the parser to grab code blocks */ -String *scanner_ccode = 0; - -/* The main file being parsed */ -static String *main_input_file = 0; - -/* Error reporting/location information */ -int cparse_line = 1; -String *cparse_file = 0; -int cparse_start_line = 0; - -/* C++ mode */ -int cparse_cplusplus = 0; - -/* Generate C++ compatible code when wrapping C code */ -int cparse_cplusplusout = 0; - -/* To allow better error reporting */ -String *cparse_unknown_directive = 0; - -/* Private vars */ -static int scan_init = 0; -static int num_brace = 0; -static int last_brace = 0; -static int last_id = 0; -static int rename_active = 0; - -/* Doxygen comments scanning */ -int scan_doxygen_comments = 0; - -int isStructuralDoxygen(String *s) { - static const char* const structuralTags[] = { - "addtogroup", - "callgraph", - "callergraph", - "category", - "def", - "defgroup", - "dir", - "example", - "file", - "headerfile", - "internal", - "mainpage", - "name", - "nosubgrouping", - "overload", - "package", - "page", - "protocol", - "relates", - "relatesalso", - "showinitializer", - "weakgroup", - }; - - unsigned n; - char *slashPointer = Strchr(s, '\\'); - char *atPointer = Strchr(s,'@'); - if (slashPointer == NULL && atPointer == NULL) - return 0; - else if(slashPointer == NULL) - slashPointer = atPointer; - - slashPointer++; /* skip backslash or at sign */ - - for (n = 0; n < sizeof(structuralTags)/sizeof(structuralTags[0]); n++) { - const size_t len = strlen(structuralTags[n]); - if (strncmp(slashPointer, structuralTags[n], len) == 0) { - /* Take care to avoid false positives with prefixes of other tags. */ - if (slashPointer[len] == '\0' || isspace((int)slashPointer[len])) - return 1; - } - } - - return 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_cparse_cplusplus() - * ----------------------------------------------------------------------------- */ - -void Swig_cparse_cplusplus(int v) { - cparse_cplusplus = v; -} - -/* ----------------------------------------------------------------------------- - * Swig_cparse_cplusplusout() - * ----------------------------------------------------------------------------- */ - -void Swig_cparse_cplusplusout(int v) { - cparse_cplusplusout = v; -} - -/* ---------------------------------------------------------------------------- - * scanner_init() - * - * Initialize buffers - * ------------------------------------------------------------------------- */ - -void scanner_init(void) { - scan = NewScanner(); - Scanner_idstart(scan,"%"); - scan_init = 1; - scanner_ccode = NewStringEmpty(); -} - -/* ---------------------------------------------------------------------------- - * scanner_file(DOHFile *f) - * - * Start reading from new file - * ------------------------------------------------------------------------- */ -void scanner_file(DOHFile * f) { - if (!scan_init) scanner_init(); - Scanner_clear(scan); - Scanner_push(scan,f); -} - -/* ---------------------------------------------------------------------------- - * start_inline(char *text, int line) - * - * Take a chunk of text and recursively feed it back into the scanner. Used - * by the %inline directive. - * ------------------------------------------------------------------------- */ - -void start_inline(char *text, int line) { - String *stext = NewString(text); - - Seek(stext,0,SEEK_SET); - Setfile(stext,cparse_file); - Setline(stext,line); - Scanner_push(scan,stext); - Delete(stext); -} - -/* ----------------------------------------------------------------------------- - * skip_balanced() - * - * Skips a piece of code enclosed in begin/end symbols such as '{...}' or - * (...). Ignores symbols inside comments or strings. - * ----------------------------------------------------------------------------- */ - -void skip_balanced(int startchar, int endchar) { - int start_line = Scanner_line(scan); - Clear(scanner_ccode); - - if (Scanner_skip_balanced(scan,startchar,endchar) < 0) { - Swig_error(cparse_file, start_line, "Missing '%c'. Reached end of input.\n", endchar); - return; - } - - cparse_line = Scanner_line(scan); - cparse_file = Scanner_file(scan); - - Append(scanner_ccode, Scanner_text(scan)); - if (endchar == '}') - num_brace--; - return; -} - -/* ----------------------------------------------------------------------------- - * get_raw_text_balanced() - * - * Returns raw text between 2 braces - * ----------------------------------------------------------------------------- */ - -String *get_raw_text_balanced(int startchar, int endchar) { - return Scanner_get_raw_text_balanced(scan, startchar, endchar); -} - -/* ---------------------------------------------------------------------------- - * void skip_decl(void) - * - * This tries to skip over an entire declaration. For example - * - * friend ostream& operator<<(ostream&, const char *s); - * - * or - * friend ostream& operator<<(ostream&, const char *s) { } - * - * ------------------------------------------------------------------------- */ - -void skip_decl(void) { - int tok; - int done = 0; - int start_line = Scanner_line(scan); - - while (!done) { - tok = Scanner_token(scan); - if (tok == 0) { - if (!Swig_error_count()) { - Swig_error(cparse_file, start_line, "Missing semicolon (';'). Reached end of input.\n"); - } - return; - } - if (tok == SWIG_TOKEN_LBRACE) { - if (Scanner_skip_balanced(scan,'{','}') < 0) { - Swig_error(cparse_file, start_line, "Missing closing brace ('}'). Reached end of input.\n"); - } - break; - } - if (tok == SWIG_TOKEN_SEMI) { - done = 1; - } - } - cparse_file = Scanner_file(scan); - cparse_line = Scanner_line(scan); -} - -/* ---------------------------------------------------------------------------- - * int yylook() - * - * Lexical scanner. - * ------------------------------------------------------------------------- */ - -static int yylook(void) { - - int tok = 0; - - while (1) { - if ((tok = Scanner_token(scan)) == 0) - return 0; - if (tok == SWIG_TOKEN_ERROR) - return 0; - cparse_start_line = Scanner_start_line(scan); - cparse_line = Scanner_line(scan); - cparse_file = Scanner_file(scan); - - switch(tok) { - case SWIG_TOKEN_ID: - return ID; - case SWIG_TOKEN_LPAREN: - return LPAREN; - case SWIG_TOKEN_RPAREN: - return RPAREN; - case SWIG_TOKEN_SEMI: - return SEMI; - case SWIG_TOKEN_COMMA: - return COMMA; - case SWIG_TOKEN_STAR: - return STAR; - case SWIG_TOKEN_RBRACE: - num_brace--; - if (num_brace < 0) { - Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous closing brace ('}')\n"); - num_brace = 0; - } else { - return RBRACE; - } - break; - case SWIG_TOKEN_LBRACE: - last_brace = num_brace; - num_brace++; - return LBRACE; - case SWIG_TOKEN_EQUAL: - return EQUAL; - case SWIG_TOKEN_EQUALTO: - return EQUALTO; - case SWIG_TOKEN_PLUS: - return PLUS; - case SWIG_TOKEN_MINUS: - return MINUS; - case SWIG_TOKEN_SLASH: - return SLASH; - case SWIG_TOKEN_AND: - return AND; - case SWIG_TOKEN_LAND: - return LAND; - case SWIG_TOKEN_OR: - return OR; - case SWIG_TOKEN_LOR: - return LOR; - case SWIG_TOKEN_XOR: - return XOR; - case SWIG_TOKEN_NOT: - return NOT; - case SWIG_TOKEN_LNOT: - return LNOT; - case SWIG_TOKEN_NOTEQUAL: - return NOTEQUALTO; - case SWIG_TOKEN_LBRACKET: - return LBRACKET; - case SWIG_TOKEN_RBRACKET: - return RBRACKET; - case SWIG_TOKEN_QUESTION: - return QUESTIONMARK; - case SWIG_TOKEN_LESSTHAN: - return LESSTHAN; - case SWIG_TOKEN_LTEQUAL: - return LESSTHANOREQUALTO; - case SWIG_TOKEN_LSHIFT: - return LSHIFT; - case SWIG_TOKEN_GREATERTHAN: - return GREATERTHAN; - case SWIG_TOKEN_GTEQUAL: - return GREATERTHANOREQUALTO; - case SWIG_TOKEN_RSHIFT: - return RSHIFT; - case SWIG_TOKEN_ARROW: - return ARROW; - case SWIG_TOKEN_PERIOD: - return PERIOD; - case SWIG_TOKEN_MODULO: - return MODULO; - case SWIG_TOKEN_COLON: - return COLON; - case SWIG_TOKEN_DCOLONSTAR: - return DSTAR; - case SWIG_TOKEN_LTEQUALGT: - return LESSEQUALGREATER; - - case SWIG_TOKEN_DCOLON: - { - int nexttok = Scanner_token(scan); - if (nexttok == SWIG_TOKEN_STAR) { - return DSTAR; - } else if (nexttok == SWIG_TOKEN_NOT) { - return DCNOT; - } else { - Scanner_pushtoken(scan,nexttok,Scanner_text(scan)); - if (!last_id) { - scanner_next_token(DCOLON); - return NONID; - } else { - return DCOLON; - } - } - } - break; - - case SWIG_TOKEN_ELLIPSIS: - return ELLIPSIS; - - case SWIG_TOKEN_LLBRACKET: - do { - tok = Scanner_token(scan); - } while ((tok != SWIG_TOKEN_RRBRACKET) && (tok > 0)); - if (tok <= 0) { - Swig_error(cparse_file, cparse_line, "Unbalanced double brackets, missing closing (']]'). Reached end of input.\n"); - } - break; - - case SWIG_TOKEN_RRBRACKET: - /* Turn an unmatched ]] back into two ] - e.g. `a[a[0]]` */ - scanner_next_token(RBRACKET); - return RBRACKET; - - /* Look for multi-character sequences */ - - case SWIG_TOKEN_RSTRING: - yylval.type = NewString(Scanner_text(scan)); - return TYPE_RAW; - - case SWIG_TOKEN_STRING: - yylval.id = Swig_copy_string(Char(Scanner_text(scan))); - return STRING; - - case SWIG_TOKEN_WSTRING: - yylval.id = Swig_copy_string(Char(Scanner_text(scan))); - return WSTRING; - - case SWIG_TOKEN_CHAR: - yylval.str = NewString(Scanner_text(scan)); - if (Len(yylval.str) == 0) { - Swig_error(cparse_file, cparse_line, "Empty character constant\n"); - } - return CHARCONST; - - case SWIG_TOKEN_WCHAR: - yylval.str = NewString(Scanner_text(scan)); - if (Len(yylval.str) == 0) { - Swig_error(cparse_file, cparse_line, "Empty character constant\n"); - } - return WCHARCONST; - - /* Numbers */ - - case SWIG_TOKEN_INT: - return NUM_INT; - - case SWIG_TOKEN_UINT: - return NUM_UNSIGNED; - - case SWIG_TOKEN_LONG: - return NUM_LONG; - - case SWIG_TOKEN_ULONG: - return NUM_ULONG; - - case SWIG_TOKEN_LONGLONG: - return NUM_LONGLONG; - - case SWIG_TOKEN_ULONGLONG: - return NUM_ULONGLONG; - - case SWIG_TOKEN_DOUBLE: - case SWIG_TOKEN_FLOAT: - return NUM_FLOAT; - - case SWIG_TOKEN_BOOL: - return NUM_BOOL; - - case SWIG_TOKEN_POUND: - Scanner_skip_line(scan); - yylval.id = Swig_copy_string(Char(Scanner_text(scan))); - return POUND; - break; - - case SWIG_TOKEN_CODEBLOCK: - yylval.str = NewString(Scanner_text(scan)); - return HBLOCK; - - case SWIG_TOKEN_COMMENT: - { - typedef enum { - DOX_COMMENT_PRE = -1, - DOX_COMMENT_NONE, - DOX_COMMENT_POST - } comment_kind_t; - comment_kind_t existing_comment = DOX_COMMENT_NONE; - - /* Concatenate or skip all consecutive comments at once. */ - do { - String *cmt = Scanner_text(scan); - String *cmt_modified = 0; - char *loc = Char(cmt); - if ((strncmp(loc, "/*@SWIG", 7) == 0) && (loc[Len(cmt)-3] == '@')) { - Scanner_locator(scan, cmt); - } - if (scan_doxygen_comments) { /* else just skip this node, to avoid crashes in parser module*/ - - int slashStyle = 0; /* Flag for "///" style doxygen comments */ - if (strncmp(loc, "///", 3) == 0) { - slashStyle = 1; - if (Len(cmt) == 3) { - /* Modify to make length=4 to ensure that the empty comment does - get processed to preserve the newlines in the original comments. */ - cmt_modified = NewStringf("%s ", cmt); - cmt = cmt_modified; - loc = Char(cmt); - } - } - - /* Check for all possible Doxygen comment start markers while ignoring - comments starting with a row of asterisks or slashes just as - Doxygen itself does. Also skip empty comment (slash-star-star-slash), - which causes a crash due to begin > end. */ - if (Len(cmt) > 3 && loc[0] == '/' && - ((loc[1] == '/' && ((loc[2] == '/' && loc[3] != '/') || loc[2] == '!')) || - (loc[1] == '*' && ((loc[2] == '*' && loc[3] != '*' && loc[3] != '/') || loc[2] == '!')))) { - comment_kind_t this_comment = loc[3] == '<' ? DOX_COMMENT_POST : DOX_COMMENT_PRE; - if (existing_comment != DOX_COMMENT_NONE && this_comment != existing_comment) { - /* We can't concatenate together Doxygen pre- and post-comments. */ - break; - } - - if (this_comment == DOX_COMMENT_POST || !isStructuralDoxygen(loc)) { - String *str; - - int begin = this_comment == DOX_COMMENT_POST ? 4 : 3; - int end = Len(cmt); - if (loc[end - 1] == '/' && loc[end - 2] == '*') { - end -= 2; - } - - str = NewStringWithSize(loc + begin, end - begin); - - if (existing_comment == DOX_COMMENT_NONE) { - yylval.str = str; - Setline(yylval.str, Scanner_start_line(scan)); - Setfile(yylval.str, Scanner_file(scan)); - } else { - if (slashStyle) { - /* Add a newline to the end of each doxygen "///" comment, - since they are processed individually, unlike the - slash-star style, which gets processed as a block with - newlines included. */ - Append(yylval.str, "\n"); - } - Append(yylval.str, str); - } - - existing_comment = this_comment; - } - } - } - do { - tok = Scanner_token(scan); - } while (tok == SWIG_TOKEN_ENDLINE); - Delete(cmt_modified); - } while (tok == SWIG_TOKEN_COMMENT); - - Scanner_pushtoken(scan, tok, Scanner_text(scan)); - - switch (existing_comment) { - case DOX_COMMENT_PRE: - return DOXYGENSTRING; - case DOX_COMMENT_NONE: - break; - case DOX_COMMENT_POST: - return DOXYGENPOSTSTRING; - } - } - break; - case SWIG_TOKEN_ENDLINE: - break; - case SWIG_TOKEN_BACKSLASH: - break; - default: - Swig_error(cparse_file, cparse_line, "Illegal token '%s'.\n", Scanner_text(scan)); - return (ILLEGAL); - } - } -} - -static int check_typedef = 0; - -void scanner_set_location(String *file, int line) { - Scanner_set_location(scan,file,line-1); -} - -void scanner_check_typedef(void) { - check_typedef = 1; -} - -void scanner_ignore_typedef(void) { - check_typedef = 0; -} - -void scanner_last_id(int x) { - last_id = x; -} - -void scanner_clear_rename(void) { - rename_active = 0; -} - -/* Used to push a fictitious token into the scanner */ -static int next_token = 0; -void scanner_next_token(int tok) { - next_token = tok; -} - -void scanner_set_main_input_file(String *file) { - main_input_file = file; -} - -String *scanner_get_main_input_file(void) { - return main_input_file; -} - -/* ---------------------------------------------------------------------------- - * int yylex() - * - * Gets the lexene and returns tokens. - * ------------------------------------------------------------------------- */ - -int yylex(void) { - - int l; - char *yytext; - - if (!scan_init) { - scanner_init(); - } - - Delete(cparse_unknown_directive); - cparse_unknown_directive = NULL; - - if (next_token) { - l = next_token; - next_token = 0; - return l; - } - - l = yylook(); - - /* Swig_diagnostic(cparse_file, cparse_line, ":::%d: '%s'\n", l, Scanner_text(scan)); */ - - if (l == NONID) { - last_id = 1; - } else { - last_id = 0; - } - - /* We got some sort of non-white space object. We set the start_line - variable unless it has already been set */ - - if (!cparse_start_line) { - cparse_start_line = cparse_line; - } - - /* Copy the lexene */ - - switch (l) { - - case NUM_INT: - case NUM_FLOAT: - case NUM_ULONG: - case NUM_LONG: - case NUM_UNSIGNED: - case NUM_LONGLONG: - case NUM_ULONGLONG: - case NUM_BOOL: - if (l == NUM_INT) - yylval.dtype.type = T_INT; - if (l == NUM_FLOAT) - yylval.dtype.type = T_DOUBLE; - if (l == NUM_ULONG) - yylval.dtype.type = T_ULONG; - if (l == NUM_LONG) - yylval.dtype.type = T_LONG; - if (l == NUM_UNSIGNED) - yylval.dtype.type = T_UINT; - if (l == NUM_LONGLONG) - yylval.dtype.type = T_LONGLONG; - if (l == NUM_ULONGLONG) - yylval.dtype.type = T_ULONGLONG; - if (l == NUM_BOOL) - yylval.dtype.type = T_BOOL; - yylval.dtype.val = NewString(Scanner_text(scan)); - yylval.dtype.bitfield = 0; - yylval.dtype.throws = 0; - return (l); - - case ID: - yytext = Char(Scanner_text(scan)); - if (yytext[0] != '%') { - /* Look for keywords now */ - - if (strcmp(yytext, "int") == 0) { - yylval.type = NewSwigType(T_INT); - return (TYPE_INT); - } - if (strcmp(yytext, "double") == 0) { - yylval.type = NewSwigType(T_DOUBLE); - return (TYPE_DOUBLE); - } - if (strcmp(yytext, "void") == 0) { - yylval.type = NewSwigType(T_VOID); - return (TYPE_VOID); - } - if (strcmp(yytext, "char") == 0) { - yylval.type = NewSwigType(T_CHAR); - return (TYPE_CHAR); - } - if (strcmp(yytext, "wchar_t") == 0) { - yylval.type = NewSwigType(T_WCHAR); - return (TYPE_WCHAR); - } - if (strcmp(yytext, "short") == 0) { - yylval.type = NewSwigType(T_SHORT); - return (TYPE_SHORT); - } - if (strcmp(yytext, "long") == 0) { - yylval.type = NewSwigType(T_LONG); - return (TYPE_LONG); - } - if (strcmp(yytext, "float") == 0) { - yylval.type = NewSwigType(T_FLOAT); - return (TYPE_FLOAT); - } - if (strcmp(yytext, "signed") == 0) { - yylval.type = NewSwigType(T_INT); - return (TYPE_SIGNED); - } - if (strcmp(yytext, "unsigned") == 0) { - yylval.type = NewSwigType(T_UINT); - return (TYPE_UNSIGNED); - } - if (strcmp(yytext, "bool") == 0) { - yylval.type = NewSwigType(T_BOOL); - return (TYPE_BOOL); - } - - /* Non ISO (Windows) C extensions */ - if (strcmp(yytext, "__int8") == 0) { - yylval.type = NewString(yytext); - return (TYPE_NON_ISO_INT8); - } - if (strcmp(yytext, "__int16") == 0) { - yylval.type = NewString(yytext); - return (TYPE_NON_ISO_INT16); - } - if (strcmp(yytext, "__int32") == 0) { - yylval.type = NewString(yytext); - return (TYPE_NON_ISO_INT32); - } - if (strcmp(yytext, "__int64") == 0) { - yylval.type = NewString(yytext); - return (TYPE_NON_ISO_INT64); - } - - /* C++ keywords */ - if (cparse_cplusplus) { - if (strcmp(yytext, "and") == 0) - return (LAND); - if (strcmp(yytext, "or") == 0) - return (LOR); - if (strcmp(yytext, "not") == 0) - return (LNOT); - if (strcmp(yytext, "class") == 0) - return (CLASS); - if (strcmp(yytext, "private") == 0) - return (PRIVATE); - if (strcmp(yytext, "public") == 0) - return (PUBLIC); - if (strcmp(yytext, "protected") == 0) - return (PROTECTED); - if (strcmp(yytext, "friend") == 0) - return (FRIEND); - if (strcmp(yytext, "constexpr") == 0) - return (CONSTEXPR); - if (strcmp(yytext, "thread_local") == 0) - return (THREAD_LOCAL); - if (strcmp(yytext, "decltype") == 0) - return (DECLTYPE); - if (strcmp(yytext, "virtual") == 0) - return (VIRTUAL); - if (strcmp(yytext, "static_assert") == 0) - return (STATIC_ASSERT); - if (strcmp(yytext, "operator") == 0) { - int nexttok; - String *s = NewString("operator "); - - /* If we have an operator, we have to collect the operator symbol and attach it to - the operator identifier. To do this, we need to scan ahead by several tokens. - Cases include: - - (1) If the next token is an operator as determined by Scanner_isoperator(), - it means that the operator applies to one of the standard C++ mathematical, - assignment, or logical operator symbols (e.g., '+','<=','==','&', etc.) - In this case, we merely append the symbol text to the operator string above. - - (2) If the next token is (, we look for ). This is operator (). - (3) If the next token is [, we look for ]. This is operator []. - (4) If the next token is an identifier. The operator is possibly a conversion operator. - (a) Must check for special case new[] and delete[] - - Error handling is somewhat tricky here. We'll try to back out gracefully if we can. - - */ - - do { - nexttok = Scanner_token(scan); - } while (nexttok == SWIG_TOKEN_ENDLINE || nexttok == SWIG_TOKEN_COMMENT); - - if (Scanner_isoperator(nexttok)) { - /* One of the standard C/C++ symbolic operators */ - Append(s,Scanner_text(scan)); - yylval.str = s; - return OPERATOR; - } else if (nexttok == SWIG_TOKEN_LPAREN) { - /* Function call operator. The next token MUST be a RPAREN */ - nexttok = Scanner_token(scan); - if (nexttok != SWIG_TOKEN_RPAREN) { - Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n"); - } else { - Append(s,"()"); - yylval.str = s; - return OPERATOR; - } - } else if (nexttok == SWIG_TOKEN_LBRACKET) { - /* Array access operator. The next token MUST be a RBRACKET */ - nexttok = Scanner_token(scan); - if (nexttok != SWIG_TOKEN_RBRACKET) { - Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n"); - } else { - Append(s,"[]"); - yylval.str = s; - return OPERATOR; - } - } else if (nexttok == SWIG_TOKEN_STRING) { - /* Operator "" or user-defined string literal ""_suffix */ - Append(s,"\"\""); - yylval.str = s; - return OPERATOR; - } else if (nexttok == SWIG_TOKEN_ID) { - /* We have an identifier. This could be any number of things. It could be a named version of - an operator (e.g., 'and_eq') or it could be a conversion operator. To deal with this, we're - going to read tokens until we encounter a ( or ;. Some care is needed for formatting. */ - int needspace = 1; - int termtoken = 0; - const char *termvalue = 0; - - Append(s,Scanner_text(scan)); - while (1) { - - nexttok = Scanner_token(scan); - if (nexttok <= 0) { - Swig_error(Scanner_file(scan),Scanner_line(scan),"Syntax error. Bad operator name.\n"); - } - if (nexttok == SWIG_TOKEN_LPAREN) { - termtoken = SWIG_TOKEN_LPAREN; - termvalue = "("; - break; - } else if (nexttok == SWIG_TOKEN_CODEBLOCK) { - termtoken = SWIG_TOKEN_CODEBLOCK; - termvalue = Char(Scanner_text(scan)); - break; - } else if (nexttok == SWIG_TOKEN_LBRACE) { - termtoken = SWIG_TOKEN_LBRACE; - termvalue = "{"; - break; - } else if (nexttok == SWIG_TOKEN_SEMI) { - termtoken = SWIG_TOKEN_SEMI; - termvalue = ";"; - break; - } else if (nexttok == SWIG_TOKEN_STRING) { - termtoken = SWIG_TOKEN_STRING; - termvalue = Swig_copy_string(Char(Scanner_text(scan))); - break; - } else if (nexttok == SWIG_TOKEN_ID) { - if (needspace) { - Append(s," "); - } - Append(s,Scanner_text(scan)); - } else if (nexttok == SWIG_TOKEN_ENDLINE) { - } else if (nexttok == SWIG_TOKEN_COMMENT) { - } else { - Append(s,Scanner_text(scan)); - needspace = 0; - } - } - yylval.str = s; - if (!rename_active) { - String *cs; - char *t = Char(s) + 9; - if (!((strcmp(t, "new") == 0) - || (strcmp(t, "delete") == 0) - || (strcmp(t, "new[]") == 0) - || (strcmp(t, "delete[]") == 0) - || (strcmp(t, "and") == 0) - || (strcmp(t, "and_eq") == 0) - || (strcmp(t, "bitand") == 0) - || (strcmp(t, "bitor") == 0) - || (strcmp(t, "compl") == 0) - || (strcmp(t, "not") == 0) - || (strcmp(t, "not_eq") == 0) - || (strcmp(t, "or") == 0) - || (strcmp(t, "or_eq") == 0) - || (strcmp(t, "xor") == 0) - || (strcmp(t, "xor_eq") == 0) - )) { - /* retract(strlen(t)); */ - - /* The operator is a conversion operator. In order to deal with this, we need to feed the - type information back into the parser. For now this is a hack. Needs to be cleaned up later. */ - cs = NewString(t); - if (termtoken) Append(cs,termvalue); - Seek(cs,0,SEEK_SET); - Setline(cs,cparse_line); - Setfile(cs,cparse_file); - Scanner_push(scan,cs); - Delete(cs); - return CONVERSIONOPERATOR; - } - } - if (termtoken) - Scanner_pushtoken(scan, termtoken, termvalue); - return (OPERATOR); - } - } - if (strcmp(yytext, "throw") == 0) - return (THROW); - if (strcmp(yytext, "noexcept") == 0) - return (NOEXCEPT); - if (strcmp(yytext, "try") == 0) - return (yylex()); - if (strcmp(yytext, "catch") == 0) - return (CATCH); - if (strcmp(yytext, "inline") == 0) - return (yylex()); - if (strcmp(yytext, "mutable") == 0) - return (yylex()); - if (strcmp(yytext, "explicit") == 0) - return (EXPLICIT); - if (strcmp(yytext, "auto") == 0) - return (AUTO); - if (strcmp(yytext, "export") == 0) - return (yylex()); - if (strcmp(yytext, "typename") == 0) - return (TYPENAME); - if (strcmp(yytext, "template") == 0) { - yylval.intvalue = cparse_line; - return (TEMPLATE); - } - if (strcmp(yytext, "delete") == 0) - return (DELETE_KW); - if (strcmp(yytext, "default") == 0) - return (DEFAULT); - if (strcmp(yytext, "using") == 0) - return (USING); - if (strcmp(yytext, "namespace") == 0) - return (NAMESPACE); - if (strcmp(yytext, "override") == 0) { - last_id = 1; - return (OVERRIDE); - } - if (strcmp(yytext, "final") == 0) { - last_id = 1; - return (FINAL); - } - } else { - if (strcmp(yytext, "class") == 0) { - Swig_warning(WARN_PARSE_CLASS_KEYWORD, cparse_file, cparse_line, "class keyword used, but not in C++ mode.\n"); - } - if (strcmp(yytext, "_Complex") == 0) { - yylval.type = NewSwigType(T_COMPLEX); - return (TYPE_COMPLEX); - } - if (strcmp(yytext, "restrict") == 0) - return (yylex()); - } - - /* Misc keywords */ - - if (strcmp(yytext, "extern") == 0) - return (EXTERN); - if (strcmp(yytext, "const") == 0) - return (CONST_QUAL); - if (strcmp(yytext, "static") == 0) - return (STATIC); - if (strcmp(yytext, "struct") == 0) - return (STRUCT); - if (strcmp(yytext, "union") == 0) - return (UNION); - if (strcmp(yytext, "enum") == 0) - return (ENUM); - if (strcmp(yytext, "sizeof") == 0) - return (SIZEOF); - - if (strcmp(yytext, "typedef") == 0) { - yylval.intvalue = 0; - return (TYPEDEF); - } - - /* Ignored keywords */ - - if (strcmp(yytext, "volatile") == 0) - return (VOLATILE); - if (strcmp(yytext, "register") == 0) - return (REGISTER); - if (strcmp(yytext, "inline") == 0) - return (yylex()); - - } else { - /* SWIG directives */ - String *stext = 0; - if (strcmp(yytext, "%module") == 0) - return (MODULE); - if (strcmp(yytext, "%insert") == 0) - return (INSERT); - if (strcmp(yytext, "%name") == 0) - return (NAME); - if (strcmp(yytext, "%rename") == 0) { - rename_active = 1; - return (RENAME); - } - if (strcmp(yytext, "%namewarn") == 0) { - rename_active = 1; - return (NAMEWARN); - } - if (strcmp(yytext, "%includefile") == 0) - return (INCLUDE); - if (strcmp(yytext, "%beginfile") == 0) - return (BEGINFILE); - if (strcmp(yytext, "%endoffile") == 0) - return (ENDOFFILE); - if (strcmp(yytext, "%val") == 0) { - Swig_warning(WARN_DEPRECATED_VAL, cparse_file, cparse_line, "%%val directive deprecated (ignored).\n"); - return (yylex()); - } - if (strcmp(yytext, "%out") == 0) { - Swig_warning(WARN_DEPRECATED_OUT, cparse_file, cparse_line, "%%out directive deprecated (ignored).\n"); - return (yylex()); - } - if (strcmp(yytext, "%constant") == 0) - return (CONSTANT); - if (strcmp(yytext, "%typedef") == 0) { - yylval.intvalue = 1; - return (TYPEDEF); - } - if (strcmp(yytext, "%native") == 0) - return (NATIVE); - if (strcmp(yytext, "%pragma") == 0) - return (PRAGMA); - if (strcmp(yytext, "%extend") == 0) - return (EXTEND); - if (strcmp(yytext, "%fragment") == 0) - return (FRAGMENT); - if (strcmp(yytext, "%inline") == 0) - return (INLINE); - if (strcmp(yytext, "%typemap") == 0) - return (TYPEMAP); - if (strcmp(yytext, "%feature") == 0) { - /* The rename_active indicates we don't need the information of the - * following function's return type. This applied for %rename, so do - * %feature. - */ - rename_active = 1; - return (FEATURE); - } - if (strcmp(yytext, "%except") == 0) - return (EXCEPT); - if (strcmp(yytext, "%importfile") == 0) - return (IMPORT); - if (strcmp(yytext, "%echo") == 0) - return (ECHO); - if (strcmp(yytext, "%apply") == 0) - return (APPLY); - if (strcmp(yytext, "%clear") == 0) - return (CLEAR); - if (strcmp(yytext, "%types") == 0) - return (TYPES); - if (strcmp(yytext, "%parms") == 0) - return (PARMS); - if (strcmp(yytext, "%varargs") == 0) - return (VARARGS); - if (strcmp(yytext, "%template") == 0) { - return (SWIGTEMPLATE); - } - if (strcmp(yytext, "%warn") == 0) - return (WARN); - - /* Note down the apparently unknown directive for error reporting - if - * we end up reporting a generic syntax error we'll instead report an - * error for his as an unknown directive. Then we treat it as MODULO - * (`%`) followed by an identifier and if that parses OK then - * `cparse_unknown_directive` doesn't get used. - * - * This allows `a%b` to be handled in expressions without a space after - * the operator. - */ - cparse_unknown_directive = NewString(yytext); - stext = NewString(yytext + 1); - Seek(stext,0,SEEK_SET); - Setfile(stext,cparse_file); - Setline(stext,cparse_line); - Scanner_push(scan,stext); - Delete(stext); - return (MODULO); - } - /* Have an unknown identifier, as a last step, we'll do a typedef lookup on it. */ - - /* Need to fix this */ - if (check_typedef) { - if (SwigType_istypedef(yytext)) { - yylval.type = NewString(yytext); - return (TYPE_TYPEDEF); - } - } - yylval.id = Swig_copy_string(yytext); - last_id = 1; - return (ID); - case POUND: - return yylex(); - case SWIG_TOKEN_COMMENT: - return yylex(); - default: - return (l); - } -} diff --git a/contrib/tools/swig/Source/CParse/parser.y b/contrib/tools/swig/Source/CParse/parser.y deleted file mode 100644 index 97b467b5c44..00000000000 --- a/contrib/tools/swig/Source/CParse/parser.y +++ /dev/null @@ -1,7499 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * parser.y - * - * YACC parser for SWIG. The grammar is a somewhat broken subset of C/C++. - * This file is a bit of a mess and probably needs to be rewritten at - * some point. Beware. - * ----------------------------------------------------------------------------- */ - -/* There are a small number of known shift-reduce conflicts in this file, fail - compilation if any more are introduced. - - Please don't increase the number of the conflicts if at all possible. And if - you really have no choice but to do it, make sure you clearly document each - new conflict in this file. - */ -%expect 7 - -%{ -#define yylex yylex - -/* doh.h uses #pragma GCC poison with GCC to prevent direct calls to certain - * standard C library functions being introduced, but those cause errors due - * to checks like `#if defined YYMALLOC || defined malloc` in the bison - * template code. We can't easily arrange to include headers after that - * template code, so instead we disable the problematic poisoning for this - * file. - */ -#define DOH_NO_POISON_MALLOC_FREE - -#include "swig.h" -#include "cparse.h" -#include "preprocessor.h" -#include <ctype.h> - -/* We do this for portability */ -#undef alloca -#define alloca Malloc - -#define YYMALLOC Malloc -#define YYFREE Free - -/* ----------------------------------------------------------------------------- - * Externals - * ----------------------------------------------------------------------------- */ - -int yyparse(void); - -/* NEW Variables */ - -static Node *top = 0; /* Top of the generated parse tree */ -static int unnamed = 0; /* Unnamed datatype counter */ -static Hash *classes = 0; /* Hash table of classes */ -static Hash *classes_typedefs = 0; /* Hash table of typedef classes: typedef struct X {...} Y; */ -static Symtab *prev_symtab = 0; -static Node *current_class = 0; -String *ModuleName = 0; -static Node *module_node = 0; -static String *Classprefix = 0; -static String *Namespaceprefix = 0; -static int inclass = 0; -static Node *currentOuterClass = 0; /* for nested classes */ -static const char *last_cpptype = 0; -static int inherit_list = 0; -static Parm *template_parameters = 0; -static int parsing_template_declaration = 0; -static int extendmode = 0; -static int compact_default_args = 0; -static int template_reduce = 0; -static int cparse_externc = 0; -int ignore_nested_classes = 0; -int kwargs_supported = 0; -/* ----------------------------------------------------------------------------- - * Doxygen Comment Globals - * ----------------------------------------------------------------------------- */ -static String *currentDeclComment = NULL; /* Comment of C/C++ declaration. */ -static Node *previousNode = NULL; /* Pointer to the previous node (for post comments) */ -static Node *currentNode = NULL; /* Pointer to the current node (for post comments) */ - -/* ----------------------------------------------------------------------------- - * Assist Functions - * ----------------------------------------------------------------------------- */ - - - -/* Called by the parser (yyparse) when an error is found.*/ -static void yyerror (const char *e) { - (void)e; -} - -static Node *new_node(const_String_or_char_ptr tag) { - Node *n = Swig_cparse_new_node(tag); - /* Remember the previous node in case it will need a post-comment */ - previousNode = currentNode; - currentNode = n; - return n; -} - -/* Copies a node. Does not copy tree links or symbol table data (except for - sym:name) */ - -static Node *copy_node(Node *n) { - Node *nn; - Iterator k; - nn = NewHash(); - Setfile(nn,Getfile(n)); - Setline(nn,Getline(n)); - for (k = First(n); k.key; k = Next(k)) { - String *ci; - String *key = k.key; - char *ckey = Char(key); - if ((strcmp(ckey,"nextSibling") == 0) || - (strcmp(ckey,"previousSibling") == 0) || - (strcmp(ckey,"parentNode") == 0) || - (strcmp(ckey,"lastChild") == 0)) { - continue; - } - if (Strncmp(key,"csym:",5) == 0) continue; - /* We do copy sym:name. For templates */ - if ((strcmp(ckey,"sym:name") == 0) || - (strcmp(ckey,"sym:weak") == 0) || - (strcmp(ckey,"sym:typename") == 0)) { - String *ci = Copy(k.item); - Setattr(nn,key, ci); - Delete(ci); - continue; - } - if (strcmp(ckey,"sym:symtab") == 0) { - Setattr(nn,"sym:needs_symtab", "1"); - } - /* We don't copy any other symbol table attributes */ - if (strncmp(ckey,"sym:",4) == 0) { - continue; - } - /* If children. We copy them recursively using this function */ - if (strcmp(ckey,"firstChild") == 0) { - /* Copy children */ - Node *cn = k.item; - while (cn) { - Node *copy = copy_node(cn); - appendChild(nn,copy); - Delete(copy); - cn = nextSibling(cn); - } - continue; - } - /* We don't copy the symbol table. But we drop an attribute - requires_symtab so that functions know it needs to be built */ - - if (strcmp(ckey,"symtab") == 0) { - /* Node defined a symbol table. */ - Setattr(nn,"requires_symtab","1"); - continue; - } - /* Can't copy nodes */ - if (strcmp(ckey,"node") == 0) { - continue; - } - if ((strcmp(ckey,"parms") == 0) || (strcmp(ckey,"pattern") == 0) || (strcmp(ckey,"throws") == 0) - || (strcmp(ckey,"kwargs") == 0)) { - ParmList *pl = CopyParmList(k.item); - Setattr(nn,key,pl); - Delete(pl); - continue; - } - if (strcmp(ckey,"nested:outer") == 0) { /* don't copy outer classes links, they will be updated later */ - Setattr(nn, key, k.item); - continue; - } - /* defaultargs will be patched back in later in update_defaultargs() */ - if (strcmp(ckey,"defaultargs") == 0) { - Setattr(nn, "needs_defaultargs", "1"); - continue; - } - /* same for abstracts, which contains pointers to the source node children, and so will need to be patch too */ - if (strcmp(ckey,"abstracts") == 0) { - SetFlag(nn, "needs_abstracts"); - continue; - } - /* Looks okay. Just copy the data using Copy */ - ci = Copy(k.item); - Setattr(nn, key, ci); - Delete(ci); - } - return nn; -} - -static void set_comment(Node *n, String *comment) { - String *name; - Parm *p; - if (!n || !comment) - return; - - if (Getattr(n, "doxygen")) - Append(Getattr(n, "doxygen"), comment); - else { - Setattr(n, "doxygen", comment); - /* This is the first comment, populate it with @params, if any */ - p = Getattr(n, "parms"); - while (p) { - if (Getattr(p, "doxygen")) - Printv(comment, "\n@param ", Getattr(p, "name"), Getattr(p, "doxygen"), NIL); - p=nextSibling(p); - } - } - - /* Append same comment to every generated overload */ - name = Getattr(n, "name"); - if (!name) - return; - n = nextSibling(n); - while (n && Getattr(n, "name") && Strcmp(Getattr(n, "name"), name) == 0) { - Setattr(n, "doxygen", comment); - n = nextSibling(n); - } -} - -/* ----------------------------------------------------------------------------- - * Variables - * ----------------------------------------------------------------------------- */ - -static char *typemap_lang = 0; /* Current language setting */ - -static int cplus_mode = 0; - -/* C++ modes */ - -#define CPLUS_PUBLIC 1 -#define CPLUS_PRIVATE 2 -#define CPLUS_PROTECTED 3 - -/* include types */ -static int import_mode = 0; - -void SWIG_typemap_lang(const char *tm_lang) { - typemap_lang = Swig_copy_string(tm_lang); -} - -void SWIG_cparse_set_compact_default_args(int defargs) { - compact_default_args = defargs; -} - -int SWIG_cparse_template_reduce(int treduce) { - template_reduce = treduce; - return treduce; -} - -/* ----------------------------------------------------------------------------- - * Assist functions - * ----------------------------------------------------------------------------- */ - -static int promote_type(int t) { - if (t <= T_UCHAR || t == T_CHAR || t == T_WCHAR) return T_INT; - return t; -} - -/* Perform type-promotion for binary operators */ -static int promote(int t1, int t2) { - t1 = promote_type(t1); - t2 = promote_type(t2); - return t1 > t2 ? t1 : t2; -} - -static String *yyrename = 0; - -/* Forward renaming operator */ - -static String *resolve_create_node_scope(String *cname, int is_class_definition); - - -Hash *Swig_cparse_features(void) { - static Hash *features_hash = 0; - if (!features_hash) features_hash = NewHash(); - return features_hash; -} - -/* Fully qualify any template parameters */ -static String *feature_identifier_fix(String *s) { - String *tp = SwigType_istemplate_templateprefix(s); - if (tp) { - String *ts, *ta, *tq; - ts = SwigType_templatesuffix(s); - ta = SwigType_templateargs(s); - tq = Swig_symbol_type_qualify(ta,0); - Append(tp,tq); - Append(tp,ts); - Delete(ts); - Delete(ta); - Delete(tq); - return tp; - } else { - return NewString(s); - } -} - -static void set_access_mode(Node *n) { - if (cplus_mode == CPLUS_PUBLIC) - Setattr(n, "access", "public"); - else if (cplus_mode == CPLUS_PROTECTED) - Setattr(n, "access", "protected"); - else - Setattr(n, "access", "private"); -} - -static void restore_access_mode(Node *n) { - String *mode = Getattr(n, "access"); - if (Strcmp(mode, "private") == 0) - cplus_mode = CPLUS_PRIVATE; - else if (Strcmp(mode, "protected") == 0) - cplus_mode = CPLUS_PROTECTED; - else - cplus_mode = CPLUS_PUBLIC; -} - -/* Generate the symbol table name for an object */ -/* This is a bit of a mess. Need to clean up */ -static String *add_oldname = 0; - - - -static String *make_name(Node *n, String *name,SwigType *decl) { - String *made_name = 0; - int destructor = name && (*(Char(name)) == '~'); - - if (yyrename) { - String *s = NewString(yyrename); - Delete(yyrename); - yyrename = 0; - if (destructor && (*(Char(s)) != '~')) { - Insert(s,0,"~"); - } - return s; - } - - if (!name) return 0; - - if (parsing_template_declaration) - SetFlag(n, "parsing_template_declaration"); - made_name = Swig_name_make(n, Namespaceprefix, name, decl, add_oldname); - Delattr(n, "parsing_template_declaration"); - - return made_name; -} - -/* Generate an unnamed identifier */ -static String *make_unnamed(void) { - unnamed++; - return NewStringf("$unnamed%d$",unnamed); -} - -/* Return if the node is a friend declaration */ -static int is_friend(Node *n) { - return Cmp(Getattr(n,"storage"),"friend") == 0; -} - -static int is_operator(String *name) { - return Strncmp(name,"operator ", 9) == 0; -} - - -/* Add declaration list to symbol table */ -static int add_only_one = 0; - -static void add_symbols(Node *n) { - String *decl; - String *wrn = 0; - - if (inclass && n) { - cparse_normalize_void(n); - } - while (n) { - String *symname = 0; - /* for friends, we need to pop the scope once */ - String *old_prefix = 0; - Symtab *old_scope = 0; - int isfriend = inclass && is_friend(n); - int iscdecl = Cmp(nodeType(n),"cdecl") == 0; - int only_csymbol = 0; - - if (inclass) { - String *name = Getattr(n, "name"); - if (isfriend) { - /* for friends, we need to add the scopename if needed */ - String *prefix = name ? Swig_scopename_prefix(name) : 0; - old_prefix = Namespaceprefix; - old_scope = Swig_symbol_popscope(); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - if (!prefix) { - if (name && !is_operator(name) && Namespaceprefix) { - String *nname = NewStringf("%s::%s", Namespaceprefix, name); - Setattr(n,"name",nname); - Delete(nname); - } - } else { - Symtab *st = Swig_symbol_getscope(prefix); - String *ns = st ? Getattr(st,"name") : prefix; - String *base = Swig_scopename_last(name); - String *nname = NewStringf("%s::%s", ns, base); - Setattr(n,"name",nname); - Delete(nname); - Delete(base); - Delete(prefix); - } - Namespaceprefix = 0; - } else { - /* for member functions, we need to remove the redundant - class scope if provided, as in - - struct Foo { - int Foo::method(int a); - }; - - */ - String *prefix = name ? Swig_scopename_prefix(name) : 0; - if (prefix) { - if (Classprefix && (Equal(prefix,Classprefix))) { - String *base = Swig_scopename_last(name); - Setattr(n,"name",base); - Delete(base); - } - Delete(prefix); - } - } - } - - if (!isfriend && (inclass || extendmode)) { - Setattr(n,"ismember","1"); - } - - if (extendmode) { - if (!Getattr(n, "template")) - SetFlag(n,"isextendmember"); - } - - if (!isfriend && inclass) { - if ((cplus_mode != CPLUS_PUBLIC)) { - only_csymbol = 1; - if (cplus_mode == CPLUS_PROTECTED) { - Setattr(n,"access", "protected"); - only_csymbol = !Swig_need_protected(n); - } else { - Setattr(n,"access", "private"); - /* private are needed only when they are pure virtuals - why? */ - if ((Cmp(Getattr(n,"storage"),"virtual") == 0) && (Cmp(Getattr(n,"value"),"0") == 0)) { - only_csymbol = 0; - } - if (Cmp(nodeType(n),"destructor") == 0) { - /* Needed for "unref" feature */ - only_csymbol = 0; - } - } - } else { - Setattr(n,"access", "public"); - } - } - if (Getattr(n,"sym:name")) { - n = nextSibling(n); - continue; - } - decl = Getattr(n,"decl"); - if (!SwigType_isfunction(decl)) { - String *name = Getattr(n,"name"); - String *makename = Getattr(n,"parser:makename"); - if (iscdecl) { - String *storage = Getattr(n, "storage"); - if (Cmp(storage,"typedef") == 0) { - Setattr(n,"kind","typedef"); - } else { - SwigType *type = Getattr(n,"type"); - String *value = Getattr(n,"value"); - Setattr(n,"kind","variable"); - if (value && Len(value)) { - Setattr(n,"hasvalue","1"); - } - if (type) { - SwigType *ty; - SwigType *tmp = 0; - if (decl) { - ty = tmp = Copy(type); - SwigType_push(ty,decl); - } else { - ty = type; - } - if (!SwigType_ismutable(ty) || (storage && Strstr(storage, "constexpr"))) { - SetFlag(n,"hasconsttype"); - SetFlag(n,"feature:immutable"); - } - if (tmp) Delete(tmp); - } - if (!type) { - Printf(stderr,"notype name %s\n", name); - } - } - } - Swig_features_get(Swig_cparse_features(), Namespaceprefix, name, 0, n); - if (makename) { - symname = make_name(n, makename,0); - Delattr(n,"parser:makename"); /* temporary information, don't leave it hanging around */ - } else { - makename = name; - symname = make_name(n, makename,0); - } - - if (!symname) { - symname = Copy(Getattr(n,"unnamed")); - } - if (symname) { - if (parsing_template_declaration) - SetFlag(n, "parsing_template_declaration"); - wrn = Swig_name_warning(n, Namespaceprefix, symname,0); - Delattr(n, "parsing_template_declaration"); - } - } else { - String *name = Getattr(n,"name"); - SwigType *fdecl = Copy(decl); - SwigType *fun = SwigType_pop_function(fdecl); - if (iscdecl) { - Setattr(n,"kind","function"); - } - - Swig_features_get(Swig_cparse_features(),Namespaceprefix,name,fun,n); - - symname = make_name(n, name,fun); - if (parsing_template_declaration) - SetFlag(n, "parsing_template_declaration"); - wrn = Swig_name_warning(n, Namespaceprefix,symname,fun); - Delattr(n, "parsing_template_declaration"); - - Delete(fdecl); - Delete(fun); - - } - if (!symname) { - n = nextSibling(n); - continue; - } - if (cparse_cplusplus) { - String *value = Getattr(n, "value"); - if (value && Strcmp(value, "delete") == 0) { - /* C++11 deleted definition / deleted function */ - SetFlag(n,"deleted"); - SetFlag(n,"feature:ignore"); - } - if (SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) { - /* Ignore rvalue ref-qualifiers by default - * Use Getattr instead of GetFlag to handle explicit ignore and explicit not ignore */ - if (!(Getattr(n, "feature:ignore") || Strncmp(symname, "$ignore", 7) == 0)) { - SWIG_WARN_NODE_BEGIN(n); - Swig_warning(WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED, Getfile(n), Getline(n), - "Method with rvalue ref-qualifier %s ignored.\n", Swig_name_decl(n)); - SWIG_WARN_NODE_END(n); - SetFlag(n, "feature:ignore"); - } - } - } - if (only_csymbol || GetFlag(n, "feature:ignore") || Strncmp(symname, "$ignore", 7) == 0) { - /* Only add to C symbol table and continue */ - Swig_symbol_add(0, n); - if (!only_csymbol && !GetFlag(n, "feature:ignore")) { - /* Print the warning attached to $ignore name, if any */ - char *c = Char(symname) + 7; - if (strlen(c)) { - SWIG_WARN_NODE_BEGIN(n); - Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1); - SWIG_WARN_NODE_END(n); - } - /* If the symbol was ignored via "rename" and is visible, set also feature:ignore*/ - SetFlag(n, "feature:ignore"); - } - if (!GetFlag(n, "feature:ignore") && Strcmp(symname,"$ignore") == 0) { - /* Add feature:ignore if the symbol was explicitly ignored, regardless of visibility */ - SetFlag(n, "feature:ignore"); - } - } else { - Node *c; - if ((wrn) && (Len(wrn))) { - String *metaname = symname; - if (!Getmeta(metaname,"already_warned")) { - SWIG_WARN_NODE_BEGIN(n); - Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn); - SWIG_WARN_NODE_END(n); - Setmeta(metaname,"already_warned","1"); - } - } - c = Swig_symbol_add(symname,n); - - if (c != n) { - /* symbol conflict attempting to add in the new symbol */ - if (Getattr(n,"sym:weak")) { - Setattr(n,"sym:name",symname); - } else { - String *e = NewStringEmpty(); - String *en = NewStringEmpty(); - String *ec = NewStringEmpty(); - int redefined = Swig_need_redefined_warn(n,c,inclass); - if (redefined) { - Printf(en,"Identifier '%s' redefined (ignored)",symname); - Printf(ec,"previous definition of '%s'",symname); - } else { - Printf(en,"Redundant redeclaration of '%s'",symname); - Printf(ec,"previous declaration of '%s'",symname); - } - if (Cmp(symname,Getattr(n,"name"))) { - Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name"))); - } - Printf(en,","); - if (Cmp(symname,Getattr(c,"name"))) { - Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name"))); - } - Printf(ec,"."); - SWIG_WARN_NODE_BEGIN(n); - if (redefined) { - Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en); - Swig_warning(WARN_PARSE_REDEFINED,Getfile(c),Getline(c),"%s\n",ec); - } else if (!is_friend(n) && !is_friend(c)) { - Swig_warning(WARN_PARSE_REDUNDANT,Getfile(n),Getline(n),"%s\n",en); - Swig_warning(WARN_PARSE_REDUNDANT,Getfile(c),Getline(c),"%s\n",ec); - } - SWIG_WARN_NODE_END(n); - Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(n),Getline(n),en, - Getfile(c),Getline(c),ec); - Setattr(n,"error",e); - Delete(e); - Delete(en); - Delete(ec); - } - } - } - /* restore the class scope if needed */ - if (isfriend) { - Swig_symbol_setscope(old_scope); - if (old_prefix) { - Delete(Namespaceprefix); - Namespaceprefix = old_prefix; - } - } - Delete(symname); - - if (add_only_one) return; - n = nextSibling(n); - } -} - - -/* add symbols a parse tree node copy */ - -static void add_symbols_copy(Node *n) { - String *name; - int emode = 0; - while (n) { - char *cnodeType = Char(nodeType(n)); - - if (strcmp(cnodeType,"access") == 0) { - String *kind = Getattr(n,"kind"); - if (Strcmp(kind,"public") == 0) { - cplus_mode = CPLUS_PUBLIC; - } else if (Strcmp(kind,"private") == 0) { - cplus_mode = CPLUS_PRIVATE; - } else if (Strcmp(kind,"protected") == 0) { - cplus_mode = CPLUS_PROTECTED; - } - n = nextSibling(n); - continue; - } - - add_oldname = Getattr(n,"sym:name"); - if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) { - int old_inclass = -1; - Node *old_current_class = 0; - if (add_oldname) { - DohIncref(add_oldname); - /* Disable this, it prevents %rename to work with templates */ - /* If already renamed, we used that name */ - /* - if (Strcmp(add_oldname, Getattr(n,"name")) != 0) { - Delete(yyrename); - yyrename = Copy(add_oldname); - } - */ - } - Delattr(n,"sym:needs_symtab"); - Delattr(n,"sym:name"); - - add_only_one = 1; - add_symbols(n); - - if (Getattr(n,"partialargs")) { - Swig_symbol_cadd(Getattr(n,"partialargs"),n); - } - add_only_one = 0; - name = Getattr(n,"name"); - if (Getattr(n,"requires_symtab")) { - Swig_symbol_newscope(); - Swig_symbol_setscopename(name); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - } - if (strcmp(cnodeType,"class") == 0) { - old_inclass = inclass; - inclass = 1; - old_current_class = current_class; - current_class = n; - if (Strcmp(Getattr(n,"kind"),"class") == 0) { - cplus_mode = CPLUS_PRIVATE; - } else { - cplus_mode = CPLUS_PUBLIC; - } - } - if (strcmp(cnodeType,"extend") == 0) { - emode = cplus_mode; - cplus_mode = CPLUS_PUBLIC; - } - add_symbols_copy(firstChild(n)); - if (strcmp(cnodeType,"extend") == 0) { - cplus_mode = emode; - } - if (Getattr(n,"requires_symtab")) { - Setattr(n,"symtab", Swig_symbol_popscope()); - Delattr(n,"requires_symtab"); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - } - if (add_oldname) { - Delete(add_oldname); - add_oldname = 0; - } - if (strcmp(cnodeType,"class") == 0) { - inclass = old_inclass; - current_class = old_current_class; - } - } else { - if (strcmp(cnodeType,"extend") == 0) { - emode = cplus_mode; - cplus_mode = CPLUS_PUBLIC; - } - add_symbols_copy(firstChild(n)); - if (strcmp(cnodeType,"extend") == 0) { - cplus_mode = emode; - } - } - n = nextSibling(n); - } -} - -/* Add in the "defaultargs" attribute for functions in instantiated templates. - * n should be any instantiated template (class or start of linked list of functions). */ -static void update_defaultargs(Node *n) { - if (n) { - Node *firstdefaultargs = n; - update_defaultargs(firstChild(n)); - n = nextSibling(n); - /* recursively loop through nodes of all types, but all we really need are the overloaded functions */ - while (n) { - update_defaultargs(firstChild(n)); - if (!Getattr(n, "defaultargs")) { - if (Getattr(n, "needs_defaultargs")) { - Setattr(n, "defaultargs", firstdefaultargs); - Delattr(n, "needs_defaultargs"); - } else { - firstdefaultargs = n; - } - } else { - /* Functions added in with %extend (for specialized template classes) will already have default args patched up */ - assert(Getattr(n, "defaultargs") == firstdefaultargs); - } - n = nextSibling(n); - } - } -} - -/* Check a set of declarations to see if any are pure-abstract */ - -static List *pure_abstracts(Node *n) { - List *abstracts = 0; - while (n) { - if (Cmp(nodeType(n),"cdecl") == 0) { - String *decl = Getattr(n,"decl"); - if (SwigType_isfunction(decl)) { - String *init = Getattr(n,"value"); - if (Cmp(init,"0") == 0) { - if (!abstracts) { - abstracts = NewList(); - } - Append(abstracts,n); - SetFlag(n,"abstract"); - } - } - } else if (Cmp(nodeType(n),"destructor") == 0) { - if (Cmp(Getattr(n,"value"),"0") == 0) { - if (!abstracts) { - abstracts = NewList(); - } - Append(abstracts,n); - SetFlag(n,"abstract"); - } - } - n = nextSibling(n); - } - return abstracts; -} - -/* Recompute the "abstracts" attribute for the classes in instantiated templates, similarly to update_defaultargs() above. */ -static void update_abstracts(Node *n) { - for (; n; n = nextSibling(n)) { - Node* const child = firstChild(n); - if (!child) - continue; - - update_abstracts(child); - - if (Getattr(n, "needs_abstracts")) { - Setattr(n, "abstracts", pure_abstracts(child)); - Delattr(n, "needs_abstracts"); - } - } -} - -/* Make a classname */ - -static String *make_class_name(String *name) { - String *nname = 0; - String *prefix; - if (Namespaceprefix) { - nname= NewStringf("%s::%s", Namespaceprefix, name); - } else { - nname = NewString(name); - } - prefix = SwigType_istemplate_templateprefix(nname); - if (prefix) { - String *args, *qargs; - args = SwigType_templateargs(nname); - qargs = Swig_symbol_type_qualify(args,0); - Append(prefix,qargs); - Delete(nname); - Delete(args); - Delete(qargs); - nname = prefix; - } - return nname; -} - -/* Use typedef name as class name */ - -static void add_typedef_name(Node *n, Node *declnode, String *oldName, Symtab *cscope, String *scpname) { - String *class_rename = 0; - SwigType *decl = Getattr(declnode, "decl"); - if (!decl || !Len(decl)) { - String *cname; - String *tdscopename; - String *class_scope = Swig_symbol_qualifiedscopename(cscope); - String *name = Getattr(declnode, "name"); - cname = Copy(name); - Setattr(n, "tdname", cname); - tdscopename = class_scope ? NewStringf("%s::%s", class_scope, name) : Copy(name); - class_rename = Getattr(n, "class_rename"); - if (class_rename && (Strcmp(class_rename, oldName) == 0)) - Setattr(n, "class_rename", NewString(name)); - if (!classes_typedefs) classes_typedefs = NewHash(); - if (!Equal(scpname, tdscopename) && !Getattr(classes_typedefs, tdscopename)) { - Setattr(classes_typedefs, tdscopename, n); - } - Setattr(n, "decl", decl); - Delete(class_scope); - Delete(cname); - Delete(tdscopename); - } -} - -/* If the class name is qualified. We need to create or lookup namespace entries */ - -static Symtab *set_scope_to_global(void) { - Symtab *symtab = Swig_symbol_global_scope(); - Swig_symbol_setscope(symtab); - return symtab; -} - -/* Remove the block braces, { and }, if the 'noblock' attribute is set. - * Node *kw can be either a Hash or Parmlist. */ -static String *remove_block(Node *kw, const String *inputcode) { - String *modified_code = 0; - while (kw) { - String *name = Getattr(kw,"name"); - if (name && (Cmp(name,"noblock") == 0)) { - char *cstr = Char(inputcode); - int len = Len(inputcode); - if (len && cstr[0] == '{') { - --len; ++cstr; - if (len && cstr[len - 1] == '}') { --len; } - /* we now remove the extra spaces */ - while (len && isspace((int)cstr[0])) { --len; ++cstr; } - while (len && isspace((int)cstr[len - 1])) { --len; } - modified_code = NewStringWithSize(cstr, len); - break; - } - } - kw = nextSibling(kw); - } - return modified_code; -} - -/* -#define RESOLVE_DEBUG 1 -*/ -static Node *nscope = 0; -static Node *nscope_inner = 0; - -/* Remove the scope prefix from cname and return the base name without the prefix. - * The scopes required for the symbol name are resolved and/or created, if required. - * For example AA::BB::CC as input returns CC and creates the namespace AA then inner - * namespace BB in the current scope. */ -static String *resolve_create_node_scope(String *cname, int is_class_definition) { - Symtab *gscope = 0; - Node *cname_node = 0; - String *last = Swig_scopename_last(cname); - nscope = 0; - nscope_inner = 0; - - if (Strncmp(cname,"::" ,2) != 0) { - if (is_class_definition) { - /* Only lookup symbols which are in scope via a using declaration but not via a using directive. - For example find y via 'using x::y' but not y via a 'using namespace x'. */ - cname_node = Swig_symbol_clookup_no_inherit(cname, 0); - if (!cname_node) { - Node *full_lookup_node = Swig_symbol_clookup(cname, 0); - if (full_lookup_node) { - /* This finds a symbol brought into scope via both a using directive and a using declaration. */ - Node *last_node = Swig_symbol_clookup_no_inherit(last, 0); - if (last_node == full_lookup_node) - cname_node = last_node; - } - } - } else { - /* For %template, the template needs to be in scope via any means. */ - cname_node = Swig_symbol_clookup(cname, 0); - } - } -#if RESOLVE_DEBUG - if (!cname_node) - Printf(stdout, "symbol does not yet exist (%d): [%s]\n", is_class_definition, cname); - else - Printf(stdout, "symbol does exist (%d): [%s]\n", is_class_definition, cname); -#endif - - if (cname_node) { - /* The symbol has been defined already or is in another scope. - If it is a weak symbol, it needs replacing and if it was brought into the current scope, - the scope needs adjusting appropriately for the new symbol. - Similarly for defined templates. */ - Symtab *symtab = Getattr(cname_node, "sym:symtab"); - Node *sym_weak = Getattr(cname_node, "sym:weak"); - if ((symtab && sym_weak) || Equal(nodeType(cname_node), "template")) { - /* Check if the scope is the current scope */ - String *current_scopename = Swig_symbol_qualifiedscopename(0); - String *found_scopename = Swig_symbol_qualifiedscopename(symtab); - if (!current_scopename) - current_scopename = NewString(""); - if (!found_scopename) - found_scopename = NewString(""); - - { - int fail = 1; - List *current_scopes = Swig_scopename_tolist(current_scopename); - List *found_scopes = Swig_scopename_tolist(found_scopename); - Iterator cit = First(current_scopes); - Iterator fit = First(found_scopes); -#if RESOLVE_DEBUG -Printf(stdout, "comparing current: [%s] found: [%s]\n", current_scopename, found_scopename); -#endif - for (; fit.item && cit.item; fit = Next(fit), cit = Next(cit)) { - String *current = cit.item; - String *found = fit.item; -#if RESOLVE_DEBUG - Printf(stdout, " looping %s %s\n", current, found); -#endif - if (Strcmp(current, found) != 0) - break; - } - - if (!cit.item) { - String *subscope = NewString(""); - for (; fit.item; fit = Next(fit)) { - if (Len(subscope) > 0) - Append(subscope, "::"); - Append(subscope, fit.item); - } - if (Len(subscope) > 0) - cname = NewStringf("%s::%s", subscope, last); - else - cname = Copy(last); -#if RESOLVE_DEBUG - Printf(stdout, "subscope to create: [%s] cname: [%s]\n", subscope, cname); -#endif - fail = 0; - Delete(subscope); - } else { - if (is_class_definition) { - if (!fit.item) { - /* It is valid to define a new class with the same name as one forward declared in a parent scope */ - fail = 0; - } else if (Swig_scopename_check(cname)) { - /* Classes defined with scope qualifiers must have a matching forward declaration in matching scope */ - fail = 1; - } else { - /* This may let through some invalid cases */ - fail = 0; - } -#if RESOLVE_DEBUG - Printf(stdout, "scope for class definition, fail: %d\n", fail); -#endif - } else { -#if RESOLVE_DEBUG - Printf(stdout, "no matching base scope for template\n"); -#endif - fail = 1; - } - } - - Delete(found_scopes); - Delete(current_scopes); - - if (fail) { - String *cname_resolved = NewStringf("%s::%s", found_scopename, last); - Swig_error(cparse_file, cparse_line, "'%s' resolves to '%s' and was incorrectly instantiated in scope '%s' instead of within scope '%s'.\n", cname, cname_resolved, current_scopename, found_scopename); - cname = Copy(last); - Delete(cname_resolved); - } - } - - Delete(current_scopename); - Delete(found_scopename); - } - } else if (!is_class_definition) { - /* A template instantiation requires a template to be found in scope... fail here too? - Swig_error(cparse_file, cparse_line, "No template found to instantiate '%s' with %%template.\n", cname); - */ - } - - if (Swig_scopename_check(cname)) { - Node *ns; - String *prefix = Swig_scopename_prefix(cname); - if (prefix && (Strncmp(prefix,"::",2) == 0)) { -/* I don't think we can use :: global scope to declare classes and hence neither %template. - consider reporting error instead - wsfulton. */ - /* Use the global scope */ - String *nprefix = NewString(Char(prefix)+2); - Delete(prefix); - prefix= nprefix; - gscope = set_scope_to_global(); - } - if (Len(prefix) == 0) { - String *base = Copy(last); - /* Use the global scope, but we need to add a 'global' namespace. */ - if (!gscope) gscope = set_scope_to_global(); - /* note that this namespace is not the "unnamed" one, - and we don't use Setattr(nscope,"name", ""), - because the unnamed namespace is private */ - nscope = new_node("namespace"); - Setattr(nscope,"symtab", gscope);; - nscope_inner = nscope; - Delete(last); - return base; - } - /* Try to locate the scope */ - ns = Swig_symbol_clookup(prefix,0); - if (!ns) { - Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix); - } else { - Symtab *nstab = Getattr(ns,"symtab"); - if (!nstab) { - Swig_error(cparse_file,cparse_line, "'%s' is not defined as a valid scope.\n", prefix); - ns = 0; - } else { - /* Check if the node scope is the current scope */ - String *tname = Swig_symbol_qualifiedscopename(0); - String *nname = Swig_symbol_qualifiedscopename(nstab); - if (tname && (Strcmp(tname,nname) == 0)) { - ns = 0; - cname = Copy(last); - } - Delete(tname); - Delete(nname); - } - if (ns) { - /* we will try to create a new node using the namespaces we - can find in the scope name */ - List *scopes = Swig_scopename_tolist(prefix); - String *sname; - Iterator si; - - for (si = First(scopes); si.item; si = Next(si)) { - Node *ns1,*ns2; - sname = si.item; - ns1 = Swig_symbol_clookup(sname,0); - assert(ns1); - if (Strcmp(nodeType(ns1),"namespace") == 0) { - if (Getattr(ns1,"alias")) { - ns1 = Getattr(ns1,"namespace"); - } - } else { - /* now this last part is a class */ - si = Next(si); - /* or a nested class tree, which is unrolled here */ - for (; si.item; si = Next(si)) { - if (si.item) { - Printf(sname,"::%s",si.item); - } - } - /* we get the 'inner' class */ - nscope_inner = Swig_symbol_clookup(sname,0); - /* set the scope to the inner class */ - Swig_symbol_setscope(Getattr(nscope_inner,"symtab")); - /* save the last namespace prefix */ - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - /* and return the node name, including the inner class prefix */ - break; - } - /* here we just populate the namespace tree as usual */ - ns2 = new_node("namespace"); - Setattr(ns2,"name",sname); - Setattr(ns2,"symtab", Getattr(ns1,"symtab")); - add_symbols(ns2); - Swig_symbol_setscope(Getattr(ns1,"symtab")); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - if (nscope_inner) { - if (Getattr(nscope_inner,"symtab") != Getattr(ns2,"symtab")) { - appendChild(nscope_inner,ns2); - Delete(ns2); - } - } - nscope_inner = ns2; - if (!nscope) nscope = ns2; - } - cname = Copy(last); - Delete(scopes); - } - } - Delete(prefix); - } - Delete(last); - - return cname; -} - -/* look for simple typedef name in typedef list */ -static String *try_to_find_a_name_for_unnamed_structure(const char *storage, Node *decls) { - String *name = 0; - Node *n = decls; - if (storage && (strcmp(storage, "typedef") == 0)) { - for (; n; n = nextSibling(n)) { - if (!Len(Getattr(n, "decl"))) { - name = Copy(Getattr(n, "name")); - break; - } - } - } - return name; -} - -/* traverse copied tree segment, and update outer class links*/ -static void update_nested_classes(Node *n) -{ - Node *c = firstChild(n); - while (c) { - if (Getattr(c, "nested:outer")) - Setattr(c, "nested:outer", n); - update_nested_classes(c); - c = nextSibling(c); - } -} - -/* ----------------------------------------------------------------------------- - * nested_forward_declaration() - * - * Nested struct handling for C++ code if the nested classes are disabled. - * Create the nested class/struct/union as a forward declaration. - * ----------------------------------------------------------------------------- */ - -static Node *nested_forward_declaration(const char *storage, const char *kind, String *sname, String *name, Node *cpp_opt_declarators) { - Node *nn = 0; - - if (sname) { - /* Add forward declaration of the nested type */ - Node *n = new_node("classforward"); - Setattr(n, "kind", kind); - Setattr(n, "name", sname); - Setattr(n, "storage", storage); - Setattr(n, "sym:weak", "1"); - add_symbols(n); - nn = n; - } - - /* Add any variable instances. Also add in any further typedefs of the nested type. - Note that anonymous typedefs (eg typedef struct {...} a, b;) are treated as class forward declarations */ - if (cpp_opt_declarators) { - int storage_typedef = (storage && (strcmp(storage, "typedef") == 0)); - int variable_of_anonymous_type = !sname && !storage_typedef; - if (!variable_of_anonymous_type) { - int anonymous_typedef = !sname && (storage && (strcmp(storage, "typedef") == 0)); - Node *n = cpp_opt_declarators; - SwigType *type = name; - while (n) { - Setattr(n, "type", type); - Setattr(n, "storage", storage); - if (anonymous_typedef) { - Setattr(n, "nodeType", "classforward"); - Setattr(n, "sym:weak", "1"); - } - n = nextSibling(n); - } - add_symbols(cpp_opt_declarators); - - if (nn) { - set_nextSibling(nn, cpp_opt_declarators); - } else { - nn = cpp_opt_declarators; - } - } - } - - if (!currentOuterClass || !GetFlag(currentOuterClass, "nested")) { - if (nn && Equal(nodeType(nn), "classforward")) { - Node *n = nn; - if (!GetFlag(n, "feature:ignore")) { - SWIG_WARN_NODE_BEGIN(n); - Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, sname ? sname : name); - SWIG_WARN_NODE_END(n); - } - } else { - Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", kind); - } - } - - return nn; -} - - -Node *Swig_cparse(File *f) { - scanner_file(f); - top = 0; - yyparse(); - return top; -} - -static void single_new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) { - String *fname; - String *name; - String *fixname; - SwigType *t = Copy(type); - - /* Printf(stdout, "single_new_feature: [%s] [%s] [%s] [%s] [%s] [%s]\n", featurename, val, declaratorid, t, ParmList_str_defaultargs(declaratorparms), qualifier); */ - - /* Warn about deprecated features */ - if (strcmp(featurename, "nestedworkaround") == 0) - Swig_warning(WARN_DEPRECATED_NESTED_WORKAROUND, cparse_file, cparse_line, "The 'nestedworkaround' feature is deprecated.\n"); - - fname = NewStringf("feature:%s",featurename); - if (declaratorid) { - fixname = feature_identifier_fix(declaratorid); - } else { - fixname = NewStringEmpty(); - } - if (Namespaceprefix) { - name = NewStringf("%s::%s",Namespaceprefix, fixname); - } else { - name = fixname; - } - - if (declaratorparms) Setmeta(val,"parms",declaratorparms); - if (!Len(t)) t = 0; - if (t) { - if (qualifier) SwigType_push(t,qualifier); - if (SwigType_isfunction(t)) { - SwigType *decl = SwigType_pop_function(t); - if (SwigType_ispointer(t)) { - String *nname = NewStringf("*%s",name); - Swig_feature_set(Swig_cparse_features(), nname, decl, fname, val, featureattribs); - Delete(nname); - } else { - Swig_feature_set(Swig_cparse_features(), name, decl, fname, val, featureattribs); - } - Delete(decl); - } else if (SwigType_ispointer(t)) { - String *nname = NewStringf("*%s",name); - Swig_feature_set(Swig_cparse_features(),nname,0,fname,val, featureattribs); - Delete(nname); - } - } else { - /* Global feature, that is, feature not associated with any particular symbol */ - Swig_feature_set(Swig_cparse_features(),name,0,fname,val, featureattribs); - } - Delete(fname); - Delete(name); -} - -/* Add a new feature to the Hash. Additional features are added if the feature has a parameter list (declaratorparms) - * and one or more of the parameters have a default argument. An extra feature is added for each defaulted parameter, - * simulating the equivalent overloaded method. */ -static void new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) { - - ParmList *declparms = declaratorparms; - - /* remove the { and } braces if the noblock attribute is set */ - String *newval = remove_block(featureattribs, val); - val = newval ? newval : val; - - /* Add the feature */ - single_new_feature(featurename, val, featureattribs, declaratorid, type, declaratorparms, qualifier); - - /* Add extra features if there are default parameters in the parameter list */ - if (type) { - while (declparms) { - if (ParmList_has_defaultargs(declparms)) { - - /* Create a parameter list for the new feature by copying all - but the last (defaulted) parameter */ - ParmList* newparms = CopyParmListMax(declparms, ParmList_len(declparms)-1); - - /* Create new declaration - with the last parameter removed */ - SwigType *newtype = Copy(type); - Delete(SwigType_pop_function(newtype)); /* remove the old parameter list from newtype */ - SwigType_add_function(newtype,newparms); - - single_new_feature(featurename, Copy(val), featureattribs, declaratorid, newtype, newparms, qualifier); - declparms = newparms; - } else { - declparms = 0; - } - } - } -} - -/* check if a function declaration is a plain C object */ -static int is_cfunction(Node *n) { - if (!cparse_cplusplus || cparse_externc) - return 1; - if (Swig_storage_isexternc(n)) { - return 1; - } - return 0; -} - -/* If the Node is a function with parameters, check to see if any of the parameters - * have default arguments. If so create a new function for each defaulted argument. - * The additional functions form a linked list of nodes with the head being the original Node n. */ -static void default_arguments(Node *n) { - Node *function = n; - - if (function) { - ParmList *varargs = Getattr(function,"feature:varargs"); - if (varargs) { - /* Handles the %varargs directive by looking for "feature:varargs" and - * substituting ... with an alternative set of arguments. */ - Parm *p = Getattr(function,"parms"); - Parm *pp = 0; - while (p) { - SwigType *t = Getattr(p,"type"); - if (Strcmp(t,"v(...)") == 0) { - if (pp) { - ParmList *cv = Copy(varargs); - set_nextSibling(pp,cv); - Delete(cv); - } else { - ParmList *cv = Copy(varargs); - Setattr(function,"parms", cv); - Delete(cv); - } - break; - } - pp = p; - p = nextSibling(p); - } - } - - /* Do not add in functions if kwargs is being used or if user wants old default argument wrapping - (one wrapped method per function irrespective of number of default arguments) */ - if (compact_default_args - || is_cfunction(function) - || GetFlag(function,"feature:compactdefaultargs") - || (GetFlag(function,"feature:kwargs") && kwargs_supported)) { - ParmList *p = Getattr(function,"parms"); - if (p) - Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */ - function = 0; /* don't add in extra methods */ - } - } - - while (function) { - ParmList *parms = Getattr(function,"parms"); - if (ParmList_has_defaultargs(parms)) { - - /* Create a parameter list for the new function by copying all - but the last (defaulted) parameter */ - ParmList* newparms = CopyParmListMax(parms,ParmList_len(parms)-1); - - /* Create new function and add to symbol table */ - { - SwigType *ntype = Copy(nodeType(function)); - char *cntype = Char(ntype); - Node *new_function = new_node(ntype); - SwigType *decl = Copy(Getattr(function,"decl")); - int constqualifier = SwigType_isconst(decl); - String *ccode = Copy(Getattr(function,"code")); - String *cstorage = Copy(Getattr(function,"storage")); - String *cvalue = Copy(Getattr(function,"value")); - SwigType *ctype = Copy(Getattr(function,"type")); - String *cthrow = Copy(Getattr(function,"throw")); - - Delete(SwigType_pop_function(decl)); /* remove the old parameter list from decl */ - SwigType_add_function(decl,newparms); - if (constqualifier) - SwigType_add_qualifier(decl,"const"); - - Setattr(new_function,"name", Getattr(function,"name")); - Setattr(new_function,"code", ccode); - Setattr(new_function,"decl", decl); - Setattr(new_function,"parms", newparms); - Setattr(new_function,"storage", cstorage); - Setattr(new_function,"value", cvalue); - Setattr(new_function,"type", ctype); - Setattr(new_function,"throw", cthrow); - - Delete(ccode); - Delete(cstorage); - Delete(cvalue); - Delete(ctype); - Delete(cthrow); - Delete(decl); - - { - Node *throws = Getattr(function,"throws"); - ParmList *pl = CopyParmList(throws); - if (throws) Setattr(new_function,"throws",pl); - Delete(pl); - } - - /* copy specific attributes for global (or in a namespace) template functions - these are not templated class methods */ - if (strcmp(cntype,"template") == 0) { - Node *templatetype = Getattr(function,"templatetype"); - Node *symtypename = Getattr(function,"sym:typename"); - Parm *templateparms = Getattr(function,"templateparms"); - if (templatetype) { - Node *tmp = Copy(templatetype); - Setattr(new_function,"templatetype",tmp); - Delete(tmp); - } - if (symtypename) { - Node *tmp = Copy(symtypename); - Setattr(new_function,"sym:typename",tmp); - Delete(tmp); - } - if (templateparms) { - Parm *tmp = CopyParmList(templateparms); - Setattr(new_function,"templateparms",tmp); - Delete(tmp); - } - } else if (strcmp(cntype,"constructor") == 0) { - /* only copied for constructors as this is not a user defined feature - it is hard coded in the parser */ - if (GetFlag(function,"feature:new")) SetFlag(new_function,"feature:new"); - } - - add_symbols(new_function); - /* mark added functions as ones with overloaded parameters and point to the parsed method */ - Setattr(new_function,"defaultargs", n); - - /* Point to the new function, extending the linked list */ - set_nextSibling(function, new_function); - Delete(new_function); - function = new_function; - - Delete(ntype); - } - } else { - function = 0; - } - } -} - -/* ----------------------------------------------------------------------------- - * mark_nodes_as_extend() - * - * Used by the %extend to mark subtypes with "feature:extend". - * template instances declared within %extend are skipped - * ----------------------------------------------------------------------------- */ - -static void mark_nodes_as_extend(Node *n) { - for (; n; n = nextSibling(n)) { - if (Getattr(n, "template") && Strcmp(nodeType(n), "class") == 0) - continue; - /* Fix me: extend is not a feature. Replace with isextendmember? */ - Setattr(n, "feature:extend", "1"); - mark_nodes_as_extend(firstChild(n)); - } -} - -/* ----------------------------------------------------------------------------- - * add_qualifier_to_declarator() - * - * Normally the qualifier is pushed on to the front of the type. - * Adding a qualifier to a pointer to member function is a special case. - * For example : typedef double (Cls::*pmf)(void) const; - * The qualifier is : q(const). - * The declarator is : m(Cls).f(void). - * We need : m(Cls).q(const).f(void). - * ----------------------------------------------------------------------------- */ - -static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier) { - int is_pointer_to_member_function = 0; - String *decl = Copy(type); - String *poppedtype = NewString(""); - assert(qualifier); - - while (decl) { - if (SwigType_ismemberpointer(decl)) { - String *memberptr = SwigType_pop(decl); - if (SwigType_isfunction(decl)) { - is_pointer_to_member_function = 1; - SwigType_push(decl, qualifier); - SwigType_push(decl, memberptr); - Insert(decl, 0, poppedtype); - Delete(memberptr); - break; - } else { - Append(poppedtype, memberptr); - } - Delete(memberptr); - } else { - String *popped = SwigType_pop(decl); - if (!popped) - break; - Append(poppedtype, popped); - Delete(popped); - } - } - - if (!is_pointer_to_member_function) { - Delete(decl); - decl = Copy(type); - SwigType_push(decl, qualifier); - } - - Delete(poppedtype); - return decl; -} - -%} - -%union { - const char *id; - List *bases; - struct Define { - String *val; - String *rawval; - int type; - String *qualifier; - String *refqualifier; - String *bitfield; - Parm *throws; - String *throwf; - String *nexcept; - String *final; - } dtype; - struct { - const char *type; - String *filename; - int line; - } loc; - struct { - char *id; - SwigType *type; - String *defarg; - ParmList *parms; - short have_parms; - ParmList *throws; - String *throwf; - String *nexcept; - String *final; - } decl; - Parm *tparms; - struct { - String *method; - Hash *kwargs; - } tmap; - struct { - String *type; - String *us; - } ptype; - SwigType *type; - String *str; - Parm *p; - ParmList *pl; - int intvalue; - Node *node; -}; - -// Define special token END for end of input. -%token END 0 - -%token <id> ID -%token <str> HBLOCK -%token <id> POUND -%token <id> STRING WSTRING -%token <loc> INCLUDE IMPORT INSERT -%token <str> CHARCONST WCHARCONST -%token <dtype> NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG NUM_BOOL -%token <intvalue> TYPEDEF -%token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64 -%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD ELLIPSIS -%token CONST_QUAL VOLATILE REGISTER STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET -%token BEGINFILE ENDOFFILE -%token ILLEGAL CONSTANT -%token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS -%token ENUM -%token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH EXPLICIT -%token STATIC_ASSERT CONSTEXPR THREAD_LOCAL DECLTYPE AUTO NOEXCEPT /* C++11 keywords */ -%token OVERRIDE FINAL /* C++11 identifiers with special meaning */ -%token USING -%token <node> NAMESPACE -%token NATIVE INLINE -%token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT -%token WARN -%token LESSTHAN GREATERTHAN DELETE_KW DEFAULT -%token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO LESSEQUALGREATER -%token ARROW -%token QUESTIONMARK -%token TYPES PARMS -%token NONID DSTAR DCNOT -%token <intvalue> TEMPLATE -%token <str> OPERATOR -%token <str> CONVERSIONOPERATOR -%token PARSETYPE PARSEPARM PARSEPARMS - -%token <str> DOXYGENSTRING -%token <str> DOXYGENPOSTSTRING - -%left CAST -%left QUESTIONMARK -%left LOR -%left LAND -%left OR -%left XOR -%left AND -%left EQUALTO NOTEQUALTO -%left GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO -%left LESSEQUALGREATER -%left LSHIFT RSHIFT -%left PLUS MINUS -%left STAR SLASH MODULO -%left UMINUS NOT LNOT -%left DCOLON - -%type <node> program interface declaration swig_directive ; - -/* SWIG directives */ -%type <node> extend_directive apply_directive clear_directive constant_directive ; -%type <node> echo_directive except_directive fragment_directive include_directive inline_directive ; -%type <node> insert_directive module_directive name_directive native_directive ; -%type <node> pragma_directive rename_directive feature_directive varargs_directive typemap_directive ; -%type <node> types_directive template_directive warn_directive ; - -/* C declarations */ -%type <node> c_declaration c_decl c_decl_tail c_enum_key c_enum_inherit c_enum_decl c_enum_forward_decl c_constructor_decl; -%type <node> enumlist enumlist_item edecl_with_dox edecl; - -/* C++ declarations */ -%type <node> cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl cpp_alternate_rettype; -%type <node> cpp_members cpp_member cpp_member_no_dox; -%type <node> cpp_constructor_decl cpp_destructor_decl cpp_protection_decl cpp_conversion_operator cpp_static_assert; -%type <node> cpp_swig_directive cpp_template_possible cpp_opt_declarators ; -%type <node> cpp_using_decl cpp_namespace_decl cpp_catch_decl cpp_lambda_decl; -%type <node> kwargs options; - -/* Misc */ -%type <id> identifier; -%type <dtype> initializer cpp_const exception_specification cv_ref_qualifier qualifiers_exception_specification; -%type <id> storage_class extern_string; -%type <pl> parms ptail rawparms varargs_parms ; -%type <pl> templateparameters templateparameterstail; -%type <p> parm_no_dox parm valparm rawvalparms valparms valptail ; -%type <p> typemap_parm tm_list tm_tail ; -%type <p> templateparameter ; -%type <id> templcpptype cpptype classkey classkeyopt access_specifier; -%type <node> base_specifier; -%type <str> variadic; -%type <type> type rawtype type_right anon_bitfield_type decltype ; -%type <bases> base_list inherit raw_inherit; -%type <dtype> definetype def_args etype default_delete deleted_definition explicit_default; -%type <dtype> expr exprnum exprsimple exprcompound valexpr exprmem callparms callptail; -%type <id> ename ; -%type <id> less_valparms_greater; -%type <str> type_qualifier; -%type <str> ref_qualifier; -%type <id> type_qualifier_raw; -%type <id> idstring idstringopt; -%type <id> pragma_lang; -%type <str> pragma_arg; -%type <loc> includetype; -%type <type> pointer primitive_type; -%type <decl> declarator direct_declarator notso_direct_declarator parameter_declarator plain_declarator; -%type <decl> abstract_declarator direct_abstract_declarator ctor_end; -%type <tmap> typemap_type; -%type <str> idcolon idcolontail idcolonnt idcolontailnt idtemplate idtemplatetemplate stringbrace stringbracesemi; -%type <str> string stringnum wstring; -%type <tparms> template_parms; -%type <dtype> cpp_end cpp_vend; -%type <intvalue> rename_namewarn; -%type <ptype> type_specifier primitive_type_list ; -%type <node> fname stringtype; -%type <node> featattr; -%type <node> lambda_introducer lambda_body lambda_template; -%type <pl> lambda_tail; -%type <str> virt_specifier_seq virt_specifier_seq_opt; -%type <str> class_virt_specifier_opt; - -%% - -/* ====================================================================== - * High-level Interface file - * - * An interface is just a sequence of declarations which may be SWIG directives - * or normal C declarations. - * ====================================================================== */ - -program : interface { - if (!classes) classes = NewHash(); - Setattr($1,"classes",classes); - Setattr($1,"name",ModuleName); - - if ((!module_node) && ModuleName) { - module_node = new_node("module"); - Setattr(module_node,"name",ModuleName); - } - Setattr($1,"module",module_node); - top = $1; - } - | PARSETYPE parm SEMI { - top = Copy(Getattr($2,"type")); - Delete($2); - } - | PARSETYPE error { - top = 0; - } - | PARSEPARM parm SEMI { - top = $2; - } - | PARSEPARM error { - top = 0; - } - | PARSEPARMS LPAREN parms RPAREN SEMI { - top = $3; - } - | PARSEPARMS error SEMI { - top = 0; - } - ; - -interface : interface declaration { - /* add declaration to end of linked list (the declaration isn't always a single declaration, sometimes it is a linked list itself) */ - if (currentDeclComment != NULL) { - set_comment($2, currentDeclComment); - currentDeclComment = NULL; - } - appendChild($1,$2); - $$ = $1; - } - | interface DOXYGENSTRING { - currentDeclComment = $2; - $$ = $1; - } - | interface DOXYGENPOSTSTRING { - Node *node = lastChild($1); - if (node) { - set_comment(node, $2); - } - $$ = $1; - } - | empty { - $$ = new_node("top"); - } - ; - -declaration : swig_directive { $$ = $1; } - | c_declaration { $$ = $1; } - | cpp_declaration { $$ = $1; } - | SEMI { $$ = 0; } - | error { - $$ = 0; - if (cparse_unknown_directive) { - Swig_error(cparse_file, cparse_line, "Unknown directive '%s'.\n", cparse_unknown_directive); - } else { - Swig_error(cparse_file, cparse_line, "Syntax error in input(1).\n"); - } - Exit(EXIT_FAILURE); - } -/* Out of class constructor/destructor declarations */ - | c_constructor_decl { - if ($$) { - add_symbols($$); - } - $$ = $1; - } - -/* Out of class conversion operator. For example: - inline A::operator char *() const { ... }. - - This is nearly impossible to parse normally. We just let the - first part generate a syntax error and then resynchronize on the - CONVERSIONOPERATOR token---discarding the rest of the definition. Ugh. - - */ - - | error CONVERSIONOPERATOR { - $$ = 0; - skip_decl(); - } - ; - -/* ====================================================================== - * SWIG DIRECTIVES - * ====================================================================== */ - -swig_directive : extend_directive { $$ = $1; } - | apply_directive { $$ = $1; } - | clear_directive { $$ = $1; } - | constant_directive { $$ = $1; } - | echo_directive { $$ = $1; } - | except_directive { $$ = $1; } - | fragment_directive { $$ = $1; } - | include_directive { $$ = $1; } - | inline_directive { $$ = $1; } - | insert_directive { $$ = $1; } - | module_directive { $$ = $1; } - | name_directive { $$ = $1; } - | native_directive { $$ = $1; } - | pragma_directive { $$ = $1; } - | rename_directive { $$ = $1; } - | feature_directive { $$ = $1; } - | varargs_directive { $$ = $1; } - | typemap_directive { $$ = $1; } - | types_directive { $$ = $1; } - | template_directive { $$ = $1; } - | warn_directive { $$ = $1; } - ; - -/* ------------------------------------------------------------ - %extend classname { ... } - ------------------------------------------------------------ */ - -extend_directive : EXTEND options classkeyopt idcolon LBRACE { - Node *cls; - String *clsname; - extendmode = 1; - cplus_mode = CPLUS_PUBLIC; - if (!classes) classes = NewHash(); - if (!classes_typedefs) classes_typedefs = NewHash(); - clsname = make_class_name($4); - cls = Getattr(classes,clsname); - if (!cls) { - cls = Getattr(classes_typedefs, clsname); - if (!cls) { - /* No previous definition. Create a new scope */ - Node *am = Getattr(Swig_extend_hash(),clsname); - if (!am) { - Swig_symbol_newscope(); - Swig_symbol_setscopename($4); - prev_symtab = 0; - } else { - prev_symtab = Swig_symbol_setscope(Getattr(am,"symtab")); - } - current_class = 0; - } else { - /* Previous typedef class definition. Use its symbol table. - Deprecated, just the real name should be used. - Note that %extend before the class typedef never worked, only %extend after the class typedef. */ - prev_symtab = Swig_symbol_setscope(Getattr(cls, "symtab")); - current_class = cls; - SWIG_WARN_NODE_BEGIN(cls); - Swig_warning(WARN_PARSE_EXTEND_NAME, cparse_file, cparse_line, "Deprecated %%extend name used - the %s name '%s' should be used instead of the typedef name '%s'.\n", Getattr(cls, "kind"), SwigType_namestr(Getattr(cls, "name")), $4); - SWIG_WARN_NODE_END(cls); - } - } else { - /* Previous class definition. Use its symbol table */ - prev_symtab = Swig_symbol_setscope(Getattr(cls,"symtab")); - current_class = cls; - } - Classprefix = NewString($4); - Namespaceprefix= Swig_symbol_qualifiedscopename(0); - Delete(clsname); - } cpp_members RBRACE { - String *clsname; - extendmode = 0; - $$ = new_node("extend"); - Setattr($$,"symtab",Swig_symbol_popscope()); - if (prev_symtab) { - Swig_symbol_setscope(prev_symtab); - } - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - clsname = make_class_name($4); - Setattr($$,"name",clsname); - - mark_nodes_as_extend($7); - if (current_class) { - /* We add the extension to the previously defined class */ - appendChild($$, $7); - appendChild(current_class,$$); - } else { - /* We store the extensions in the extensions hash */ - Node *am = Getattr(Swig_extend_hash(),clsname); - if (am) { - /* Append the members to the previous extend methods */ - appendChild(am, $7); - } else { - appendChild($$, $7); - Setattr(Swig_extend_hash(),clsname,$$); - } - } - current_class = 0; - Delete(Classprefix); - Delete(clsname); - Classprefix = 0; - prev_symtab = 0; - $$ = 0; - - } - ; - -/* ------------------------------------------------------------ - %apply - ------------------------------------------------------------ */ - -apply_directive : APPLY typemap_parm LBRACE tm_list RBRACE { - $$ = new_node("apply"); - Setattr($$,"pattern",Getattr($2,"pattern")); - appendChild($$,$4); - }; - -/* ------------------------------------------------------------ - %clear - ------------------------------------------------------------ */ - -clear_directive : CLEAR tm_list SEMI { - $$ = new_node("clear"); - appendChild($$,$2); - } - ; - -/* ------------------------------------------------------------ - %constant name = value; - %constant type name = value; - - Note: Source/Preprocessor/cpp.c injects `%constant X = Y;` for - each `#define X Y` so that's handled here too. - ------------------------------------------------------------ */ - -constant_directive : CONSTANT identifier EQUAL definetype SEMI { - if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) { - SwigType *type = NewSwigType($4.type); - $$ = new_node("constant"); - Setattr($$,"name",$2); - Setattr($$,"type",type); - Setattr($$,"value",$4.val); - if ($4.rawval) Setattr($$,"rawval", $4.rawval); - Setattr($$,"storage","%constant"); - SetFlag($$,"feature:immutable"); - add_symbols($$); - Delete(type); - } else { - if ($4.type == T_ERROR) { - Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value (ignored)\n"); - } - $$ = 0; - } - - } - | CONSTANT type declarator def_args SEMI { - if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) { - SwigType_push($2,$3.type); - /* Sneaky callback function trick */ - if (SwigType_isfunction($2)) { - SwigType_add_pointer($2); - } - $$ = new_node("constant"); - Setattr($$,"name",$3.id); - Setattr($$,"type",$2); - Setattr($$,"value",$4.val); - if ($4.rawval) Setattr($$,"rawval", $4.rawval); - Setattr($$,"storage","%constant"); - SetFlag($$,"feature:immutable"); - add_symbols($$); - } else { - if ($4.type == T_ERROR) { - Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line, "Unsupported constant value\n"); - } - $$ = 0; - } - } - /* Member function pointers with qualifiers. eg. - %constant short (Funcs::*pmf)(bool) const = &Funcs::F; */ - | CONSTANT type direct_declarator LPAREN parms RPAREN cv_ref_qualifier def_args SEMI { - if (($8.type != T_ERROR) && ($8.type != T_SYMBOL)) { - SwigType_add_function($2, $5); - SwigType_push($2, $7.qualifier); - SwigType_push($2, $3.type); - /* Sneaky callback function trick */ - if (SwigType_isfunction($2)) { - SwigType_add_pointer($2); - } - $$ = new_node("constant"); - Setattr($$, "name", $3.id); - Setattr($$, "type", $2); - Setattr($$, "value", $8.val); - if ($8.rawval) Setattr($$, "rawval", $8.rawval); - Setattr($$, "storage", "%constant"); - SetFlag($$, "feature:immutable"); - add_symbols($$); - } else { - if ($8.type == T_ERROR) { - Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line, "Unsupported constant value\n"); - } - $$ = 0; - } - } - | CONSTANT error SEMI { - Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n"); - $$ = 0; - } - | CONSTANT error END { - Swig_error(cparse_file,cparse_line,"Missing semicolon (';') after %%constant.\n"); - Exit(EXIT_FAILURE); - } - ; - -/* ------------------------------------------------------------ - %echo "text" - %echo %{ ... %} - ------------------------------------------------------------ */ - -echo_directive : ECHO HBLOCK { - char temp[64]; - Replace($2,"$file",cparse_file, DOH_REPLACE_ANY); - sprintf(temp,"%d", cparse_line); - Replace($2,"$line",temp,DOH_REPLACE_ANY); - Printf(stderr,"%s\n", $2); - Delete($2); - $$ = 0; - } - | ECHO string { - char temp[64]; - String *s = $2; - Replace(s,"$file",cparse_file, DOH_REPLACE_ANY); - sprintf(temp,"%d", cparse_line); - Replace(s,"$line",temp,DOH_REPLACE_ANY); - Printf(stderr,"%s\n", s); - Delete(s); - $$ = 0; - } - ; - -/* ------------------------------------------------------------ - %except(lang) { ... } - %except { ... } - %except(lang); - %except; - ------------------------------------------------------------ */ - -except_directive : EXCEPT LPAREN identifier RPAREN LBRACE { - skip_balanced('{','}'); - $$ = 0; - Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); - } - - | EXCEPT LBRACE { - skip_balanced('{','}'); - $$ = 0; - Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); - } - - | EXCEPT LPAREN identifier RPAREN SEMI { - $$ = 0; - Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); - } - - | EXCEPT SEMI { - $$ = 0; - Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); - } - ; - -/* fragment keyword arguments */ -stringtype : string LBRACE parm RBRACE { - $$ = NewHash(); - Setattr($$,"value",$1); - Setattr($$,"type",Getattr($3,"type")); - } - ; - -fname : string { - $$ = NewHash(); - Setattr($$,"value",$1); - } - | stringtype { - $$ = $1; - } - ; - -/* ------------------------------------------------------------ - %fragment(name, section) %{ ... %} - %fragment("name" {type}, "section") %{ ... %} - %fragment("name", "section", fragment="fragment1", fragment="fragment2") %{ ... %} - Also as above but using { ... } - %fragment("name"); - ------------------------------------------------------------ */ - -fragment_directive: FRAGMENT LPAREN fname COMMA kwargs RPAREN HBLOCK { - Hash *p = $5; - $$ = new_node("fragment"); - Setattr($$,"value",Getattr($3,"value")); - Setattr($$,"type",Getattr($3,"type")); - Setattr($$,"section",Getattr(p,"name")); - Setattr($$,"kwargs",nextSibling(p)); - Setattr($$,"code",$7); - } - | FRAGMENT LPAREN fname COMMA kwargs RPAREN LBRACE { - Hash *p = $5; - String *code; - skip_balanced('{','}'); - $$ = new_node("fragment"); - Setattr($$,"value",Getattr($3,"value")); - Setattr($$,"type",Getattr($3,"type")); - Setattr($$,"section",Getattr(p,"name")); - Setattr($$,"kwargs",nextSibling(p)); - Delitem(scanner_ccode,0); - Delitem(scanner_ccode,DOH_END); - code = Copy(scanner_ccode); - Setattr($$,"code",code); - Delete(code); - } - | FRAGMENT LPAREN fname RPAREN SEMI { - $$ = new_node("fragment"); - Setattr($$,"value",Getattr($3,"value")); - Setattr($$,"type",Getattr($3,"type")); - Setattr($$,"emitonly","1"); - } - ; - -/* ------------------------------------------------------------ - %includefile(option1="xyz", ...) "filename" [ declarations ] - %importfile(option1="xyz", ...) "filename" [ declarations ] - ------------------------------------------------------------ */ - -include_directive: includetype options string BEGINFILE { - $1.filename = Copy(cparse_file); - $1.line = cparse_line; - scanner_set_location($3,1); - if ($2) { - String *maininput = Getattr($2, "maininput"); - if (maininput) - scanner_set_main_input_file(NewString(maininput)); - } - } interface ENDOFFILE { - String *mname = 0; - $$ = $6; - scanner_set_location($1.filename,$1.line+1); - if (strcmp($1.type,"include") == 0) set_nodeType($$,"include"); - if (strcmp($1.type,"import") == 0) { - mname = $2 ? Getattr($2,"module") : 0; - set_nodeType($$,"import"); - if (import_mode) --import_mode; - } - - Setattr($$,"name",$3); - /* Search for the module (if any) */ - { - Node *n = firstChild($$); - while (n) { - if (Strcmp(nodeType(n),"module") == 0) { - if (mname) { - Setattr(n,"name", mname); - mname = 0; - } - Setattr($$,"module",Getattr(n,"name")); - break; - } - n = nextSibling(n); - } - if (mname) { - /* There is no module node in the import - node, ie, you imported a .h file - directly. We are forced then to create - a new import node with a module node. - */ - Node *nint = new_node("import"); - Node *mnode = new_node("module"); - Setattr(mnode,"name", mname); - Setattr(mnode,"options",$2); - appendChild(nint,mnode); - Delete(mnode); - appendChild(nint,firstChild($$)); - $$ = nint; - Setattr($$,"module",mname); - } - } - Setattr($$,"options",$2); - } - ; - -includetype : INCLUDE { $$.type = "include"; } - | IMPORT { $$.type = "import"; ++import_mode;} - ; - -/* ------------------------------------------------------------ - %inline %{ ... %} - ------------------------------------------------------------ */ - -inline_directive : INLINE HBLOCK { - String *cpps; - if (Namespaceprefix) { - Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n"); - $$ = 0; - } else { - $$ = new_node("insert"); - Setattr($$,"code",$2); - /* Need to run through the preprocessor */ - Seek($2,0,SEEK_SET); - Setline($2,cparse_start_line); - Setfile($2,cparse_file); - cpps = Preprocessor_parse($2); - start_inline(Char(cpps), cparse_start_line); - Delete($2); - Delete(cpps); - } - - } - | INLINE LBRACE { - String *cpps; - int start_line = cparse_line; - skip_balanced('{','}'); - if (Namespaceprefix) { - Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n"); - - $$ = 0; - } else { - String *code; - $$ = new_node("insert"); - Delitem(scanner_ccode,0); - Delitem(scanner_ccode,DOH_END); - code = Copy(scanner_ccode); - Setattr($$,"code", code); - Delete(code); - cpps=Copy(scanner_ccode); - start_inline(Char(cpps), start_line); - Delete(cpps); - } - } - ; - -/* ------------------------------------------------------------ - %{ ... %} - %insert(section) "filename" - %insert("section") "filename" - %insert(section) %{ ... %} - %insert("section") %{ ... %} - ------------------------------------------------------------ */ - -insert_directive : HBLOCK { - $$ = new_node("insert"); - Setattr($$,"code",$1); - } - | INSERT LPAREN idstring RPAREN string { - String *code = NewStringEmpty(); - $$ = new_node("insert"); - Setattr($$,"section",$3); - Setattr($$,"code",code); - if (Swig_insert_file($5,code) < 0) { - Swig_error(cparse_file, cparse_line, "Couldn't find '%s'.\n", $5); - $$ = 0; - } - } - | INSERT LPAREN idstring RPAREN HBLOCK { - $$ = new_node("insert"); - Setattr($$,"section",$3); - Setattr($$,"code",$5); - } - | INSERT LPAREN idstring RPAREN LBRACE { - String *code; - skip_balanced('{','}'); - $$ = new_node("insert"); - Setattr($$,"section",$3); - Delitem(scanner_ccode,0); - Delitem(scanner_ccode,DOH_END); - code = Copy(scanner_ccode); - Setattr($$,"code", code); - Delete(code); - } - ; - -/* ------------------------------------------------------------ - %module modname - %module "modname" - ------------------------------------------------------------ */ - -module_directive: MODULE options idstring { - $$ = new_node("module"); - if ($2) { - Setattr($$,"options",$2); - if (Getattr($2,"directors")) { - Wrapper_director_mode_set(1); - if (!cparse_cplusplus) { - Swig_error(cparse_file, cparse_line, "Directors are not supported for C code and require the -c++ option\n"); - } - } - if (Getattr($2,"dirprot")) { - Wrapper_director_protected_mode_set(1); - } - if (Getattr($2,"allprotected")) { - Wrapper_all_protected_mode_set(1); - } - if (Getattr($2,"templatereduce")) { - template_reduce = 1; - } - if (Getattr($2,"notemplatereduce")) { - template_reduce = 0; - } - } - if (!ModuleName) ModuleName = NewString($3); - if (!import_mode) { - /* first module included, we apply global - ModuleName, which can be modify by -module */ - String *mname = Copy(ModuleName); - Setattr($$,"name",mname); - Delete(mname); - } else { - /* import mode, we just pass the idstring */ - Setattr($$,"name",$3); - } - if (!module_node) module_node = $$; - } - ; - -/* ------------------------------------------------------------ - %name(newname) declaration - %name("newname") declaration - ------------------------------------------------------------ */ - -name_directive : NAME LPAREN idstring RPAREN { - Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n"); - Delete(yyrename); - yyrename = NewString($3); - $$ = 0; - } - | NAME LPAREN RPAREN { - Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated. Use %%rename instead.\n"); - $$ = 0; - Swig_error(cparse_file,cparse_line,"Missing argument to %%name directive.\n"); - } - ; - - -/* ------------------------------------------------------------ - %native(scriptname) name; - %native(scriptname) type name (parms); - ------------------------------------------------------------ */ - -native_directive : NATIVE LPAREN identifier RPAREN storage_class identifier SEMI { - $$ = new_node("native"); - Setattr($$,"name",$3); - Setattr($$,"wrap:name",$6); - add_symbols($$); - } - | NATIVE LPAREN identifier RPAREN storage_class type declarator SEMI { - if (!SwigType_isfunction($7.type)) { - Swig_error(cparse_file,cparse_line,"%%native declaration '%s' is not a function.\n", $7.id); - $$ = 0; - } else { - Delete(SwigType_pop_function($7.type)); - /* Need check for function here */ - SwigType_push($6,$7.type); - $$ = new_node("native"); - Setattr($$,"name",$3); - Setattr($$,"wrap:name",$7.id); - Setattr($$,"type",$6); - Setattr($$,"parms",$7.parms); - Setattr($$,"decl",$7.type); - } - add_symbols($$); - } - ; - -/* ------------------------------------------------------------ - %pragma(lang) name=value - %pragma(lang) name - %pragma name = value - %pragma name - ------------------------------------------------------------ */ - -pragma_directive : PRAGMA pragma_lang identifier EQUAL pragma_arg { - $$ = new_node("pragma"); - Setattr($$,"lang",$2); - Setattr($$,"name",$3); - Setattr($$,"value",$5); - } - | PRAGMA pragma_lang identifier { - $$ = new_node("pragma"); - Setattr($$,"lang",$2); - Setattr($$,"name",$3); - } - ; - -pragma_arg : string { $$ = $1; } - | HBLOCK { $$ = $1; } - ; - -pragma_lang : LPAREN identifier RPAREN { $$ = $2; } - | empty { $$ = (char *) "swig"; } - ; - -/* ------------------------------------------------------------ - %rename(newname) identifier; - ------------------------------------------------------------ */ - -rename_directive : rename_namewarn declarator idstring SEMI { - SwigType *t = $2.type; - Hash *kws = NewHash(); - String *fixname; - fixname = feature_identifier_fix($2.id); - Setattr(kws,"name",$3); - if (!Len(t)) t = 0; - /* Special declarator check */ - if (t) { - if (SwigType_isfunction(t)) { - SwigType *decl = SwigType_pop_function(t); - if (SwigType_ispointer(t)) { - String *nname = NewStringf("*%s",fixname); - if ($1) { - Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$2.parms); - } else { - Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws); - } - Delete(nname); - } else { - if ($1) { - Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$2.parms); - } else { - Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws); - } - } - Delete(decl); - } else if (SwigType_ispointer(t)) { - String *nname = NewStringf("*%s",fixname); - if ($1) { - Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$2.parms); - } else { - Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws); - } - Delete(nname); - } - } else { - if ($1) { - Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$2.parms); - } else { - Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws); - } - } - $$ = 0; - scanner_clear_rename(); - } - | rename_namewarn LPAREN kwargs RPAREN declarator cpp_const SEMI { - String *fixname; - Hash *kws = $3; - SwigType *t = $5.type; - fixname = feature_identifier_fix($5.id); - if (!Len(t)) t = 0; - /* Special declarator check */ - if (t) { - if ($6.qualifier) SwigType_push(t,$6.qualifier); - if (SwigType_isfunction(t)) { - SwigType *decl = SwigType_pop_function(t); - if (SwigType_ispointer(t)) { - String *nname = NewStringf("*%s",fixname); - if ($1) { - Swig_name_rename_add(Namespaceprefix, nname,decl,kws,$5.parms); - } else { - Swig_name_namewarn_add(Namespaceprefix,nname,decl,kws); - } - Delete(nname); - } else { - if ($1) { - Swig_name_rename_add(Namespaceprefix,(fixname),decl,kws,$5.parms); - } else { - Swig_name_namewarn_add(Namespaceprefix,(fixname),decl,kws); - } - } - Delete(decl); - } else if (SwigType_ispointer(t)) { - String *nname = NewStringf("*%s",fixname); - if ($1) { - Swig_name_rename_add(Namespaceprefix,(nname),0,kws,$5.parms); - } else { - Swig_name_namewarn_add(Namespaceprefix,(nname),0,kws); - } - Delete(nname); - } - } else { - if ($1) { - Swig_name_rename_add(Namespaceprefix,(fixname),0,kws,$5.parms); - } else { - Swig_name_namewarn_add(Namespaceprefix,(fixname),0,kws); - } - } - $$ = 0; - scanner_clear_rename(); - } - | rename_namewarn LPAREN kwargs RPAREN string SEMI { - if ($1) { - Swig_name_rename_add(Namespaceprefix,$5,0,$3,0); - } else { - Swig_name_namewarn_add(Namespaceprefix,$5,0,$3); - } - $$ = 0; - scanner_clear_rename(); - } - ; - -rename_namewarn : RENAME { - $$ = 1; - } - | NAMEWARN { - $$ = 0; - }; - - -/* ------------------------------------------------------------ - Feature targeting a symbol name (non-global feature): - - %feature(featurename) name "val"; - %feature(featurename, val) name; - - where "val" could instead be the other bracket types, that is, - { val } or %{ val %} or indeed omitted whereupon it defaults to "1". - Or, the global feature which does not target a symbol name: - - %feature(featurename) "val"; - %feature(featurename, val); - - An empty val (empty string) clears the feature. - Any number of feature attributes can optionally be added, for example - a non-global feature with 2 attributes: - - %feature(featurename, attrib1="attribval1", attrib2="attribval2") name "val"; - %feature(featurename, val, attrib1="attribval1", attrib2="attribval2") name; - ------------------------------------------------------------ */ - - /* Non-global feature */ -feature_directive : FEATURE LPAREN idstring RPAREN declarator cpp_const stringbracesemi { - String *val = $7 ? NewString($7) : NewString("1"); - new_feature($3, val, 0, $5.id, $5.type, $5.parms, $6.qualifier); - $$ = 0; - scanner_clear_rename(); - } - | FEATURE LPAREN idstring COMMA stringnum RPAREN declarator cpp_const SEMI { - String *val = Len($5) ? $5 : 0; - new_feature($3, val, 0, $7.id, $7.type, $7.parms, $8.qualifier); - $$ = 0; - scanner_clear_rename(); - } - | FEATURE LPAREN idstring featattr RPAREN declarator cpp_const stringbracesemi { - String *val = $8 ? NewString($8) : NewString("1"); - new_feature($3, val, $4, $6.id, $6.type, $6.parms, $7.qualifier); - $$ = 0; - scanner_clear_rename(); - } - | FEATURE LPAREN idstring COMMA stringnum featattr RPAREN declarator cpp_const SEMI { - String *val = Len($5) ? $5 : 0; - new_feature($3, val, $6, $8.id, $8.type, $8.parms, $9.qualifier); - $$ = 0; - scanner_clear_rename(); - } - - /* Global feature */ - | FEATURE LPAREN idstring RPAREN stringbracesemi { - String *val = $5 ? NewString($5) : NewString("1"); - new_feature($3, val, 0, 0, 0, 0, 0); - $$ = 0; - scanner_clear_rename(); - } - | FEATURE LPAREN idstring COMMA stringnum RPAREN SEMI { - String *val = Len($5) ? $5 : 0; - new_feature($3, val, 0, 0, 0, 0, 0); - $$ = 0; - scanner_clear_rename(); - } - | FEATURE LPAREN idstring featattr RPAREN stringbracesemi { - String *val = $6 ? NewString($6) : NewString("1"); - new_feature($3, val, $4, 0, 0, 0, 0); - $$ = 0; - scanner_clear_rename(); - } - | FEATURE LPAREN idstring COMMA stringnum featattr RPAREN SEMI { - String *val = Len($5) ? $5 : 0; - new_feature($3, val, $6, 0, 0, 0, 0); - $$ = 0; - scanner_clear_rename(); - } - ; - -stringbracesemi : stringbrace { $$ = $1; } - | SEMI { $$ = 0; } - | PARMS LPAREN parms RPAREN SEMI { $$ = $3; } - ; - -featattr : COMMA idstring EQUAL stringnum { - $$ = NewHash(); - Setattr($$,"name",$2); - Setattr($$,"value",$4); - } - | COMMA idstring EQUAL stringnum featattr { - $$ = NewHash(); - Setattr($$,"name",$2); - Setattr($$,"value",$4); - set_nextSibling($$,$5); - } - ; - -/* %varargs() directive. */ - -varargs_directive : VARARGS LPAREN varargs_parms RPAREN declarator cpp_const SEMI { - Parm *val; - String *name; - SwigType *t; - if (Namespaceprefix) name = NewStringf("%s::%s", Namespaceprefix, $5.id); - else name = NewString($5.id); - val = $3; - if ($5.parms) { - Setmeta(val,"parms",$5.parms); - } - t = $5.type; - if (!Len(t)) t = 0; - if (t) { - if ($6.qualifier) SwigType_push(t,$6.qualifier); - if (SwigType_isfunction(t)) { - SwigType *decl = SwigType_pop_function(t); - if (SwigType_ispointer(t)) { - String *nname = NewStringf("*%s",name); - Swig_feature_set(Swig_cparse_features(), nname, decl, "feature:varargs", val, 0); - Delete(nname); - } else { - Swig_feature_set(Swig_cparse_features(), name, decl, "feature:varargs", val, 0); - } - Delete(decl); - } else if (SwigType_ispointer(t)) { - String *nname = NewStringf("*%s",name); - Swig_feature_set(Swig_cparse_features(),nname,0,"feature:varargs",val, 0); - Delete(nname); - } - } else { - Swig_feature_set(Swig_cparse_features(),name,0,"feature:varargs",val, 0); - } - Delete(name); - $$ = 0; - }; - -varargs_parms : parms { $$ = $1; } - | NUM_INT COMMA parm { - int i; - int n; - Parm *p; - n = atoi(Char($1.val)); - if (n <= 0) { - Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n"); - $$ = 0; - } else { - String *name = Getattr($3, "name"); - $$ = Copy($3); - if (name) - Setattr($$, "name", NewStringf("%s%d", name, n)); - for (i = 1; i < n; i++) { - p = Copy($3); - name = Getattr(p, "name"); - if (name) - Setattr(p, "name", NewStringf("%s%d", name, n-i)); - set_nextSibling(p,$$); - Delete($$); - $$ = p; - } - } - } - ; - - -/* ------------------------------------------------------------ - %typemap(method) type { ... } - %typemap(method) type "..." - %typemap(method) type; - typemap deletion - %typemap(method) type1,type2,... = type; - typemap copy - %typemap type1,type2,... = type; - typemap copy - ------------------------------------------------------------ */ - -typemap_directive : TYPEMAP LPAREN typemap_type RPAREN tm_list stringbrace { - $$ = 0; - if ($3.method) { - String *code = 0; - $$ = new_node("typemap"); - Setattr($$,"method",$3.method); - if ($3.kwargs) { - ParmList *kw = $3.kwargs; - code = remove_block(kw, $6); - Setattr($$,"kwargs", $3.kwargs); - } - code = code ? code : NewString($6); - Setattr($$,"code", code); - Delete(code); - appendChild($$,$5); - } - } - | TYPEMAP LPAREN typemap_type RPAREN tm_list SEMI { - $$ = 0; - if ($3.method) { - $$ = new_node("typemap"); - Setattr($$,"method",$3.method); - appendChild($$,$5); - } - } - | TYPEMAP LPAREN typemap_type RPAREN tm_list EQUAL typemap_parm SEMI { - $$ = 0; - if ($3.method) { - $$ = new_node("typemapcopy"); - Setattr($$,"method",$3.method); - Setattr($$,"pattern", Getattr($7,"pattern")); - appendChild($$,$5); - } - } - ; - -/* typemap method type (lang,method) or (method) */ - -typemap_type : kwargs { - String *name = Getattr($1, "name"); - Hash *p = nextSibling($1); - $$.method = name; - $$.kwargs = p; - if (Getattr($1, "value")) { - Swig_error(cparse_file, cparse_line, - "%%typemap method shouldn't have a value specified.\n"); - } - while (p) { - if (!Getattr(p, "value")) { - Swig_error(cparse_file, cparse_line, - "%%typemap attribute '%s' is missing its value. If this is specifying the target language, that's no longer supported: use #ifdef SWIG<LANG> instead.\n", - Getattr(p, "name")); - /* Set to empty value to avoid segfaults later. */ - Setattr(p, "value", NewStringEmpty()); - } - p = nextSibling(p); - } - } - ; - -tm_list : typemap_parm tm_tail { - $$ = $1; - set_nextSibling($$,$2); - } - ; - -tm_tail : COMMA typemap_parm tm_tail { - $$ = $2; - set_nextSibling($$,$3); - } - | empty { $$ = 0;} - ; - -typemap_parm : type plain_declarator { - Parm *parm; - SwigType_push($1,$2.type); - $$ = new_node("typemapitem"); - parm = NewParmWithoutFileLineInfo($1,$2.id); - Setattr($$,"pattern",parm); - Setattr($$,"parms", $2.parms); - Delete(parm); - /* $$ = NewParmWithoutFileLineInfo($1,$2.id); - Setattr($$,"parms",$2.parms); */ - } - | LPAREN parms RPAREN { - $$ = new_node("typemapitem"); - Setattr($$,"pattern",$2); - /* Setattr($$,"multitype",$2); */ - } - | LPAREN parms RPAREN LPAREN parms RPAREN { - $$ = new_node("typemapitem"); - Setattr($$,"pattern", $2); - /* Setattr($$,"multitype",$2); */ - Setattr($$,"parms",$5); - } - ; - -/* ------------------------------------------------------------ - %types(parmlist); - %types(parmlist) %{ ... %} - ------------------------------------------------------------ */ - -types_directive : TYPES LPAREN parms RPAREN stringbracesemi { - $$ = new_node("types"); - Setattr($$,"parms",$3); - if ($5) - Setattr($$,"convcode",NewString($5)); - } - ; - -/* ------------------------------------------------------------ - %template(name) tname<args>; - ------------------------------------------------------------ */ - -template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI { - Parm *p, *tp; - Node *n; - Node *outer_class = currentOuterClass; - Symtab *tscope = 0; - int specialized = 0; - int variadic = 0; - - $$ = 0; - - tscope = Swig_symbol_current(); /* Get the current scope */ - - /* If the class name is qualified, we need to create or lookup namespace entries */ - $5 = resolve_create_node_scope($5, 0); - - if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0) { - outer_class = nscope_inner; - } - - /* - We use the new namespace entry 'nscope' only to - emit the template node. The template parameters are - resolved in the current 'tscope'. - - This is closer to the C++ (typedef) behavior. - */ - n = Swig_cparse_template_locate($5,$7,tscope); - - /* Patch the argument types to respect namespaces */ - p = $7; - while (p) { - SwigType *value = Getattr(p,"value"); - if (!value) { - SwigType *ty = Getattr(p,"type"); - if (ty) { - SwigType *rty = 0; - int reduce = template_reduce; - if (reduce || !SwigType_ispointer(ty)) { - rty = Swig_symbol_typedef_reduce(ty,tscope); - if (!reduce) reduce = SwigType_ispointer(rty); - } - ty = reduce ? Swig_symbol_type_qualify(rty,tscope) : Swig_symbol_type_qualify(ty,tscope); - Setattr(p,"type",ty); - Delete(ty); - Delete(rty); - } - } else { - value = Swig_symbol_type_qualify(value,tscope); - Setattr(p,"value",value); - Delete(value); - } - - p = nextSibling(p); - } - - /* Look for the template */ - { - Node *nn = n; - Node *linklistend = 0; - Node *linkliststart = 0; - while (nn) { - Node *templnode = 0; - if (Strcmp(nodeType(nn),"template") == 0) { - int nnisclass = (Strcmp(Getattr(nn,"templatetype"),"class") == 0); /* if not a templated class it is a templated function */ - Parm *tparms = Getattr(nn,"templateparms"); - if (!tparms) { - specialized = 1; - } else if (Getattr(tparms,"variadic") && strncmp(Char(Getattr(tparms,"variadic")), "1", 1)==0) { - variadic = 1; - } - if (nnisclass && !variadic && !specialized && (ParmList_len($7) > ParmList_len(tparms))) { - Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms)); - } else if (nnisclass && !specialized && ((ParmList_len($7) < (ParmList_numrequired(tparms) - (variadic?1:0))))) { /* Variadic parameter is optional */ - Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", (ParmList_numrequired(tparms)-(variadic?1:0)) ); - } else if (!nnisclass && ((ParmList_len($7) != ParmList_len(tparms)))) { - /* must be an overloaded templated method - ignore it as it is overloaded with a different number of template parameters */ - nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions */ - continue; - } else { - String *tname = Copy($5); - int def_supplied = 0; - /* Expand the template */ - Node *templ = Swig_symbol_clookup($5,0); - Parm *targs = templ ? Getattr(templ,"templateparms") : 0; - - ParmList *temparms; - if (specialized) temparms = CopyParmList($7); - else temparms = CopyParmList(tparms); - - /* Create typedef's and arguments */ - p = $7; - tp = temparms; - if (!p && ParmList_len(p) != ParmList_len(temparms)) { - /* we have no template parameters supplied in %template for a template that has default args*/ - p = tp; - def_supplied = 1; - } - - while (p) { - String *value = Getattr(p,"value"); - if (def_supplied) { - Setattr(p,"default","1"); - } - if (value) { - Setattr(tp,"value",value); - } else { - SwigType *ty = Getattr(p,"type"); - if (ty) { - Setattr(tp,"type",ty); - } - Delattr(tp,"value"); - } - /* fix default arg values */ - if (targs) { - Parm *pi = temparms; - Parm *ti = targs; - String *tv = Getattr(tp,"value"); - if (!tv) tv = Getattr(tp,"type"); - while(pi != tp && ti && pi) { - String *name = Getattr(ti,"name"); - String *value = Getattr(pi,"value"); - if (!value) value = Getattr(pi,"type"); - Replaceid(tv, name, value); - pi = nextSibling(pi); - ti = nextSibling(ti); - } - } - p = nextSibling(p); - tp = nextSibling(tp); - if (!p && tp) { - p = tp; - def_supplied = 1; - } else if (p && !tp) { /* Variadic template - tp < p */ - SWIG_WARN_NODE_BEGIN(nn); - Swig_warning(WARN_CPP11_VARIADIC_TEMPLATE,cparse_file, cparse_line,"Only the first variadic template argument is currently supported.\n"); - SWIG_WARN_NODE_END(nn); - break; - } - } - - templnode = copy_node(nn); - update_nested_classes(templnode); /* update classes nested within template */ - /* We need to set the node name based on name used to instantiate */ - Setattr(templnode,"name",tname); - Delete(tname); - if (!specialized) { - Delattr(templnode,"sym:typename"); - } else { - Setattr(templnode,"sym:typename","1"); - } - /* for now, nested %template is allowed only in the same scope as the template declaration */ - if ($3 && !(nnisclass && ((outer_class && (outer_class != Getattr(nn, "nested:outer"))) - ||(extendmode && current_class && (current_class != Getattr(nn, "nested:outer")))))) { - /* - Comment this out for 1.3.28. We need to - re-enable it later but first we need to - move %ignore from using %rename to use - %feature(ignore). - - String *symname = Swig_name_make(templnode,0,$3,0,0); - */ - String *symname = NewString($3); - Swig_cparse_template_expand(templnode,symname,temparms,tscope); - Setattr(templnode,"sym:name",symname); - } else { - static int cnt = 0; - String *nname = NewStringf("__dummy_%d__", cnt++); - Swig_cparse_template_expand(templnode,nname,temparms,tscope); - Setattr(templnode,"sym:name",nname); - SetFlag(templnode,"hidden"); - Delete(nname); - Setattr(templnode,"feature:onlychildren", "typemap,typemapitem,typemapcopy,typedef,types,fragment,apply"); - if ($3) { - Swig_warning(WARN_PARSE_NESTED_TEMPLATE, cparse_file, cparse_line, "Named nested template instantiations not supported. Processing as if no name was given to %%template().\n"); - } - } - Delattr(templnode,"templatetype"); - Setattr(templnode,"template",nn); - Setfile(templnode,cparse_file); - Setline(templnode,cparse_line); - Delete(temparms); - if (outer_class && nnisclass) { - SetFlag(templnode, "nested"); - Setattr(templnode, "nested:outer", outer_class); - } - add_symbols_copy(templnode); - - if (Strcmp(nodeType(templnode),"class") == 0) { - - /* Identify pure abstract methods */ - Setattr(templnode,"abstracts", pure_abstracts(firstChild(templnode))); - - /* Set up inheritance in symbol table */ - { - Symtab *csyms; - List *baselist = Getattr(templnode,"baselist"); - csyms = Swig_symbol_current(); - Swig_symbol_setscope(Getattr(templnode,"symtab")); - if (baselist) { - List *bases = Swig_make_inherit_list(Getattr(templnode,"name"),baselist, Namespaceprefix); - if (bases) { - Iterator s; - for (s = First(bases); s.item; s = Next(s)) { - Symtab *st = Getattr(s.item,"symtab"); - if (st) { - Setfile(st,Getfile(s.item)); - Setline(st,Getline(s.item)); - Swig_symbol_inherit(st); - } - } - Delete(bases); - } - } - Swig_symbol_setscope(csyms); - } - - /* Merge in %extend methods for this class. - This only merges methods within %extend for a template specialized class such as - template<typename T> class K {}; %extend K<int> { ... } - The copy_node() call above has already added in the generic %extend methods such as - template<typename T> class K {}; %extend K { ... } */ - - /* !!! This may be broken. We may have to add the - %extend methods at the beginning of the class */ - { - String *stmp = 0; - String *clsname; - Node *am; - if (Namespaceprefix) { - clsname = stmp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name")); - } else { - clsname = Getattr(templnode,"name"); - } - am = Getattr(Swig_extend_hash(),clsname); - if (am) { - Symtab *st = Swig_symbol_current(); - Swig_symbol_setscope(Getattr(templnode,"symtab")); - /* Printf(stdout,"%s: %s %p %p\n", Getattr(templnode,"name"), clsname, Swig_symbol_current(), Getattr(templnode,"symtab")); */ - Swig_extend_merge(templnode,am); - Swig_symbol_setscope(st); - Swig_extend_append_previous(templnode,am); - Delattr(Swig_extend_hash(),clsname); - } - if (stmp) Delete(stmp); - } - - /* Add to classes hash */ - if (!classes) - classes = NewHash(); - - if (Namespaceprefix) { - String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(templnode,"name")); - Setattr(classes,temp,templnode); - Delete(temp); - } else { - String *qs = Swig_symbol_qualifiedscopename(templnode); - Setattr(classes, qs,templnode); - Delete(qs); - } - } - } - - /* all the overloaded templated functions are added into a linked list */ - if (!linkliststart) - linkliststart = templnode; - if (nscope_inner) { - /* non-global namespace */ - if (templnode) { - appendChild(nscope_inner,templnode); - Delete(templnode); - if (nscope) $$ = nscope; - } - } else { - /* global namespace */ - if (!linklistend) { - $$ = templnode; - } else { - set_nextSibling(linklistend,templnode); - Delete(templnode); - } - linklistend = templnode; - } - } - nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions. If a templated class there will never be a sibling. */ - } - update_defaultargs(linkliststart); - update_abstracts(linkliststart); - } - Swig_symbol_setscope(tscope); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - } - ; - -/* ------------------------------------------------------------ - %warn "text" - %warn(no) - ------------------------------------------------------------ */ - -warn_directive : WARN string { - Swig_warning(0,cparse_file, cparse_line,"%s\n", $2); - $$ = 0; - } - ; - -/* ====================================================================== - * C Parsing - * ====================================================================== */ - -c_declaration : c_decl { - $$ = $1; - if ($$) { - add_symbols($$); - default_arguments($$); - } - } - | c_enum_decl { $$ = $1; } - | c_enum_forward_decl { $$ = $1; } - -/* An extern C type declaration, disable cparse_cplusplus if needed. */ - - | EXTERN string LBRACE { - if (Strcmp($2,"C") == 0) { - cparse_externc = 1; - } - } interface RBRACE { - cparse_externc = 0; - if (Strcmp($2,"C") == 0) { - Node *n = firstChild($5); - $$ = new_node("extern"); - Setattr($$,"name",$2); - appendChild($$,n); - while (n) { - String *s = Getattr(n, "storage"); - if (s) { - if (Strstr(s, "thread_local")) { - Insert(s,0,"externc "); - } else if (!Equal(s, "typedef")) { - Setattr(n,"storage","externc"); - } - } else { - Setattr(n,"storage","externc"); - } - n = nextSibling(n); - } - } else { - if (!Equal($2,"C++")) { - Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2); - } - $$ = new_node("extern"); - Setattr($$,"name",$2); - appendChild($$,firstChild($5)); - } - } - | cpp_lambda_decl { - $$ = $1; - SWIG_WARN_NODE_BEGIN($$); - Swig_warning(WARN_CPP11_LAMBDA, cparse_file, cparse_line, "Lambda expressions and closures are not fully supported yet.\n"); - SWIG_WARN_NODE_END($$); - } - | USING idcolon EQUAL type plain_declarator SEMI { - /* Convert using statement to a typedef statement */ - $$ = new_node("cdecl"); - Setattr($$,"type",$4); - Setattr($$,"storage","typedef"); - Setattr($$,"name",$2); - Setattr($$,"decl",$5.type); - SetFlag($$,"typealias"); - add_symbols($$); - } - | TEMPLATE LESSTHAN template_parms GREATERTHAN USING idcolon EQUAL type plain_declarator SEMI { - /* Convert alias template to a "template" typedef statement */ - $$ = new_node("template"); - Setattr($$,"type",$8); - Setattr($$,"storage","typedef"); - Setattr($$,"name",$6); - Setattr($$,"decl",$9.type); - Setattr($$,"templateparms",$3); - Setattr($$,"templatetype","cdecl"); - SetFlag($$,"aliastemplate"); - add_symbols($$); - } - | cpp_static_assert { - $$ = $1; - } - ; - -/* ------------------------------------------------------------ - A C global declaration of some kind (may be variable, function, typedef, etc.) - ------------------------------------------------------------ */ - -c_decl : storage_class type declarator cpp_const initializer c_decl_tail { - String *decl = $3.type; - $$ = new_node("cdecl"); - if ($4.qualifier) - decl = add_qualifier_to_declarator($3.type, $4.qualifier); - Setattr($$,"refqualifier",$4.refqualifier); - Setattr($$,"type",$2); - Setattr($$,"storage",$1); - Setattr($$,"name",$3.id); - Setattr($$,"decl",decl); - Setattr($$,"parms",$3.parms); - Setattr($$,"value",$5.val); - Setattr($$,"throws",$4.throws); - Setattr($$,"throw",$4.throwf); - Setattr($$,"noexcept",$4.nexcept); - Setattr($$,"final",$4.final); - if ($5.val && $5.type) { - /* store initializer type as it might be different to the declared type */ - SwigType *valuetype = NewSwigType($5.type); - if (Len(valuetype) > 0) - Setattr($$,"valuetype",valuetype); - else - Delete(valuetype); - } - if (!$6) { - if (Len(scanner_ccode)) { - String *code = Copy(scanner_ccode); - Setattr($$,"code",code); - Delete(code); - } - } else { - Node *n = $6; - /* Inherit attributes */ - while (n) { - String *type = Copy($2); - Setattr(n,"type",type); - Setattr(n,"storage",$1); - n = nextSibling(n); - Delete(type); - } - } - if ($5.bitfield) { - Setattr($$,"bitfield", $5.bitfield); - } - - if ($3.id) { - /* Look for "::" declarations (ignored) */ - if (Strstr($3.id, "::")) { - /* This is a special case. If the scope name of the declaration exactly - matches that of the declaration, then we will allow it. Otherwise, delete. */ - String *p = Swig_scopename_prefix($3.id); - if (p) { - if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) || - (Classprefix && Strcmp(p, Classprefix) == 0)) { - String *lstr = Swig_scopename_last($3.id); - Setattr($$, "name", lstr); - Delete(lstr); - set_nextSibling($$, $6); - } else { - Delete($$); - $$ = $6; - } - Delete(p); - } else { - Delete($$); - $$ = $6; - } - } else { - set_nextSibling($$, $6); - } - } else { - Swig_error(cparse_file, cparse_line, "Missing symbol name for global declaration\n"); - $$ = 0; - } - - if ($4.qualifier && $1 && Strstr($1, "static")) - Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$)); - } - /* Alternate function syntax introduced in C++11: - auto funcName(int x, int y) -> int; */ - | storage_class AUTO declarator cpp_const ARROW cpp_alternate_rettype virt_specifier_seq_opt initializer c_decl_tail { - $$ = new_node("cdecl"); - if ($4.qualifier) SwigType_push($3.type, $4.qualifier); - Setattr($$,"refqualifier",$4.refqualifier); - Setattr($$,"type",$6); - Setattr($$,"storage",$1); - Setattr($$,"name",$3.id); - Setattr($$,"decl",$3.type); - Setattr($$,"parms",$3.parms); - Setattr($$,"value",$4.val); - Setattr($$,"throws",$4.throws); - Setattr($$,"throw",$4.throwf); - Setattr($$,"noexcept",$4.nexcept); - Setattr($$,"final",$4.final); - if (!$9) { - if (Len(scanner_ccode)) { - String *code = Copy(scanner_ccode); - Setattr($$,"code",code); - Delete(code); - } - } else { - Node *n = $9; - while (n) { - String *type = Copy($6); - Setattr(n,"type",type); - Setattr(n,"storage",$1); - n = nextSibling(n); - Delete(type); - } - } - if ($4.bitfield) { - Setattr($$,"bitfield", $4.bitfield); - } - - if (Strstr($3.id,"::")) { - String *p = Swig_scopename_prefix($3.id); - if (p) { - if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) || - (Classprefix && Strcmp(p, Classprefix) == 0)) { - String *lstr = Swig_scopename_last($3.id); - Setattr($$,"name",lstr); - Delete(lstr); - set_nextSibling($$, $9); - } else { - Delete($$); - $$ = $9; - } - Delete(p); - } else { - Delete($$); - $$ = $9; - } - } else { - set_nextSibling($$, $9); - } - - if ($4.qualifier && $1 && Strstr($1, "static")) - Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$)); - } - ; - -/* Allow lists of variables and functions to be built up */ - -c_decl_tail : SEMI { - $$ = 0; - Clear(scanner_ccode); - } - | COMMA declarator cpp_const initializer c_decl_tail { - $$ = new_node("cdecl"); - if ($3.qualifier) SwigType_push($2.type,$3.qualifier); - Setattr($$,"refqualifier",$3.refqualifier); - Setattr($$,"name",$2.id); - Setattr($$,"decl",$2.type); - Setattr($$,"parms",$2.parms); - Setattr($$,"value",$4.val); - Setattr($$,"throws",$3.throws); - Setattr($$,"throw",$3.throwf); - Setattr($$,"noexcept",$3.nexcept); - Setattr($$,"final",$3.final); - if ($4.bitfield) { - Setattr($$,"bitfield", $4.bitfield); - } - if (!$5) { - if (Len(scanner_ccode)) { - String *code = Copy(scanner_ccode); - Setattr($$,"code",code); - Delete(code); - } - } else { - set_nextSibling($$, $5); - } - } - | LBRACE { - skip_balanced('{','}'); - $$ = 0; - } - | error { - $$ = 0; - if (yychar == RPAREN) { - Swig_error(cparse_file, cparse_line, "Unexpected closing parenthesis (')').\n"); - } else { - Swig_error(cparse_file, cparse_line, "Syntax error - possibly a missing semicolon (';').\n"); - } - Exit(EXIT_FAILURE); - } - ; - -initializer : def_args { - $$ = $1; - } - ; - -cpp_alternate_rettype : primitive_type { $$ = $1; } - | TYPE_BOOL { $$ = $1; } - | TYPE_VOID { $$ = $1; } -/* - | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); } -*/ - | TYPE_RAW { $$ = $1; } - | idcolon { $$ = $1; } - | idcolon AND { - $$ = $1; - SwigType_add_reference($$); - } - | decltype { $$ = $1; } - ; - -/* ------------------------------------------------------------ - Lambda functions and expressions, such as: - auto myFunc = [] { return something; }; - auto myFunc = [](int x, int y) { return x+y; }; - auto myFunc = [](int x, int y) -> int { return x+y; }; - auto myFunc = [](int x, int y) throw() -> int { return x+y; }; - auto six = [](int x, int y) { return x+y; }(4, 2); - ------------------------------------------------------------ */ -cpp_lambda_decl : storage_class AUTO idcolon EQUAL lambda_introducer lambda_template LPAREN parms RPAREN cpp_const lambda_body lambda_tail { - $$ = new_node("lambda"); - Setattr($$,"name",$3); - add_symbols($$); - } - | storage_class AUTO idcolon EQUAL lambda_introducer lambda_template LPAREN parms RPAREN cpp_const ARROW type lambda_body lambda_tail { - $$ = new_node("lambda"); - Setattr($$,"name",$3); - add_symbols($$); - } - | storage_class AUTO idcolon EQUAL lambda_introducer lambda_template lambda_body lambda_tail { - $$ = new_node("lambda"); - Setattr($$,"name",$3); - add_symbols($$); - } - ; - -lambda_introducer : LBRACKET { - skip_balanced('[',']'); - $$ = 0; - } - ; - -lambda_template : LESSTHAN { - skip_balanced('<','>'); - $$ = 0; - } - | empty { $$ = 0; } - ; - -lambda_body : LBRACE { - skip_balanced('{','}'); - $$ = 0; - } - -lambda_tail : SEMI { - $$ = 0; - } - | LPAREN { - skip_balanced('(',')'); - } SEMI { - $$ = 0; - } - ; - -/* ------------------------------------------------------------ - enum - or - enum class - ------------------------------------------------------------ */ - -c_enum_key : ENUM { - $$ = (char *)"enum"; - } - | ENUM CLASS { - $$ = (char *)"enum class"; - } - | ENUM STRUCT { - $$ = (char *)"enum struct"; - } - ; - -/* ------------------------------------------------------------ - base enum type (eg. unsigned short) - ------------------------------------------------------------ */ - -c_enum_inherit : COLON type_right { - $$ = $2; - } - | empty { $$ = 0; } - ; -/* ------------------------------------------------------------ - enum [class] Name; - enum [class] Name [: base_type]; - ------------------------------------------------------------ */ - -c_enum_forward_decl : storage_class c_enum_key ename c_enum_inherit SEMI { - SwigType *ty = 0; - int scopedenum = $3 && !Equal($2, "enum"); - $$ = new_node("enumforward"); - ty = NewStringf("enum %s", $3); - Setattr($$,"enumkey",$2); - if (scopedenum) - SetFlag($$, "scopedenum"); - Setattr($$,"name",$3); - Setattr($$,"inherit",$4); - Setattr($$,"type",ty); - Setattr($$,"sym:weak", "1"); - add_symbols($$); - } - ; - -/* ------------------------------------------------------------ - enum [class] Name [: base_type] { ... }; - or - enum [class] Name [: base_type] { ... } MyEnum [= ...]; - * ------------------------------------------------------------ */ - -c_enum_decl : storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBRACE SEMI { - SwigType *ty = 0; - int scopedenum = $3 && !Equal($2, "enum"); - $$ = new_node("enum"); - ty = NewStringf("enum %s", $3); - Setattr($$,"enumkey",$2); - if (scopedenum) - SetFlag($$, "scopedenum"); - Setattr($$,"name",$3); - Setattr($$,"inherit",$4); - Setattr($$,"type",ty); - appendChild($$,$6); - add_symbols($$); /* Add to tag space */ - - if (scopedenum) { - Swig_symbol_newscope(); - Swig_symbol_setscopename($3); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - } - - add_symbols($6); /* Add enum values to appropriate enum or enum class scope */ - - if (scopedenum) { - Setattr($$,"symtab", Swig_symbol_popscope()); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - } - } - | storage_class c_enum_key ename c_enum_inherit LBRACE enumlist RBRACE declarator cpp_const initializer c_decl_tail { - Node *n; - SwigType *ty = 0; - String *unnamed = 0; - int unnamedinstance = 0; - int scopedenum = $3 && !Equal($2, "enum"); - - $$ = new_node("enum"); - Setattr($$,"enumkey",$2); - if (scopedenum) - SetFlag($$, "scopedenum"); - Setattr($$,"inherit",$4); - if ($3) { - Setattr($$,"name",$3); - ty = NewStringf("enum %s", $3); - } else if ($8.id) { - unnamed = make_unnamed(); - ty = NewStringf("enum %s", unnamed); - Setattr($$,"unnamed",unnamed); - /* name is not set for unnamed enum instances, e.g. enum { foo } Instance; */ - if ($1 && Cmp($1,"typedef") == 0) { - Setattr($$,"name",$8.id); - } else { - unnamedinstance = 1; - } - Setattr($$,"storage",$1); - } - if ($8.id && Cmp($1,"typedef") == 0) { - Setattr($$,"tdname",$8.id); - Setattr($$,"allows_typedef","1"); - } - appendChild($$,$6); - n = new_node("cdecl"); - Setattr(n,"type",ty); - Setattr(n,"name",$8.id); - Setattr(n,"storage",$1); - Setattr(n,"decl",$8.type); - Setattr(n,"parms",$8.parms); - Setattr(n,"unnamed",unnamed); - - if (unnamedinstance) { - SwigType *cty = NewString("enum "); - Setattr($$,"type",cty); - SetFlag($$,"unnamedinstance"); - SetFlag(n,"unnamedinstance"); - Delete(cty); - } - if ($11) { - Node *p = $11; - set_nextSibling(n,p); - while (p) { - SwigType *cty = Copy(ty); - Setattr(p,"type",cty); - Setattr(p,"unnamed",unnamed); - Setattr(p,"storage",$1); - Delete(cty); - p = nextSibling(p); - } - } else { - if (Len(scanner_ccode)) { - String *code = Copy(scanner_ccode); - Setattr(n,"code",code); - Delete(code); - } - } - - /* Ensure that typedef enum ABC {foo} XYZ; uses XYZ for sym:name, like structs. - * Note that class_rename/yyrename are bit of a mess so used this simple approach to change the name. */ - if ($8.id && $3 && Cmp($1,"typedef") == 0) { - String *name = NewString($8.id); - Setattr($$, "parser:makename", name); - Delete(name); - } - - add_symbols($$); /* Add enum to tag space */ - set_nextSibling($$,n); - Delete(n); - - if (scopedenum) { - Swig_symbol_newscope(); - Swig_symbol_setscopename($3); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - } - - add_symbols($6); /* Add enum values to appropriate enum or enum class scope */ - - if (scopedenum) { - Setattr($$,"symtab", Swig_symbol_popscope()); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - } - - add_symbols(n); - Delete(unnamed); - } - ; - -c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end { - /* This is a sick hack. If the ctor_end has parameters, - and the parms parameter only has 1 parameter, this - could be a declaration of the form: - - type (id)(parms) - - Otherwise it's an error. */ - int err = 0; - $$ = 0; - - if ((ParmList_len($4) == 1) && (!Swig_scopename_check($2))) { - SwigType *ty = Getattr($4,"type"); - String *name = Getattr($4,"name"); - err = 1; - if (!name) { - $$ = new_node("cdecl"); - Setattr($$,"type",$2); - Setattr($$,"storage",$1); - Setattr($$,"name",ty); - - if ($6.have_parms) { - SwigType *decl = NewStringEmpty(); - SwigType_add_function(decl,$6.parms); - Setattr($$,"decl",decl); - Setattr($$,"parms",$6.parms); - if (Len(scanner_ccode)) { - String *code = Copy(scanner_ccode); - Setattr($$,"code",code); - Delete(code); - } - } - if ($6.defarg) { - Setattr($$,"value",$6.defarg); - } - Setattr($$,"throws",$6.throws); - Setattr($$,"throw",$6.throwf); - Setattr($$,"noexcept",$6.nexcept); - Setattr($$,"final",$6.final); - err = 0; - } - } - if (err) { - Swig_error(cparse_file,cparse_line,"Syntax error in input(2).\n"); - Exit(EXIT_FAILURE); - } - } - ; - -/* ====================================================================== - * C++ Support - * ====================================================================== */ - -cpp_declaration : cpp_class_decl { $$ = $1; } - | cpp_forward_class_decl { $$ = $1; } - | cpp_template_decl { $$ = $1; } - | cpp_using_decl { $$ = $1; } - | cpp_namespace_decl { $$ = $1; } - | cpp_catch_decl { $$ = 0; } - ; - - -/* A simple class/struct/union definition */ - -/* Note that class_virt_specifier_opt for supporting final classes introduces one shift-reduce conflict - with C style variable declarations, such as: struct X final; */ - -cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit LBRACE { - String *prefix; - List *bases = 0; - Node *scope = 0; - String *code; - $<node>$ = new_node("class"); - Setline($<node>$,cparse_start_line); - Setattr($<node>$,"kind",$2); - if ($5) { - Setattr($<node>$,"baselist", Getattr($5,"public")); - Setattr($<node>$,"protectedbaselist", Getattr($5,"protected")); - Setattr($<node>$,"privatebaselist", Getattr($5,"private")); - } - Setattr($<node>$,"allows_typedef","1"); - - /* preserve the current scope */ - Setattr($<node>$,"prev_symtab",Swig_symbol_current()); - - /* If the class name is qualified. We need to create or lookup namespace/scope entries */ - scope = resolve_create_node_scope($3, 1); - /* save nscope_inner to the class - it may be overwritten in nested classes*/ - Setattr($<node>$, "nested:innerscope", nscope_inner); - Setattr($<node>$, "nested:nscope", nscope); - Setfile(scope,cparse_file); - Setline(scope,cparse_line); - $3 = scope; - Setattr($<node>$,"name",$3); - - if (currentOuterClass) { - SetFlag($<node>$, "nested"); - Setattr($<node>$, "nested:outer", currentOuterClass); - set_access_mode($<node>$); - } - Swig_features_get(Swig_cparse_features(), Namespaceprefix, Getattr($<node>$, "name"), 0, $<node>$); - /* save yyrename to the class attribute, to be used later in add_symbols()*/ - Setattr($<node>$, "class_rename", make_name($<node>$, $3, 0)); - Setattr($<node>$, "Classprefix", $3); - Classprefix = NewString($3); - /* Deal with inheritance */ - if ($5) - bases = Swig_make_inherit_list($3,Getattr($5,"public"),Namespaceprefix); - prefix = SwigType_istemplate_templateprefix($3); - if (prefix) { - String *fbase, *tbase; - if (Namespaceprefix) { - fbase = NewStringf("%s::%s", Namespaceprefix,$3); - tbase = NewStringf("%s::%s", Namespaceprefix, prefix); - } else { - fbase = Copy($3); - tbase = Copy(prefix); - } - Swig_name_inherit(tbase,fbase); - Delete(fbase); - Delete(tbase); - } - if (strcmp($2,"class") == 0) { - cplus_mode = CPLUS_PRIVATE; - } else { - cplus_mode = CPLUS_PUBLIC; - } - if (!cparse_cplusplus) { - set_scope_to_global(); - } - Swig_symbol_newscope(); - Swig_symbol_setscopename($3); - Swig_inherit_base_symbols(bases); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - cparse_start_line = cparse_line; - - /* If there are active template parameters, we need to make sure they are - placed in the class symbol table so we can catch shadows */ - - if (template_parameters) { - Parm *tp = template_parameters; - while(tp) { - String *tpname = Copy(Getattr(tp,"name")); - Node *tn = new_node("templateparm"); - Setattr(tn,"name",tpname); - Swig_symbol_cadd(tpname,tn); - tp = nextSibling(tp); - Delete(tpname); - } - } - Delete(prefix); - inclass = 1; - currentOuterClass = $<node>$; - if (cparse_cplusplusout) { - /* save the structure declaration to declare it in global scope for C++ to see */ - code = get_raw_text_balanced('{', '}'); - Setattr($<node>$, "code", code); - Delete(code); - } - } cpp_members RBRACE cpp_opt_declarators { - Node *p; - SwigType *ty; - Symtab *cscope; - Node *am = 0; - String *scpname = 0; - (void) $<node>6; - $$ = currentOuterClass; - currentOuterClass = Getattr($$, "nested:outer"); - nscope_inner = Getattr($<node>$, "nested:innerscope"); - nscope = Getattr($<node>$, "nested:nscope"); - Delattr($<node>$, "nested:innerscope"); - Delattr($<node>$, "nested:nscope"); - if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0) { /* actual parent class for this class */ - Node* forward_declaration = Swig_symbol_clookup_no_inherit(Getattr($<node>$,"name"), Getattr(nscope_inner, "symtab")); - if (forward_declaration) { - Setattr($<node>$, "access", Getattr(forward_declaration, "access")); - } - Setattr($<node>$, "nested:outer", nscope_inner); - SetFlag($<node>$, "nested"); - } - if (!currentOuterClass) - inclass = 0; - cscope = Getattr($$, "prev_symtab"); - Delattr($$, "prev_symtab"); - - /* Check for pure-abstract class */ - Setattr($$,"abstracts", pure_abstracts($8)); - - /* This bit of code merges in a previously defined %extend directive (if any) */ - { - String *clsname = Swig_symbol_qualifiedscopename(0); - am = Getattr(Swig_extend_hash(), clsname); - if (am) { - Swig_extend_merge($$, am); - Delattr(Swig_extend_hash(), clsname); - } - Delete(clsname); - } - if (!classes) classes = NewHash(); - scpname = Swig_symbol_qualifiedscopename(0); - Setattr(classes, scpname, $$); - - appendChild($$, $8); - - if (am) - Swig_extend_append_previous($$, am); - - p = $10; - if (p && !nscope_inner) { - if (!cparse_cplusplus && currentOuterClass) - appendChild(currentOuterClass, p); - else - appendSibling($$, p); - } - - if (nscope_inner) { - ty = NewString(scpname); /* if the class is declared out of scope, let the declarator use fully qualified type*/ - } else if (cparse_cplusplus && !cparse_externc) { - ty = NewString($3); - } else { - ty = NewStringf("%s %s", $2, $3); - } - while (p) { - Setattr(p, "storage", $1); - Setattr(p, "type" ,ty); - if (!cparse_cplusplus && currentOuterClass && (!Getattr(currentOuterClass, "name"))) { - SetFlag(p, "hasconsttype"); - SetFlag(p, "feature:immutable"); - } - p = nextSibling(p); - } - if ($10 && Cmp($1,"typedef") == 0) - add_typedef_name($$, $10, $3, cscope, scpname); - Delete(scpname); - - if (cplus_mode != CPLUS_PUBLIC) { - /* we 'open' the class at the end, to allow %template - to add new members */ - Node *pa = new_node("access"); - Setattr(pa, "kind", "public"); - cplus_mode = CPLUS_PUBLIC; - appendChild($$, pa); - Delete(pa); - } - if (currentOuterClass) - restore_access_mode($$); - Setattr($$, "symtab", Swig_symbol_popscope()); - Classprefix = Getattr($<node>$, "Classprefix"); - Delattr($<node>$, "Classprefix"); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - if (cplus_mode == CPLUS_PRIVATE) { - $$ = 0; /* skip private nested classes */ - } else if (cparse_cplusplus && currentOuterClass && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) { - $$ = nested_forward_declaration($1, $2, $3, Copy($3), $10); - } else if (nscope_inner) { - /* this is tricky */ - /* we add the declaration in the original namespace */ - if (Strcmp(nodeType(nscope_inner), "class") == 0 && cparse_cplusplus && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) - $$ = nested_forward_declaration($1, $2, $3, Copy($3), $10); - appendChild(nscope_inner, $$); - Swig_symbol_setscope(Getattr(nscope_inner, "symtab")); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - yyrename = Copy(Getattr($<node>$, "class_rename")); - add_symbols($$); - Delattr($$, "class_rename"); - /* but the variable definition in the current scope */ - Swig_symbol_setscope(cscope); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - add_symbols($10); - if (nscope) { - $$ = nscope; /* here we return recreated namespace tower instead of the class itself */ - if ($10) { - appendSibling($$, $10); - } - } else if (!SwigType_istemplate(ty) && template_parameters == 0) { /* for template we need the class itself */ - $$ = $10; - } - } else { - Delete(yyrename); - yyrename = 0; - if (!cparse_cplusplus && currentOuterClass) { /* nested C structs go into global scope*/ - Node *outer = currentOuterClass; - while (Getattr(outer, "nested:outer")) - outer = Getattr(outer, "nested:outer"); - appendSibling(outer, $$); - Swig_symbol_setscope(cscope); /* declaration goes in the parent scope */ - add_symbols($10); - set_scope_to_global(); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - yyrename = Copy(Getattr($<node>$, "class_rename")); - add_symbols($$); - if (!cparse_cplusplusout) - Delattr($$, "nested:outer"); - Delattr($$, "class_rename"); - $$ = 0; - } else { - yyrename = Copy(Getattr($<node>$, "class_rename")); - add_symbols($$); - add_symbols($10); - Delattr($$, "class_rename"); - } - } - Delete(ty); - Swig_symbol_setscope(cscope); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - Classprefix = currentOuterClass ? Getattr(currentOuterClass, "Classprefix") : 0; - } - -/* An unnamed struct, possibly with a typedef */ - - | storage_class cpptype inherit LBRACE { - String *unnamed; - String *code; - unnamed = make_unnamed(); - $<node>$ = new_node("class"); - Setline($<node>$,cparse_start_line); - Setattr($<node>$,"kind",$2); - if ($3) { - Setattr($<node>$,"baselist", Getattr($3,"public")); - Setattr($<node>$,"protectedbaselist", Getattr($3,"protected")); - Setattr($<node>$,"privatebaselist", Getattr($3,"private")); - } - Setattr($<node>$,"storage",$1); - Setattr($<node>$,"unnamed",unnamed); - Setattr($<node>$,"allows_typedef","1"); - if (currentOuterClass) { - SetFlag($<node>$, "nested"); - Setattr($<node>$, "nested:outer", currentOuterClass); - set_access_mode($<node>$); - } - Swig_features_get(Swig_cparse_features(), Namespaceprefix, 0, 0, $<node>$); - /* save yyrename to the class attribute, to be used later in add_symbols()*/ - Setattr($<node>$, "class_rename", make_name($<node>$,0,0)); - if (strcmp($2,"class") == 0) { - cplus_mode = CPLUS_PRIVATE; - } else { - cplus_mode = CPLUS_PUBLIC; - } - Swig_symbol_newscope(); - cparse_start_line = cparse_line; - currentOuterClass = $<node>$; - inclass = 1; - Classprefix = 0; - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - /* save the structure declaration to make a typedef for it later*/ - code = get_raw_text_balanced('{', '}'); - Setattr($<node>$, "code", code); - Delete(code); - } cpp_members RBRACE cpp_opt_declarators { - String *unnamed; - List *bases = 0; - String *name = 0; - Node *n; - Classprefix = 0; - (void)$<node>5; - $$ = currentOuterClass; - currentOuterClass = Getattr($$, "nested:outer"); - if (!currentOuterClass) - inclass = 0; - else - restore_access_mode($$); - unnamed = Getattr($$,"unnamed"); - /* Check for pure-abstract class */ - Setattr($$,"abstracts", pure_abstracts($6)); - n = $8; - if (cparse_cplusplus && currentOuterClass && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) { - String *name = n ? Copy(Getattr(n, "name")) : 0; - $$ = nested_forward_declaration($1, $2, 0, name, n); - Swig_symbol_popscope(); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - } else if (n) { - appendSibling($$,n); - /* If a proper typedef name was given, we'll use it to set the scope name */ - name = try_to_find_a_name_for_unnamed_structure($1, n); - if (name) { - String *scpname = 0; - SwigType *ty; - Setattr($$,"tdname",name); - Setattr($$,"name",name); - Swig_symbol_setscopename(name); - if ($3) - bases = Swig_make_inherit_list(name,Getattr($3,"public"),Namespaceprefix); - Swig_inherit_base_symbols(bases); - - /* If a proper name was given, we use that as the typedef, not unnamed */ - Clear(unnamed); - Append(unnamed, name); - if (cparse_cplusplus && !cparse_externc) { - ty = NewString(name); - } else { - ty = NewStringf("%s %s", $2,name); - } - while (n) { - Setattr(n,"storage",$1); - Setattr(n, "type", ty); - if (!cparse_cplusplus && currentOuterClass && (!Getattr(currentOuterClass, "name"))) { - SetFlag(n,"hasconsttype"); - SetFlag(n,"feature:immutable"); - } - n = nextSibling(n); - } - n = $8; - - /* Check for previous extensions */ - { - String *clsname = Swig_symbol_qualifiedscopename(0); - Node *am = Getattr(Swig_extend_hash(),clsname); - if (am) { - /* Merge the extension into the symbol table */ - Swig_extend_merge($$,am); - Swig_extend_append_previous($$,am); - Delattr(Swig_extend_hash(),clsname); - } - Delete(clsname); - } - if (!classes) classes = NewHash(); - scpname = Swig_symbol_qualifiedscopename(0); - Setattr(classes,scpname,$$); - Delete(scpname); - } else { /* no suitable name was found for a struct */ - Setattr($$, "nested:unnamed", Getattr(n, "name")); /* save the name of the first declarator for later use in name generation*/ - while (n) { /* attach unnamed struct to the declarators, so that they would receive proper type later*/ - Setattr(n, "nested:unnamedtype", $$); - Setattr(n, "storage", $1); - n = nextSibling(n); - } - n = $8; - Swig_symbol_setscopename("<unnamed>"); - } - appendChild($$,$6); - /* Pop the scope */ - Setattr($$,"symtab",Swig_symbol_popscope()); - if (name) { - Delete(yyrename); - yyrename = Copy(Getattr($<node>$, "class_rename")); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - add_symbols($$); - add_symbols(n); - Delattr($$, "class_rename"); - }else if (cparse_cplusplus) - $$ = 0; /* ignore unnamed structs for C++ */ - Delete(unnamed); - } else { /* unnamed struct w/o declarator*/ - Swig_symbol_popscope(); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - add_symbols($6); - Delete($$); - $$ = $6; /* pass member list to outer class/namespace (instead of self)*/ - } - Classprefix = currentOuterClass ? Getattr(currentOuterClass, "Classprefix") : 0; - } - ; - -cpp_opt_declarators : SEMI { $$ = 0; } - | declarator cpp_const initializer c_decl_tail { - $$ = new_node("cdecl"); - Setattr($$,"name",$1.id); - Setattr($$,"decl",$1.type); - Setattr($$,"parms",$1.parms); - set_nextSibling($$, $4); - } - ; -/* ------------------------------------------------------------ - class Name; - ------------------------------------------------------------ */ - -cpp_forward_class_decl : storage_class cpptype idcolon SEMI { - if ($1 && (Strcmp($1,"friend") == 0)) { - /* Ignore */ - $$ = 0; - } else { - $$ = new_node("classforward"); - Setattr($$,"kind",$2); - Setattr($$,"name",$3); - Setattr($$,"sym:weak", "1"); - add_symbols($$); - } - } - ; - -/* ------------------------------------------------------------ - template<...> decl - ------------------------------------------------------------ */ - -cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { - if (currentOuterClass) - Setattr(currentOuterClass, "template_parameters", template_parameters); - template_parameters = $3; - parsing_template_declaration = 1; - } cpp_template_possible { - String *tname = 0; - int error = 0; - - /* check if we get a namespace node with a class declaration, and retrieve the class */ - Symtab *cscope = Swig_symbol_current(); - Symtab *sti = 0; - Node *ntop = $6; - Node *ni = ntop; - SwigType *ntype = ni ? nodeType(ni) : 0; - while (ni && Strcmp(ntype,"namespace") == 0) { - sti = Getattr(ni,"symtab"); - ni = firstChild(ni); - ntype = nodeType(ni); - } - if (sti) { - Swig_symbol_setscope(sti); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - $6 = ni; - } - - $$ = $6; - if ($$) tname = Getattr($$,"name"); - - /* Check if the class is a template specialization */ - if (($$) && (Strchr(tname,'<')) && (!is_operator(tname))) { - /* If a specialization. Check if defined. */ - Node *tempn = 0; - { - String *tbase = SwigType_templateprefix(tname); - tempn = Swig_symbol_clookup_local(tbase,0); - if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) { - SWIG_WARN_NODE_BEGIN(tempn); - Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase); - SWIG_WARN_NODE_END(tempn); - tempn = 0; - error = 1; - } - Delete(tbase); - } - Setattr($$,"specialization","1"); - Setattr($$,"templatetype",nodeType($$)); - set_nodeType($$,"template"); - /* Template partial specialization */ - if (tempn && ($3) && ($6)) { - List *tlist; - String *targs = SwigType_templateargs(tname); - tlist = SwigType_parmlist(targs); - /* Printf(stdout,"targs = '%s' %s\n", targs, tlist); */ - if (!Getattr($$,"sym:weak")) { - Setattr($$,"sym:typename","1"); - } - - if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) { - Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms"))); - - } else { - - /* This code builds the argument list for the partial template - specialization. This is a little hairy, but the idea is as - follows: - - $3 contains a list of arguments supplied for the template. - For example template<class T>. - - tlist is a list of the specialization arguments--which may be - different. For example class<int,T>. - - tp is a copy of the arguments in the original template definition. - - The patching algorithm walks through the list of supplied - arguments ($3), finds the position in the specialization arguments - (tlist), and then patches the name in the argument list of the - original template. - */ - - { - String *pn; - Parm *p, *p1; - int i, nargs; - Parm *tp = CopyParmList(Getattr(tempn,"templateparms")); - nargs = Len(tlist); - p = $3; - while (p) { - for (i = 0; i < nargs; i++){ - pn = Getattr(p,"name"); - if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) { - int j; - Parm *p1 = tp; - for (j = 0; j < i; j++) { - p1 = nextSibling(p1); - } - Setattr(p1,"name",pn); - Setattr(p1,"partialarg","1"); - } - } - p = nextSibling(p); - } - p1 = tp; - i = 0; - while (p1) { - if (!Getattr(p1,"partialarg")) { - Delattr(p1,"name"); - Setattr(p1,"type", Getitem(tlist,i)); - } - i++; - p1 = nextSibling(p1); - } - Setattr($$,"templateparms",tp); - Delete(tp); - } - #if 0 - /* Patch the parameter list */ - if (tempn) { - Parm *p,*p1; - ParmList *tp = CopyParmList(Getattr(tempn,"templateparms")); - p = $3; - p1 = tp; - while (p && p1) { - String *pn = Getattr(p,"name"); - Printf(stdout,"pn = '%s'\n", pn); - if (pn) Setattr(p1,"name",pn); - else Delattr(p1,"name"); - pn = Getattr(p,"type"); - if (pn) Setattr(p1,"type",pn); - p = nextSibling(p); - p1 = nextSibling(p1); - } - Setattr($$,"templateparms",tp); - Delete(tp); - } else { - Setattr($$,"templateparms",$3); - } - #endif - Delattr($$,"specialization"); - Setattr($$,"partialspecialization","1"); - /* Create a specialized name for matching */ - { - Parm *p = $3; - String *fname = NewString(Getattr($$,"name")); - String *ffname = 0; - ParmList *partialparms = 0; - - char tmp[32]; - int i, ilen; - while (p) { - String *n = Getattr(p,"name"); - if (!n) { - p = nextSibling(p); - continue; - } - ilen = Len(tlist); - for (i = 0; i < ilen; i++) { - if (Strstr(Getitem(tlist,i),n)) { - sprintf(tmp,"$%d",i+1); - Replaceid(fname,n,tmp); - } - } - p = nextSibling(p); - } - /* Patch argument names with typedef */ - { - Iterator tt; - Parm *parm_current = 0; - List *tparms = SwigType_parmlist(fname); - ffname = SwigType_templateprefix(fname); - Append(ffname,"<("); - for (tt = First(tparms); tt.item; ) { - SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0); - SwigType *ttr = Swig_symbol_type_qualify(rtt,0); - - Parm *newp = NewParmWithoutFileLineInfo(ttr, 0); - if (partialparms) - set_nextSibling(parm_current, newp); - else - partialparms = newp; - parm_current = newp; - - Append(ffname,ttr); - tt = Next(tt); - if (tt.item) Putc(',',ffname); - Delete(rtt); - Delete(ttr); - } - Delete(tparms); - Append(ffname,")>"); - } - { - Node *new_partial = NewHash(); - String *partials = Getattr(tempn,"partials"); - if (!partials) { - partials = NewList(); - Setattr(tempn,"partials",partials); - Delete(partials); - } - /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */ - Setattr(new_partial, "partialparms", partialparms); - Setattr(new_partial, "templcsymname", ffname); - Append(partials, new_partial); - } - Setattr($$,"partialargs",ffname); - Swig_symbol_cadd(ffname,$$); - } - } - Delete(tlist); - Delete(targs); - } else { - /* An explicit template specialization */ - /* add default args from primary (unspecialized) template */ - String *ty = Swig_symbol_template_deftype(tname,0); - String *fname = Swig_symbol_type_qualify(ty,0); - Swig_symbol_cadd(fname,$$); - Delete(ty); - Delete(fname); - } - } else if ($$) { - Setattr($$,"templatetype",nodeType($6)); - set_nodeType($$,"template"); - Setattr($$,"templateparms", $3); - if (!Getattr($$,"sym:weak")) { - Setattr($$,"sym:typename","1"); - } - add_symbols($$); - default_arguments($$); - /* We also place a fully parameterized version in the symbol table */ - { - Parm *p; - String *fname = NewStringf("%s<(", Getattr($$,"name")); - p = $3; - while (p) { - String *n = Getattr(p,"name"); - if (!n) n = Getattr(p,"type"); - Append(fname,n); - p = nextSibling(p); - if (p) Putc(',',fname); - } - Append(fname,")>"); - Swig_symbol_cadd(fname,$$); - } - } - $$ = ntop; - Swig_symbol_setscope(cscope); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - if (error || (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0)) { - $$ = 0; - } - if (currentOuterClass) - template_parameters = Getattr(currentOuterClass, "template_parameters"); - else - template_parameters = 0; - parsing_template_declaration = 0; - } - - /* Class template explicit instantiation definition */ - | TEMPLATE cpptype idcolon { - Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n"); - $$ = 0; - } - - /* Function template explicit instantiation definition */ - | TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN { - Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n"); - $$ = 0; - } - - /* Class template explicit instantiation declaration (extern template) */ - | EXTERN TEMPLATE cpptype idcolon { - Swig_warning(WARN_PARSE_EXTERN_TEMPLATE, cparse_file, cparse_line, "Extern template ignored.\n"); - $$ = 0; - } - - /* Function template explicit instantiation declaration (extern template) */ - | EXTERN TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN { - Swig_warning(WARN_PARSE_EXTERN_TEMPLATE, cparse_file, cparse_line, "Extern template ignored.\n"); - $$ = 0; - } - ; - -cpp_template_possible: c_decl { - $$ = $1; - } - | cpp_class_decl { - $$ = $1; - } - | cpp_constructor_decl { - $$ = $1; - } - | cpp_template_decl { - $$ = 0; - } - | cpp_forward_class_decl { - $$ = $1; - } - | cpp_conversion_operator { - $$ = $1; - } - ; - -template_parms : templateparameters { - /* Rip out the parameter names */ - Parm *p = $1; - $$ = $1; - - while (p) { - String *name = Getattr(p,"name"); - if (!name) { - /* Hmmm. Maybe it's a 'class T' parameter */ - char *type = Char(Getattr(p,"type")); - /* Template template parameter */ - if (strncmp(type,"template<class> ",16) == 0) { - type += 16; - } - if ((strncmp(type,"class ",6) == 0) || (strncmp(type,"typename ", 9) == 0)) { - char *t = strchr(type,' '); - Setattr(p,"name", t+1); - } else - /* Variadic template args */ - if ((strncmp(type,"class... ",9) == 0) || (strncmp(type,"typename... ", 12) == 0)) { - char *t = strchr(type,' '); - Setattr(p,"name", t+1); - Setattr(p,"variadic", "1"); - } else { - /* - Swig_error(cparse_file, cparse_line, "Missing template parameter name\n"); - $$.rparms = 0; - $$.parms = 0; - break; */ - } - } - p = nextSibling(p); - } - } - ; - -templateparameters : templateparameter templateparameterstail { - set_nextSibling($1,$2); - $$ = $1; - } - | empty { $$ = 0; } - ; - -templateparameter : templcpptype def_args { - $$ = NewParmWithoutFileLineInfo(NewString($1), 0); - Setattr($$, "value", $2.rawval ? $2.rawval : $2.val); - } - | parm { - $$ = $1; - } - ; - -templateparameterstail : COMMA templateparameter templateparameterstail { - set_nextSibling($2,$3); - $$ = $2; - } - | empty { $$ = 0; } - ; - -/* Namespace support */ - -cpp_using_decl : USING idcolon SEMI { - String *uname = Swig_symbol_type_qualify($2,0); - String *name = Swig_scopename_last($2); - $$ = new_node("using"); - Setattr($$,"uname",uname); - Setattr($$,"name", name); - Delete(uname); - Delete(name); - add_symbols($$); - } - | USING NAMESPACE idcolon SEMI { - Node *n = Swig_symbol_clookup($3,0); - if (!n) { - Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", $3); - $$ = 0; - } else { - - while (Strcmp(nodeType(n),"using") == 0) { - n = Getattr(n,"node"); - } - if (n) { - if (Strcmp(nodeType(n),"namespace") == 0) { - Symtab *current = Swig_symbol_current(); - Symtab *symtab = Getattr(n,"symtab"); - $$ = new_node("using"); - Setattr($$,"node",n); - Setattr($$,"namespace", $3); - if (current != symtab) { - Swig_symbol_inherit(symtab); - } - } else { - Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", $3); - $$ = 0; - } - } else { - $$ = 0; - } - } - } - ; - -cpp_namespace_decl : NAMESPACE idcolon LBRACE { - Hash *h; - Node *parent_ns = 0; - List *scopes = Swig_scopename_tolist($2); - int ilen = Len(scopes); - int i; - -/* -Printf(stdout, "==== Namespace %s creation...\n", $2); -*/ - $<node>$ = 0; - for (i = 0; i < ilen; i++) { - Node *ns = new_node("namespace"); - Symtab *current_symtab = Swig_symbol_current(); - String *scopename = Getitem(scopes, i); - Setattr(ns, "name", scopename); - $<node>$ = ns; - if (parent_ns) - appendChild(parent_ns, ns); - parent_ns = ns; - h = Swig_symbol_clookup(scopename, 0); - if (h && (current_symtab == Getattr(h, "sym:symtab")) && (Strcmp(nodeType(h), "namespace") == 0)) { -/* -Printf(stdout, " Scope %s [found C++17 style]\n", scopename); -*/ - if (Getattr(h, "alias")) { - h = Getattr(h, "namespace"); - Swig_warning(WARN_PARSE_NAMESPACE_ALIAS, cparse_file, cparse_line, "Namespace alias '%s' not allowed here. Assuming '%s'\n", - scopename, Getattr(h, "name")); - scopename = Getattr(h, "name"); - } - Swig_symbol_setscope(Getattr(h, "symtab")); - } else { -/* -Printf(stdout, " Scope %s [creating single scope C++17 style]\n", scopename); -*/ - h = Swig_symbol_newscope(); - Swig_symbol_setscopename(scopename); - } - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - } - Delete(scopes); - } interface RBRACE { - Node *n = $<node>4; - Node *top_ns = 0; - do { - Setattr(n, "symtab", Swig_symbol_popscope()); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - add_symbols(n); - top_ns = n; - n = parentNode(n); - } while(n); - appendChild($<node>4, firstChild($5)); - Delete($5); - $$ = top_ns; - } - | NAMESPACE LBRACE { - Hash *h; - $1 = Swig_symbol_current(); - h = Swig_symbol_clookup(" ",0); - if (h && (Strcmp(nodeType(h),"namespace") == 0)) { - Swig_symbol_setscope(Getattr(h,"symtab")); - } else { - Swig_symbol_newscope(); - /* we don't use "__unnamed__", but a long 'empty' name */ - Swig_symbol_setscopename(" "); - } - Namespaceprefix = 0; - } interface RBRACE { - $$ = $4; - set_nodeType($$,"namespace"); - Setattr($$,"unnamed","1"); - Setattr($$,"symtab", Swig_symbol_popscope()); - Swig_symbol_setscope($1); - Delete(Namespaceprefix); - Namespaceprefix = Swig_symbol_qualifiedscopename(0); - add_symbols($$); - } - | NAMESPACE identifier EQUAL idcolon SEMI { - /* Namespace alias */ - Node *n; - $$ = new_node("namespace"); - Setattr($$,"name",$2); - Setattr($$,"alias",$4); - n = Swig_symbol_clookup($4,0); - if (!n) { - Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", $4); - $$ = 0; - } else { - if (Strcmp(nodeType(n),"namespace") != 0) { - Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n",$4); - $$ = 0; - } else { - while (Getattr(n,"alias")) { - n = Getattr(n,"namespace"); - } - Setattr($$,"namespace",n); - add_symbols($$); - /* Set up a scope alias */ - Swig_symbol_alias($2,Getattr(n,"symtab")); - } - } - } - ; - -cpp_members : cpp_member cpp_members { - $$ = $1; - /* Insert cpp_member (including any siblings) to the front of the cpp_members linked list */ - if ($$) { - Node *p = $$; - Node *pp =0; - while (p) { - pp = p; - p = nextSibling(p); - } - set_nextSibling(pp,$2); - if ($2) - set_previousSibling($2, pp); - } else { - $$ = $2; - } - } - | EXTEND LBRACE { - extendmode = 1; - if (cplus_mode != CPLUS_PUBLIC) { - Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n"); - } - } cpp_members RBRACE { - extendmode = 0; - } cpp_members { - $$ = new_node("extend"); - mark_nodes_as_extend($4); - appendChild($$,$4); - set_nextSibling($$,$7); - } - | include_directive { $$ = $1; } - | empty { $$ = 0;} - | error { - Swig_error(cparse_file,cparse_line,"Syntax error in input(3).\n"); - Exit(EXIT_FAILURE); - } cpp_members { - $$ = $3; - } - ; - -/* ====================================================================== - * C++ Class members - * ====================================================================== */ - -/* A class member. May be data or a function. Static or virtual as well */ - -cpp_member_no_dox : c_declaration { $$ = $1; } - | cpp_constructor_decl { - $$ = $1; - if (extendmode && current_class) { - String *symname; - symname= make_name($$,Getattr($$,"name"), Getattr($$,"decl")); - if (Strcmp(symname,Getattr($$,"name")) == 0) { - /* No renaming operation. Set name to class name */ - Delete(yyrename); - yyrename = NewString(Getattr(current_class,"sym:name")); - } else { - Delete(yyrename); - yyrename = symname; - } - } - add_symbols($$); - default_arguments($$); - } - | cpp_destructor_decl { $$ = $1; } - | cpp_protection_decl { $$ = $1; } - | cpp_swig_directive { $$ = $1; } - | cpp_conversion_operator { $$ = $1; } - | cpp_forward_class_decl { $$ = $1; } - | cpp_class_decl { $$ = $1; } - | storage_class idcolon SEMI { $$ = 0; } - | cpp_using_decl { $$ = $1; } - | cpp_template_decl { $$ = $1; } - | cpp_catch_decl { $$ = 0; } - | template_directive { $$ = $1; } - | warn_directive { $$ = $1; } - | anonymous_bitfield { $$ = 0; } - | fragment_directive {$$ = $1; } - | types_directive {$$ = $1; } - | SEMI { $$ = 0; } - -cpp_member : cpp_member_no_dox { - $$ = $1; - } - | DOXYGENSTRING cpp_member_no_dox { - $$ = $2; - set_comment($2, $1); - } - | cpp_member_no_dox DOXYGENPOSTSTRING { - $$ = $1; - set_comment($1, $2); - } - ; - -/* Possibly a constructor */ -/* Note: the use of 'type' is here to resolve a shift-reduce conflict. For example: - typedef Foo (); - typedef Foo (*ptr)(); -*/ - -cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end { - if (inclass || extendmode) { - SwigType *decl = NewStringEmpty(); - $$ = new_node("constructor"); - Setattr($$,"storage",$1); - Setattr($$,"name",$2); - Setattr($$,"parms",$4); - SwigType_add_function(decl,$4); - Setattr($$,"decl",decl); - Setattr($$,"throws",$6.throws); - Setattr($$,"throw",$6.throwf); - Setattr($$,"noexcept",$6.nexcept); - Setattr($$,"final",$6.final); - if (Len(scanner_ccode)) { - String *code = Copy(scanner_ccode); - Setattr($$,"code",code); - Delete(code); - } - SetFlag($$,"feature:new"); - if ($6.defarg) - Setattr($$,"value",$6.defarg); - } else { - $$ = 0; - } - } - ; - -/* A destructor (hopefully) */ - -cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end { - String *name = NewStringf("%s",$2); - if (*(Char(name)) != '~') Insert(name,0,"~"); - $$ = new_node("destructor"); - Setattr($$,"name",name); - Delete(name); - if (Len(scanner_ccode)) { - String *code = Copy(scanner_ccode); - Setattr($$,"code",code); - Delete(code); - } - { - String *decl = NewStringEmpty(); - SwigType_add_function(decl,$4); - Setattr($$,"decl",decl); - Delete(decl); - } - Setattr($$,"throws",$6.throws); - Setattr($$,"throw",$6.throwf); - Setattr($$,"noexcept",$6.nexcept); - Setattr($$,"final",$6.final); - if ($6.val) - Setattr($$,"value",$6.val); - if ($6.qualifier) - Swig_error(cparse_file, cparse_line, "Destructor %s %s cannot have a qualifier.\n", Swig_name_decl($$), SwigType_str($6.qualifier, 0)); - add_symbols($$); - } - -/* A virtual destructor */ - - | VIRTUAL NOT idtemplate LPAREN parms RPAREN cpp_vend { - String *name; - $$ = new_node("destructor"); - Setattr($$,"storage","virtual"); - name = NewStringf("%s",$3); - if (*(Char(name)) != '~') Insert(name,0,"~"); - Setattr($$,"name",name); - Delete(name); - Setattr($$,"throws",$7.throws); - Setattr($$,"throw",$7.throwf); - Setattr($$,"noexcept",$7.nexcept); - Setattr($$,"final",$7.final); - if ($7.val) - Setattr($$,"value",$7.val); - if (Len(scanner_ccode)) { - String *code = Copy(scanner_ccode); - Setattr($$,"code",code); - Delete(code); - } - { - String *decl = NewStringEmpty(); - SwigType_add_function(decl,$5); - Setattr($$,"decl",decl); - Delete(decl); - } - if ($7.qualifier) - Swig_error(cparse_file, cparse_line, "Destructor %s %s cannot have a qualifier.\n", Swig_name_decl($$), SwigType_str($7.qualifier, 0)); - add_symbols($$); - } - ; - - -/* C++ type conversion operator */ -cpp_conversion_operator : storage_class CONVERSIONOPERATOR type pointer LPAREN parms RPAREN cpp_vend { - $$ = new_node("cdecl"); - Setattr($$,"type",$3); - Setattr($$,"name",$2); - Setattr($$,"storage",$1); - - SwigType_add_function($4,$6); - if ($8.qualifier) { - SwigType_push($4,$8.qualifier); - } - if ($8.val) { - Setattr($$,"value",$8.val); - } - Setattr($$,"refqualifier",$8.refqualifier); - Setattr($$,"decl",$4); - Setattr($$,"parms",$6); - Setattr($$,"conversion_operator","1"); - add_symbols($$); - } - | storage_class CONVERSIONOPERATOR type AND LPAREN parms RPAREN cpp_vend { - SwigType *decl; - $$ = new_node("cdecl"); - Setattr($$,"type",$3); - Setattr($$,"name",$2); - Setattr($$,"storage",$1); - decl = NewStringEmpty(); - SwigType_add_reference(decl); - SwigType_add_function(decl,$6); - if ($8.qualifier) { - SwigType_push(decl,$8.qualifier); - } - if ($8.val) { - Setattr($$,"value",$8.val); - } - Setattr($$,"refqualifier",$8.refqualifier); - Setattr($$,"decl",decl); - Setattr($$,"parms",$6); - Setattr($$,"conversion_operator","1"); - add_symbols($$); - } - | storage_class CONVERSIONOPERATOR type LAND LPAREN parms RPAREN cpp_vend { - SwigType *decl; - $$ = new_node("cdecl"); - Setattr($$,"type",$3); - Setattr($$,"name",$2); - Setattr($$,"storage",$1); - decl = NewStringEmpty(); - SwigType_add_rvalue_reference(decl); - SwigType_add_function(decl,$6); - if ($8.qualifier) { - SwigType_push(decl,$8.qualifier); - } - if ($8.val) { - Setattr($$,"value",$8.val); - } - Setattr($$,"refqualifier",$8.refqualifier); - Setattr($$,"decl",decl); - Setattr($$,"parms",$6); - Setattr($$,"conversion_operator","1"); - add_symbols($$); - } - - | storage_class CONVERSIONOPERATOR type pointer AND LPAREN parms RPAREN cpp_vend { - SwigType *decl; - $$ = new_node("cdecl"); - Setattr($$,"type",$3); - Setattr($$,"name",$2); - Setattr($$,"storage",$1); - decl = NewStringEmpty(); - SwigType_add_pointer(decl); - SwigType_add_reference(decl); - SwigType_add_function(decl,$7); - if ($9.qualifier) { - SwigType_push(decl,$9.qualifier); - } - if ($9.val) { - Setattr($$,"value",$9.val); - } - Setattr($$,"refqualifier",$9.refqualifier); - Setattr($$,"decl",decl); - Setattr($$,"parms",$7); - Setattr($$,"conversion_operator","1"); - add_symbols($$); - } - - | storage_class CONVERSIONOPERATOR type LPAREN parms RPAREN cpp_vend { - String *t = NewStringEmpty(); - $$ = new_node("cdecl"); - Setattr($$,"type",$3); - Setattr($$,"name",$2); - Setattr($$,"storage",$1); - SwigType_add_function(t,$5); - if ($7.qualifier) { - SwigType_push(t,$7.qualifier); - } - if ($7.val) { - Setattr($$,"value",$7.val); - } - Setattr($$,"refqualifier",$7.refqualifier); - Setattr($$,"decl",t); - Setattr($$,"parms",$5); - Setattr($$,"conversion_operator","1"); - add_symbols($$); - } - ; - -/* isolated catch clause. */ - -cpp_catch_decl : CATCH LPAREN parms RPAREN LBRACE { - skip_balanced('{','}'); - $$ = 0; - } - ; - -/* static_assert(bool, const char*); (C++11) - * static_assert(bool); (C++17) */ -cpp_static_assert : STATIC_ASSERT LPAREN { - skip_balanced('(',')'); - $$ = 0; - } - ; - -/* public: */ -cpp_protection_decl : PUBLIC COLON { - $$ = new_node("access"); - Setattr($$,"kind","public"); - cplus_mode = CPLUS_PUBLIC; - } - -/* private: */ - | PRIVATE COLON { - $$ = new_node("access"); - Setattr($$,"kind","private"); - cplus_mode = CPLUS_PRIVATE; - } - -/* protected: */ - - | PROTECTED COLON { - $$ = new_node("access"); - Setattr($$,"kind","protected"); - cplus_mode = CPLUS_PROTECTED; - } - ; -/* These directives can be included inside a class definition */ - -cpp_swig_directive: pragma_directive { $$ = $1; } - -/* A constant (includes #defines) inside a class */ - | constant_directive { $$ = $1; } - -/* This is the new style rename */ - - | name_directive { $$ = $1; } - -/* rename directive */ - | rename_directive { $$ = $1; } - | feature_directive { $$ = $1; } - | varargs_directive { $$ = $1; } - | insert_directive { $$ = $1; } - | typemap_directive { $$ = $1; } - | apply_directive { $$ = $1; } - | clear_directive { $$ = $1; } - | echo_directive { $$ = $1; } - ; - -cpp_end : cpp_const SEMI { - Clear(scanner_ccode); - $$.val = 0; - $$.qualifier = $1.qualifier; - $$.refqualifier = $1.refqualifier; - $$.bitfield = 0; - $$.throws = $1.throws; - $$.throwf = $1.throwf; - $$.nexcept = $1.nexcept; - $$.final = $1.final; - } - | cpp_const EQUAL default_delete SEMI { - Clear(scanner_ccode); - $$.val = $3.val; - $$.qualifier = $1.qualifier; - $$.refqualifier = $1.refqualifier; - $$.bitfield = 0; - $$.throws = $1.throws; - $$.throwf = $1.throwf; - $$.nexcept = $1.nexcept; - $$.final = $1.final; - } - | cpp_const LBRACE { - skip_balanced('{','}'); - $$.val = 0; - $$.qualifier = $1.qualifier; - $$.refqualifier = $1.refqualifier; - $$.bitfield = 0; - $$.throws = $1.throws; - $$.throwf = $1.throwf; - $$.nexcept = $1.nexcept; - $$.final = $1.final; - } - ; - -cpp_vend : cpp_const SEMI { - Clear(scanner_ccode); - $$.val = 0; - $$.qualifier = $1.qualifier; - $$.refqualifier = $1.refqualifier; - $$.bitfield = 0; - $$.throws = $1.throws; - $$.throwf = $1.throwf; - $$.nexcept = $1.nexcept; - $$.final = $1.final; - } - | cpp_const EQUAL definetype SEMI { - Clear(scanner_ccode); - $$.val = $3.val; - $$.qualifier = $1.qualifier; - $$.refqualifier = $1.refqualifier; - $$.bitfield = 0; - $$.throws = $1.throws; - $$.throwf = $1.throwf; - $$.nexcept = $1.nexcept; - $$.final = $1.final; - } - | cpp_const LBRACE { - skip_balanced('{','}'); - $$.val = 0; - $$.qualifier = $1.qualifier; - $$.refqualifier = $1.refqualifier; - $$.bitfield = 0; - $$.throws = $1.throws; - $$.throwf = $1.throwf; - $$.nexcept = $1.nexcept; - $$.final = $1.final; - } - ; - - -anonymous_bitfield : storage_class anon_bitfield_type COLON expr SEMI { }; - -/* Equals type_right without the ENUM keyword and cpptype (templates etc.): */ -anon_bitfield_type : primitive_type { $$ = $1; - /* Printf(stdout,"primitive = '%s'\n", $$);*/ - } - | TYPE_BOOL { $$ = $1; } - | TYPE_VOID { $$ = $1; } -/* - | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); } -*/ - | TYPE_RAW { $$ = $1; } - - | idcolon { - $$ = $1; - } - ; - -/* ====================================================================== - * PRIMITIVES - * ====================================================================== */ -extern_string : EXTERN string { - if (Strcmp($2,"C") == 0) { - $$ = "externc"; - } else if (Strcmp($2,"C++") == 0) { - $$ = "extern"; - } else { - Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2); - $$ = 0; - } - } - ; - -storage_class : EXTERN { $$ = "extern"; } - | extern_string { $$ = $1; } - | extern_string THREAD_LOCAL { - if (Equal($1, "extern")) { - $$ = "extern thread_local"; - } else { - $$ = "externc thread_local"; - } - } - | extern_string TYPEDEF { $$ = "typedef"; } - | STATIC { $$ = "static"; } - | TYPEDEF { $$ = "typedef"; } - | VIRTUAL { $$ = "virtual"; } - | FRIEND { $$ = "friend"; } - | EXPLICIT { $$ = "explicit"; } - | CONSTEXPR { $$ = "constexpr"; } - | EXPLICIT CONSTEXPR { $$ = "explicit constexpr"; } - | CONSTEXPR EXPLICIT { $$ = "explicit constexpr"; } - | STATIC CONSTEXPR { $$ = "static constexpr"; } - | CONSTEXPR STATIC { $$ = "static constexpr"; } - | THREAD_LOCAL { $$ = "thread_local"; } - | THREAD_LOCAL STATIC { $$ = "static thread_local"; } - | STATIC THREAD_LOCAL { $$ = "static thread_local"; } - | EXTERN THREAD_LOCAL { $$ = "extern thread_local"; } - | THREAD_LOCAL EXTERN { $$ = "extern thread_local"; } - | empty { $$ = 0; } - ; - -/* ------------------------------------------------------------------------------ - Function parameter lists - ------------------------------------------------------------------------------ */ - -parms : rawparms { - Parm *p; - $$ = $1; - p = $1; - while (p) { - Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY); - p = nextSibling(p); - } - } - ; - -rawparms : parm ptail { - set_nextSibling($1,$2); - $$ = $1; - } - | empty { - $$ = 0; - previousNode = currentNode; - currentNode=0; - } - ; - -ptail : COMMA parm ptail { - set_nextSibling($2,$3); - $$ = $2; - } - | COMMA DOXYGENPOSTSTRING parm ptail { - set_comment(previousNode, $2); - set_nextSibling($3, $4); - $$ = $3; - } - | empty { $$ = 0; } - ; - - -parm_no_dox : rawtype parameter_declarator { - SwigType_push($1,$2.type); - $$ = NewParmWithoutFileLineInfo($1,$2.id); - previousNode = currentNode; - currentNode = $$; - Setfile($$,cparse_file); - Setline($$,cparse_line); - if ($2.defarg) { - Setattr($$,"value",$2.defarg); - } - } - - | TEMPLATE LESSTHAN cpptype GREATERTHAN cpptype idcolon def_args { - $$ = NewParmWithoutFileLineInfo(NewStringf("template<class> %s %s", $5,$6), 0); - previousNode = currentNode; - currentNode = $$; - Setfile($$,cparse_file); - Setline($$,cparse_line); - if ($7.val) { - Setattr($$,"value",$7.val); - } - } - | ELLIPSIS { - SwigType *t = NewString("v(...)"); - $$ = NewParmWithoutFileLineInfo(t, 0); - previousNode = currentNode; - currentNode = $$; - Setfile($$,cparse_file); - Setline($$,cparse_line); - } - ; - -parm : parm_no_dox { - $$ = $1; - } - | DOXYGENSTRING parm_no_dox { - $$ = $2; - set_comment($2, $1); - } - | parm_no_dox DOXYGENPOSTSTRING { - $$ = $1; - set_comment($1, $2); - } - ; - -valparms : rawvalparms { - Parm *p; - $$ = $1; - p = $1; - while (p) { - if (Getattr(p,"type")) { - Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY); - } - p = nextSibling(p); - } - } - ; - -rawvalparms : valparm valptail { - set_nextSibling($1,$2); - $$ = $1; - } - | empty { $$ = 0; } - ; - -valptail : COMMA valparm valptail { - set_nextSibling($2,$3); - $$ = $2; - } - | empty { $$ = 0; } - ; - - -valparm : parm { - $$ = $1; - { - /* We need to make a possible adjustment for integer parameters. */ - SwigType *type; - Node *n = 0; - - while (!n) { - type = Getattr($1,"type"); - n = Swig_symbol_clookup(type,0); /* See if we can find a node that matches the typename */ - if ((n) && (Strcmp(nodeType(n),"cdecl") == 0)) { - SwigType *decl = Getattr(n,"decl"); - if (!SwigType_isfunction(decl)) { - String *value = Getattr(n,"value"); - if (value) { - String *v = Copy(value); - Setattr($1,"type",v); - Delete(v); - n = 0; - } - } - } else { - break; - } - } - } - - } - | valexpr { - $$ = NewParmWithoutFileLineInfo(0,0); - Setfile($$,cparse_file); - Setline($$,cparse_line); - Setattr($$,"value",$1.val); - } - ; - -callparms : valexpr callptail { - $$ = $1; - Printf($$.val, "%s", $2.val); - } - | empty { $$.val = NewStringEmpty(); } - ; - -callptail : COMMA valexpr callptail { - $$.val = NewStringf(",%s%s", $2.val, $3.val); - $$.type = 0; - } - | empty { $$.val = NewStringEmpty(); } - ; - -def_args : EQUAL definetype { - $$ = $2; - if ($2.type == T_ERROR) { - Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n"); - $$.val = 0; - $$.rawval = 0; - $$.bitfield = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } - } - | EQUAL definetype LBRACKET expr RBRACKET { - $$ = $2; - if ($2.type == T_ERROR) { - Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n"); - $$ = $2; - $$.val = 0; - $$.rawval = 0; - $$.bitfield = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } else { - $$.val = NewStringf("%s[%s]",$2.val,$4.val); - } - } - | EQUAL LBRACE { - skip_balanced('{','}'); - $$.val = NewString(scanner_ccode); - $$.rawval = 0; - $$.type = T_INT; - $$.bitfield = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } - | COLON expr { - $$.val = 0; - $$.rawval = 0; - $$.type = 0; - $$.bitfield = $2.val; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } - | empty { - $$.val = 0; - $$.rawval = 0; - $$.type = T_INT; - $$.bitfield = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } - ; - -parameter_declarator : declarator def_args { - $$ = $1; - $$.defarg = $2.rawval ? $2.rawval : $2.val; - } - | abstract_declarator def_args { - $$ = $1; - $$.defarg = $2.rawval ? $2.rawval : $2.val; - } - | def_args { - $$.type = 0; - $$.id = 0; - $$.defarg = $1.rawval ? $1.rawval : $1.val; - } - /* Member function pointers with qualifiers. eg. - int f(short (Funcs::*parm)(bool) const); */ - | direct_declarator LPAREN parms RPAREN cv_ref_qualifier { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_function(t,$3); - if ($5.qualifier) - SwigType_push(t, $5.qualifier); - if (!$$.have_parms) { - $$.parms = $3; - $$.have_parms = 1; - } - if (!$$.type) { - $$.type = t; - } else { - SwigType_push(t, $$.type); - Delete($$.type); - $$.type = t; - } - $$.defarg = 0; - } - ; - -plain_declarator : declarator { - $$ = $1; - if (SwigType_isfunction($1.type)) { - Delete(SwigType_pop_function($1.type)); - } else if (SwigType_isarray($1.type)) { - SwigType *ta = SwigType_pop_arrays($1.type); - if (SwigType_isfunction($1.type)) { - Delete(SwigType_pop_function($1.type)); - } else { - $$.parms = 0; - } - SwigType_push($1.type,ta); - Delete(ta); - } else { - $$.parms = 0; - } - } - | abstract_declarator { - $$ = $1; - if (SwigType_isfunction($1.type)) { - Delete(SwigType_pop_function($1.type)); - } else if (SwigType_isarray($1.type)) { - SwigType *ta = SwigType_pop_arrays($1.type); - if (SwigType_isfunction($1.type)) { - Delete(SwigType_pop_function($1.type)); - } else { - $$.parms = 0; - } - SwigType_push($1.type,ta); - Delete(ta); - } else { - $$.parms = 0; - } - } - /* Member function pointers with qualifiers. eg. - int f(short (Funcs::*parm)(bool) const) */ - | direct_declarator LPAREN parms RPAREN cv_ref_qualifier { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_function(t, $3); - if ($5.qualifier) - SwigType_push(t, $5.qualifier); - if (!$$.have_parms) { - $$.parms = $3; - $$.have_parms = 1; - } - if (!$$.type) { - $$.type = t; - } else { - SwigType_push(t, $$.type); - Delete($$.type); - $$.type = t; - } - } - | empty { - $$.type = 0; - $$.id = 0; - $$.parms = 0; - } - ; - -declarator : pointer notso_direct_declarator { - $$ = $2; - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - | pointer AND notso_direct_declarator { - $$ = $3; - SwigType_add_reference($1); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - | pointer LAND notso_direct_declarator { - $$ = $3; - SwigType_add_rvalue_reference($1); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - | direct_declarator { - $$ = $1; - if (!$$.type) $$.type = NewStringEmpty(); - } - | AND notso_direct_declarator { - $$ = $2; - $$.type = NewStringEmpty(); - SwigType_add_reference($$.type); - if ($2.type) { - SwigType_push($$.type,$2.type); - Delete($2.type); - } - } - | LAND notso_direct_declarator { - /* Introduced in C++11, move operator && */ - /* Adds one S/R conflict */ - $$ = $2; - $$.type = NewStringEmpty(); - SwigType_add_rvalue_reference($$.type); - if ($2.type) { - SwigType_push($$.type,$2.type); - Delete($2.type); - } - } - | idcolon DSTAR notso_direct_declarator { - SwigType *t = NewStringEmpty(); - - $$ = $3; - SwigType_add_memberpointer(t,$1); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - | pointer idcolon DSTAR notso_direct_declarator { - SwigType *t = NewStringEmpty(); - $$ = $4; - SwigType_add_memberpointer(t,$2); - SwigType_push($1,t); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - Delete(t); - } - | pointer idcolon DSTAR AND notso_direct_declarator { - $$ = $5; - SwigType_add_memberpointer($1,$2); - SwigType_add_reference($1); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - | idcolon DSTAR AND notso_direct_declarator { - SwigType *t = NewStringEmpty(); - $$ = $4; - SwigType_add_memberpointer(t,$1); - SwigType_add_reference(t); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - - /* Variadic versions eg. MyClasses&... myIds */ - - | pointer ELLIPSIS notso_direct_declarator { - $$ = $3; - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - | pointer AND ELLIPSIS notso_direct_declarator { - $$ = $4; - SwigType_add_reference($1); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - | pointer LAND ELLIPSIS notso_direct_declarator { - $$ = $4; - SwigType_add_rvalue_reference($1); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - | ELLIPSIS direct_declarator { - $$ = $2; - if (!$$.type) $$.type = NewStringEmpty(); - } - | AND ELLIPSIS notso_direct_declarator { - $$ = $3; - $$.type = NewStringEmpty(); - SwigType_add_reference($$.type); - if ($3.type) { - SwigType_push($$.type,$3.type); - Delete($3.type); - } - } - | LAND ELLIPSIS notso_direct_declarator { - /* Introduced in C++11, move operator && */ - /* Adds one S/R conflict */ - $$ = $3; - $$.type = NewStringEmpty(); - SwigType_add_rvalue_reference($$.type); - if ($3.type) { - SwigType_push($$.type,$3.type); - Delete($3.type); - } - } - | idcolon DSTAR ELLIPSIS notso_direct_declarator { - SwigType *t = NewStringEmpty(); - - $$ = $4; - SwigType_add_memberpointer(t,$1); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - | pointer idcolon DSTAR ELLIPSIS notso_direct_declarator { - SwigType *t = NewStringEmpty(); - $$ = $5; - SwigType_add_memberpointer(t,$2); - SwigType_push($1,t); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - Delete(t); - } - | pointer idcolon DSTAR AND ELLIPSIS notso_direct_declarator { - $$ = $6; - SwigType_add_memberpointer($1,$2); - SwigType_add_reference($1); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - | pointer idcolon DSTAR LAND ELLIPSIS notso_direct_declarator { - $$ = $6; - SwigType_add_memberpointer($1,$2); - SwigType_add_rvalue_reference($1); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - | idcolon DSTAR AND ELLIPSIS notso_direct_declarator { - SwigType *t = NewStringEmpty(); - $$ = $5; - SwigType_add_memberpointer(t,$1); - SwigType_add_reference(t); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - | idcolon DSTAR LAND ELLIPSIS notso_direct_declarator { - SwigType *t = NewStringEmpty(); - $$ = $5; - SwigType_add_memberpointer(t,$1); - SwigType_add_rvalue_reference(t); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - ; - -notso_direct_declarator : idcolon { - /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */ - $$.id = Char($1); - $$.type = 0; - $$.parms = 0; - $$.have_parms = 0; - } - | NOT idcolon { - $$.id = Char(NewStringf("~%s",$2)); - $$.type = 0; - $$.parms = 0; - $$.have_parms = 0; - } - -/* This generates a shift-reduce conflict with constructors */ - | LPAREN idcolon RPAREN { - $$.id = Char($2); - $$.type = 0; - $$.parms = 0; - $$.have_parms = 0; - } - -/* - | LPAREN AND idcolon RPAREN { - $$.id = Char($3); - $$.type = 0; - $$.parms = 0; - $$.have_parms = 0; - } -*/ -/* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */ - | LPAREN pointer notso_direct_declarator RPAREN { - $$ = $3; - if ($$.type) { - SwigType_push($2,$$.type); - Delete($$.type); - } - $$.type = $2; - } - | LPAREN idcolon DSTAR notso_direct_declarator RPAREN { - SwigType *t; - $$ = $4; - t = NewStringEmpty(); - SwigType_add_memberpointer(t,$2); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - | notso_direct_declarator LBRACKET RBRACKET { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_array(t,""); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - | notso_direct_declarator LBRACKET expr RBRACKET { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_array(t,$3.val); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - | notso_direct_declarator LPAREN parms RPAREN { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_function(t,$3); - if (!$$.have_parms) { - $$.parms = $3; - $$.have_parms = 1; - } - if (!$$.type) { - $$.type = t; - } else { - SwigType_push(t, $$.type); - Delete($$.type); - $$.type = t; - } - } - ; - -direct_declarator : idcolon { - /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */ - $$.id = Char($1); - $$.type = 0; - $$.parms = 0; - $$.have_parms = 0; - } - - | NOT idcolon { - $$.id = Char(NewStringf("~%s",$2)); - $$.type = 0; - $$.parms = 0; - $$.have_parms = 0; - } - -/* This generate a shift-reduce conflict with constructors */ -/* - | LPAREN idcolon RPAREN { - $$.id = Char($2); - $$.type = 0; - $$.parms = 0; - $$.have_parms = 0; - } -*/ -/* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */ - | LPAREN pointer direct_declarator RPAREN { - $$ = $3; - if ($$.type) { - SwigType_push($2,$$.type); - Delete($$.type); - } - $$.type = $2; - } - | LPAREN AND direct_declarator RPAREN { - $$ = $3; - if (!$$.type) { - $$.type = NewStringEmpty(); - } - SwigType_add_reference($$.type); - } - | LPAREN LAND direct_declarator RPAREN { - $$ = $3; - if (!$$.type) { - $$.type = NewStringEmpty(); - } - SwigType_add_rvalue_reference($$.type); - } - | LPAREN idcolon DSTAR declarator RPAREN { - SwigType *t; - $$ = $4; - t = NewStringEmpty(); - SwigType_add_memberpointer(t,$2); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - | LPAREN idcolon DSTAR type_qualifier declarator RPAREN { - SwigType *t; - $$ = $5; - t = NewStringEmpty(); - SwigType_add_memberpointer(t, $2); - SwigType_push(t, $4); - if ($$.type) { - SwigType_push(t, $$.type); - Delete($$.type); - } - $$.type = t; - } - | LPAREN idcolon DSTAR abstract_declarator RPAREN { - SwigType *t; - $$ = $4; - t = NewStringEmpty(); - SwigType_add_memberpointer(t, $2); - if ($$.type) { - SwigType_push(t, $$.type); - Delete($$.type); - } - $$.type = t; - } - | LPAREN idcolon DSTAR type_qualifier abstract_declarator RPAREN { - SwigType *t; - $$ = $5; - t = NewStringEmpty(); - SwigType_add_memberpointer(t, $2); - SwigType_push(t, $4); - if ($$.type) { - SwigType_push(t, $$.type); - Delete($$.type); - } - $$.type = t; - } - | direct_declarator LBRACKET RBRACKET { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_array(t,""); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - | direct_declarator LBRACKET expr RBRACKET { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_array(t,$3.val); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - | direct_declarator LPAREN parms RPAREN { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_function(t,$3); - if (!$$.have_parms) { - $$.parms = $3; - $$.have_parms = 1; - } - if (!$$.type) { - $$.type = t; - } else { - SwigType_push(t, $$.type); - Delete($$.type); - $$.type = t; - } - } - /* User-defined string literals. eg. - int operator"" _mySuffix(const char* val, int length) {...} */ - /* This produces one S/R conflict. */ - | OPERATOR ID LPAREN parms RPAREN { - SwigType *t; - Append($1, " "); /* intervening space is mandatory */ - Append($1, Char($2)); - $$.id = Char($1); - t = NewStringEmpty(); - SwigType_add_function(t,$4); - if (!$$.have_parms) { - $$.parms = $4; - $$.have_parms = 1; - } - if (!$$.type) { - $$.type = t; - } else { - SwigType_push(t, $$.type); - Delete($$.type); - $$.type = t; - } - } - ; - -abstract_declarator : pointer { - $$.type = $1; - $$.id = 0; - $$.parms = 0; - $$.have_parms = 0; - } - | pointer direct_abstract_declarator { - $$ = $2; - SwigType_push($1,$2.type); - $$.type = $1; - Delete($2.type); - } - | pointer AND { - $$.type = $1; - SwigType_add_reference($$.type); - $$.id = 0; - $$.parms = 0; - $$.have_parms = 0; - } - | pointer LAND { - $$.type = $1; - SwigType_add_rvalue_reference($$.type); - $$.id = 0; - $$.parms = 0; - $$.have_parms = 0; - } - | pointer AND direct_abstract_declarator { - $$ = $3; - SwigType_add_reference($1); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - | pointer LAND direct_abstract_declarator { - $$ = $3; - SwigType_add_rvalue_reference($1); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - | direct_abstract_declarator { - $$ = $1; - } - | AND direct_abstract_declarator { - $$ = $2; - $$.type = NewStringEmpty(); - SwigType_add_reference($$.type); - if ($2.type) { - SwigType_push($$.type,$2.type); - Delete($2.type); - } - } - | LAND direct_abstract_declarator { - $$ = $2; - $$.type = NewStringEmpty(); - SwigType_add_rvalue_reference($$.type); - if ($2.type) { - SwigType_push($$.type,$2.type); - Delete($2.type); - } - } - | AND { - $$.id = 0; - $$.parms = 0; - $$.have_parms = 0; - $$.type = NewStringEmpty(); - SwigType_add_reference($$.type); - } - | LAND { - $$.id = 0; - $$.parms = 0; - $$.have_parms = 0; - $$.type = NewStringEmpty(); - SwigType_add_rvalue_reference($$.type); - } - | idcolon DSTAR { - $$.type = NewStringEmpty(); - SwigType_add_memberpointer($$.type,$1); - $$.id = 0; - $$.parms = 0; - $$.have_parms = 0; - } - | idcolon DSTAR type_qualifier { - $$.type = NewStringEmpty(); - SwigType_add_memberpointer($$.type, $1); - SwigType_push($$.type, $3); - $$.id = 0; - $$.parms = 0; - $$.have_parms = 0; - } - | pointer idcolon DSTAR { - SwigType *t = NewStringEmpty(); - $$.type = $1; - $$.id = 0; - $$.parms = 0; - $$.have_parms = 0; - SwigType_add_memberpointer(t,$2); - SwigType_push($$.type,t); - Delete(t); - } - | pointer idcolon DSTAR direct_abstract_declarator { - $$ = $4; - SwigType_add_memberpointer($1,$2); - if ($$.type) { - SwigType_push($1,$$.type); - Delete($$.type); - } - $$.type = $1; - } - ; - -direct_abstract_declarator : direct_abstract_declarator LBRACKET RBRACKET { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_array(t,""); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - | direct_abstract_declarator LBRACKET expr RBRACKET { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_array(t,$3.val); - if ($$.type) { - SwigType_push(t,$$.type); - Delete($$.type); - } - $$.type = t; - } - | LBRACKET RBRACKET { - $$.type = NewStringEmpty(); - $$.id = 0; - $$.parms = 0; - $$.have_parms = 0; - SwigType_add_array($$.type,""); - } - | LBRACKET expr RBRACKET { - $$.type = NewStringEmpty(); - $$.id = 0; - $$.parms = 0; - $$.have_parms = 0; - SwigType_add_array($$.type,$2.val); - } - | LPAREN abstract_declarator RPAREN { - $$ = $2; - } - | direct_abstract_declarator LPAREN parms RPAREN { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_function(t,$3); - if (!$$.type) { - $$.type = t; - } else { - SwigType_push(t,$$.type); - Delete($$.type); - $$.type = t; - } - if (!$$.have_parms) { - $$.parms = $3; - $$.have_parms = 1; - } - } - | direct_abstract_declarator LPAREN parms RPAREN cv_ref_qualifier { - SwigType *t; - $$ = $1; - t = NewStringEmpty(); - SwigType_add_function(t,$3); - SwigType_push(t, $5.qualifier); - if (!$$.type) { - $$.type = t; - } else { - SwigType_push(t,$$.type); - Delete($$.type); - $$.type = t; - } - if (!$$.have_parms) { - $$.parms = $3; - $$.have_parms = 1; - } - } - | LPAREN parms RPAREN { - $$.type = NewStringEmpty(); - SwigType_add_function($$.type,$2); - $$.parms = $2; - $$.have_parms = 1; - $$.id = 0; - } - ; - - -pointer : STAR type_qualifier pointer { - $$ = NewStringEmpty(); - SwigType_add_pointer($$); - SwigType_push($$,$2); - SwigType_push($$,$3); - Delete($3); - } - | STAR pointer { - $$ = NewStringEmpty(); - SwigType_add_pointer($$); - SwigType_push($$,$2); - Delete($2); - } - | STAR type_qualifier { - $$ = NewStringEmpty(); - SwigType_add_pointer($$); - SwigType_push($$,$2); - } - | STAR { - $$ = NewStringEmpty(); - SwigType_add_pointer($$); - } - ; - -/* cv-qualifier plus C++11 ref-qualifier for non-static member functions */ -cv_ref_qualifier : type_qualifier { - $$.qualifier = $1; - $$.refqualifier = 0; - } - | type_qualifier ref_qualifier { - $$.qualifier = $1; - $$.refqualifier = $2; - SwigType_push($$.qualifier, $2); - } - | ref_qualifier { - $$.qualifier = NewStringEmpty(); - $$.refqualifier = $1; - SwigType_push($$.qualifier, $1); - } - ; - -ref_qualifier : AND { - $$ = NewStringEmpty(); - SwigType_add_reference($$); - } - | LAND { - $$ = NewStringEmpty(); - SwigType_add_rvalue_reference($$); - } - ; - -type_qualifier : type_qualifier_raw { - $$ = NewStringEmpty(); - if ($1) SwigType_add_qualifier($$,$1); - } - | type_qualifier_raw type_qualifier { - $$ = $2; - if ($1) SwigType_add_qualifier($$,$1); - } - ; - -type_qualifier_raw : CONST_QUAL { $$ = "const"; } - | VOLATILE { $$ = "volatile"; } - | REGISTER { $$ = 0; } - ; - -/* Data type must be a built in type or an identifier for user-defined types - This type can be preceded by a modifier. */ - -type : rawtype { - $$ = $1; - Replace($$,"typename ","", DOH_REPLACE_ANY); - } - ; - -rawtype : type_qualifier type_right { - $$ = $2; - SwigType_push($$,$1); - } - | type_right { $$ = $1; } - | type_right type_qualifier { - $$ = $1; - SwigType_push($$,$2); - } - | type_qualifier type_right type_qualifier { - $$ = $2; - SwigType_push($$,$3); - SwigType_push($$,$1); - } - ; - -type_right : primitive_type { $$ = $1; - /* Printf(stdout,"primitive = '%s'\n", $$);*/ - } - | TYPE_BOOL { $$ = $1; } - | TYPE_VOID { $$ = $1; } -/* - | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); } -*/ - | c_enum_key idcolon { $$ = NewStringf("enum %s", $2); } - | TYPE_RAW { $$ = $1; } - - | idcolon { - $$ = $1; - } - | cpptype idcolon { - $$ = NewStringf("%s %s", $1, $2); - } - | decltype { - $$ = $1; - } - ; - -decltype : DECLTYPE LPAREN idcolon RPAREN { - Node *n = Swig_symbol_clookup($3,0); - if (!n) { - Swig_error(cparse_file, cparse_line, "Identifier %s not defined.\n", $3); - $$ = $3; - } else { - $$ = Getattr(n, "type"); - } - } - ; - -primitive_type : primitive_type_list { - if (!$1.type) $1.type = NewString("int"); - if ($1.us) { - $$ = NewStringf("%s %s", $1.us, $1.type); - Delete($1.us); - Delete($1.type); - } else { - $$ = $1.type; - } - if (Cmp($$,"signed int") == 0) { - Delete($$); - $$ = NewString("int"); - } else if (Cmp($$,"signed long") == 0) { - Delete($$); - $$ = NewString("long"); - } else if (Cmp($$,"signed short") == 0) { - Delete($$); - $$ = NewString("short"); - } else if (Cmp($$,"signed long long") == 0) { - Delete($$); - $$ = NewString("long long"); - } - } - ; - -primitive_type_list : type_specifier { - $$ = $1; - } - | type_specifier primitive_type_list { - if ($1.us && $2.us) { - Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $2.us); - } - $$ = $2; - if ($1.us) $$.us = $1.us; - if ($1.type) { - if (!$2.type) $$.type = $1.type; - else { - int err = 0; - if ((Cmp($1.type,"long") == 0)) { - if ((Cmp($2.type,"long") == 0) || (Strncmp($2.type,"double",6) == 0)) { - $$.type = NewStringf("long %s", $2.type); - } else if (Cmp($2.type,"int") == 0) { - $$.type = $1.type; - } else { - err = 1; - } - } else if ((Cmp($1.type,"short")) == 0) { - if (Cmp($2.type,"int") == 0) { - $$.type = $1.type; - } else { - err = 1; - } - } else if (Cmp($1.type,"int") == 0) { - $$.type = $2.type; - } else if (Cmp($1.type,"double") == 0) { - if (Cmp($2.type,"long") == 0) { - $$.type = NewString("long double"); - } else if (Cmp($2.type,"_Complex") == 0) { - $$.type = NewString("double _Complex"); - } else { - err = 1; - } - } else if (Cmp($1.type,"float") == 0) { - if (Cmp($2.type,"_Complex") == 0) { - $$.type = NewString("float _Complex"); - } else { - err = 1; - } - } else if (Cmp($1.type,"_Complex") == 0) { - $$.type = NewStringf("%s _Complex", $2.type); - } else { - err = 1; - } - if (err) { - Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $1.type); - } - } - } - } - ; - - -type_specifier : TYPE_INT { - $$.type = NewString("int"); - $$.us = 0; - } - | TYPE_SHORT { - $$.type = NewString("short"); - $$.us = 0; - } - | TYPE_LONG { - $$.type = NewString("long"); - $$.us = 0; - } - | TYPE_CHAR { - $$.type = NewString("char"); - $$.us = 0; - } - | TYPE_WCHAR { - $$.type = NewString("wchar_t"); - $$.us = 0; - } - | TYPE_FLOAT { - $$.type = NewString("float"); - $$.us = 0; - } - | TYPE_DOUBLE { - $$.type = NewString("double"); - $$.us = 0; - } - | TYPE_SIGNED { - $$.us = NewString("signed"); - $$.type = 0; - } - | TYPE_UNSIGNED { - $$.us = NewString("unsigned"); - $$.type = 0; - } - | TYPE_COMPLEX { - $$.type = NewString("_Complex"); - $$.us = 0; - } - | TYPE_NON_ISO_INT8 { - $$.type = NewString("__int8"); - $$.us = 0; - } - | TYPE_NON_ISO_INT16 { - $$.type = NewString("__int16"); - $$.us = 0; - } - | TYPE_NON_ISO_INT32 { - $$.type = NewString("__int32"); - $$.us = 0; - } - | TYPE_NON_ISO_INT64 { - $$.type = NewString("__int64"); - $$.us = 0; - } - ; - -definetype : { /* scanner_check_typedef(); */ } expr { - $$ = $2; - if ($$.type == T_STRING) { - $$.rawval = NewStringf("\"%(escape)s\"",$$.val); - } else if ($$.type != T_CHAR && $$.type != T_WSTRING && $$.type != T_WCHAR) { - $$.rawval = NewStringf("%s", $$.val); - } - $$.qualifier = 0; - $$.refqualifier = 0; - $$.bitfield = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - scanner_ignore_typedef(); - } - | default_delete { - $$ = $1; - } - ; - -default_delete : deleted_definition { - $$ = $1; - } - | explicit_default { - $$ = $1; - } - ; - -/* For C++ deleted definition '= delete' */ -deleted_definition : DELETE_KW { - $$.val = NewString("delete"); - $$.rawval = 0; - $$.type = T_STRING; - $$.qualifier = 0; - $$.refqualifier = 0; - $$.bitfield = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } - ; - -/* For C++ explicitly defaulted functions '= default' */ -explicit_default : DEFAULT { - $$.val = NewString("default"); - $$.rawval = 0; - $$.type = T_STRING; - $$.qualifier = 0; - $$.refqualifier = 0; - $$.bitfield = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } - ; - -/* Some stuff for handling enums */ - -ename : identifier { $$ = $1; } - | empty { $$ = (char *) 0;} - ; - -constant_directives : constant_directive - | constant_directive constant_directives - ; - -optional_ignored_defines - : constant_directives - | empty - ; - -/* Enum lists - any #define macros (constant directives) within the enum list are ignored. Trailing commas accepted. */ - -/* - Note that "_last" attribute is not supposed to be set on the last enum element, as might be expected from its name, but on the _first_ one, and _only_ on it, - so we propagate it back to the first item while parsing and reset it on all the subsequent ones. - */ - -enumlist : enumlist_item { - Setattr($1,"_last",$1); - $$ = $1; - } - | enumlist_item DOXYGENPOSTSTRING { - Setattr($1,"_last",$1); - set_comment($1, $2); - $$ = $1; - } - | enumlist_item COMMA enumlist { - if ($3) { - set_nextSibling($1, $3); - Setattr($1,"_last",Getattr($3,"_last")); - Setattr($3,"_last",NULL); - } else { - Setattr($1,"_last",$1); - } - $$ = $1; - } - | enumlist_item COMMA DOXYGENPOSTSTRING enumlist { - if ($4) { - set_nextSibling($1, $4); - Setattr($1,"_last",Getattr($4,"_last")); - Setattr($4,"_last",NULL); - } else { - Setattr($1,"_last",$1); - } - set_comment($1, $3); - $$ = $1; - } - | optional_ignored_defines { - $$ = 0; - } - ; - -enumlist_item : optional_ignored_defines edecl_with_dox optional_ignored_defines { - $$ = $2; - } - ; - -edecl_with_dox : edecl { - $$ = $1; - } - | DOXYGENSTRING edecl { - $$ = $2; - set_comment($2, $1); - } - ; - -edecl : identifier { - SwigType *type = NewSwigType(T_INT); - $$ = new_node("enumitem"); - Setattr($$,"name",$1); - Setattr($$,"type",type); - SetFlag($$,"feature:immutable"); - Delete(type); - } - | identifier EQUAL etype { - SwigType *type = NewSwigType($3.type == T_BOOL ? T_BOOL : ($3.type == T_CHAR ? T_CHAR : T_INT)); - $$ = new_node("enumitem"); - Setattr($$,"name",$1); - Setattr($$,"type",type); - SetFlag($$,"feature:immutable"); - Setattr($$,"enumvalue", $3.val); - Setattr($$,"value",$1); - Delete(type); - } - ; - -etype : expr { - $$ = $1; - if (($$.type != T_INT) && ($$.type != T_UINT) && - ($$.type != T_LONG) && ($$.type != T_ULONG) && - ($$.type != T_LONGLONG) && ($$.type != T_ULONGLONG) && - ($$.type != T_SHORT) && ($$.type != T_USHORT) && - ($$.type != T_SCHAR) && ($$.type != T_UCHAR) && - ($$.type != T_CHAR) && ($$.type != T_BOOL)) { - Swig_error(cparse_file,cparse_line,"Type error. Expecting an integral type\n"); - } - } - ; - -/* Arithmetic expressions. Used for constants, C++ templates, and other cool stuff. */ - -expr : valexpr { $$ = $1; } - | type { - Node *n; - $$.val = $1; - $$.type = T_INT; - /* Check if value is in scope */ - n = Swig_symbol_clookup($1,0); - if (n) { - /* A band-aid for enum values used in expressions. */ - if (Strcmp(nodeType(n),"enumitem") == 0) { - String *q = Swig_symbol_qualified(n); - if (q) { - $$.val = NewStringf("%s::%s", q, Getattr(n,"name")); - Delete(q); - } - } - } - } - ; - -/* simple member access expressions */ -exprmem : ID ARROW ID { - $$.val = NewStringf("%s->%s", $1, $3); - $$.type = 0; - } - | ID ARROW ID LPAREN callparms RPAREN { - $$.val = NewStringf("%s->%s(%s)", $1, $3, $5.val); - $$.type = 0; - } - | exprmem ARROW ID { - $$ = $1; - Printf($$.val, "->%s", $3); - } - | exprmem ARROW ID LPAREN callparms RPAREN { - $$ = $1; - Printf($$.val, "->%s(%s)", $3, $5.val); - } - | ID PERIOD ID { - $$.val = NewStringf("%s.%s", $1, $3); - $$.type = 0; - } - | ID PERIOD ID LPAREN callparms RPAREN { - $$.val = NewStringf("%s.%s(%s)", $1, $3, $5.val); - $$.type = 0; - } - | exprmem PERIOD ID { - $$ = $1; - Printf($$.val, ".%s", $3); - } - | exprmem PERIOD ID LPAREN callparms RPAREN { - $$ = $1; - Printf($$.val, ".%s(%s)", $3, $5.val); - } - ; - -/* Non-compound expression */ -exprsimple : exprnum { - $$ = $1; - } - | exprmem { - $$ = $1; - } - | string { - $$.val = $1; - $$.type = T_STRING; - } - | SIZEOF LPAREN type parameter_declarator RPAREN { - SwigType_push($3,$4.type); - $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0)); - $$.type = T_ULONG; - } - | SIZEOF ELLIPSIS LPAREN type parameter_declarator RPAREN { - SwigType_push($4,$5.type); - $$.val = NewStringf("sizeof...(%s)",SwigType_str($4,0)); - $$.type = T_ULONG; - } - /* We don't support all valid expressions here currently - e.g. - * sizeof(<unaryop> x) doesn't work - but those are unlikely to - * be seen in real code. - * - * Note: sizeof(x) is not handled here, but instead by the rule - * for sizeof(<type>) because it matches that syntactically. - */ - | SIZEOF LPAREN exprsimple RPAREN { - $$.val = NewStringf("sizeof(%s)", $3.val); - $$.type = T_ULONG; - } - /* `sizeof expr` without parentheses is valid for an expression, - * but not for a type. This doesn't support `sizeof x` in - * addition to the case not supported above. - */ - | SIZEOF exprsimple { - $$.val = NewStringf("sizeof(%s)", $2.val); - $$.type = T_ULONG; - } - | wstring { - $$.val = $1; - $$.rawval = NewStringf("L\"%s\"", $$.val); - $$.type = T_WSTRING; - } - | CHARCONST { - $$.val = NewString($1); - if (Len($$.val)) { - $$.rawval = NewStringf("'%(escape)s'", $$.val); - } else { - $$.rawval = NewString("'\\0'"); - } - $$.type = T_CHAR; - $$.bitfield = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } - | WCHARCONST { - $$.val = NewString($1); - if (Len($$.val)) { - $$.rawval = NewStringf("L\'%s\'", $$.val); - } else { - $$.rawval = NewString("L'\\0'"); - } - $$.type = T_WCHAR; - $$.bitfield = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } - - ; - -valexpr : exprsimple { $$ = $1; } - | exprcompound { $$ = $1; } - -/* grouping */ - | LPAREN expr RPAREN %prec CAST { - $$.val = NewStringf("(%s)",$2.val); - if ($2.rawval) { - $$.rawval = NewStringf("(%s)",$2.rawval); - } - $$.type = $2.type; - } - -/* A few common casting operations */ - - | LPAREN expr RPAREN expr %prec CAST { - $$ = $4; - if ($4.type != T_STRING) { - switch ($2.type) { - case T_FLOAT: - case T_DOUBLE: - case T_LONGDOUBLE: - case T_FLTCPLX: - case T_DBLCPLX: - $$.val = NewStringf("(%s)%s", $2.val, $4.val); /* SwigType_str and decimal points don't mix! */ - break; - default: - $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $4.val); - break; - } - } - $$.type = promote($2.type, $4.type); - } - | LPAREN expr pointer RPAREN expr %prec CAST { - $$ = $5; - if ($5.type != T_STRING) { - SwigType_push($2.val,$3); - $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); - } - } - | LPAREN expr AND RPAREN expr %prec CAST { - $$ = $5; - if ($5.type != T_STRING) { - SwigType_add_reference($2.val); - $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); - } - } - | LPAREN expr LAND RPAREN expr %prec CAST { - $$ = $5; - if ($5.type != T_STRING) { - SwigType_add_rvalue_reference($2.val); - $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); - } - } - | LPAREN expr pointer AND RPAREN expr %prec CAST { - $$ = $6; - if ($6.type != T_STRING) { - SwigType_push($2.val,$3); - SwigType_add_reference($2.val); - $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val); - } - } - | LPAREN expr pointer LAND RPAREN expr %prec CAST { - $$ = $6; - if ($6.type != T_STRING) { - SwigType_push($2.val,$3); - SwigType_add_rvalue_reference($2.val); - $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val); - } - } - | AND expr { - $$ = $2; - $$.val = NewStringf("&%s",$2.val); - } - | STAR expr { - $$ = $2; - $$.val = NewStringf("*%s",$2.val); - } - ; - -exprnum : NUM_INT { $$ = $1; } - | NUM_FLOAT { $$ = $1; } - | NUM_UNSIGNED { $$ = $1; } - | NUM_LONG { $$ = $1; } - | NUM_ULONG { $$ = $1; } - | NUM_LONGLONG { $$ = $1; } - | NUM_ULONGLONG { $$ = $1; } - | NUM_BOOL { $$ = $1; } - ; - -exprcompound : expr PLUS expr { - $$.val = NewStringf("%s+%s", COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = promote($1.type,$3.type); - } - | expr MINUS expr { - $$.val = NewStringf("%s-%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = promote($1.type,$3.type); - } - | expr STAR expr { - $$.val = NewStringf("%s*%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = promote($1.type,$3.type); - } - | expr SLASH expr { - $$.val = NewStringf("%s/%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = promote($1.type,$3.type); - } - | expr MODULO expr { - $$.val = NewStringf("%s%%%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = promote($1.type,$3.type); - } - | expr AND expr { - $$.val = NewStringf("%s&%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = promote($1.type,$3.type); - } - | expr OR expr { - $$.val = NewStringf("%s|%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = promote($1.type,$3.type); - } - | expr XOR expr { - $$.val = NewStringf("%s^%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = promote($1.type,$3.type); - } - | expr LSHIFT expr { - $$.val = NewStringf("%s << %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = promote_type($1.type); - } - | expr RSHIFT expr { - $$.val = NewStringf("%s >> %s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = promote_type($1.type); - } - | expr LAND expr { - $$.val = NewStringf("%s&&%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = cparse_cplusplus ? T_BOOL : T_INT; - } - | expr LOR expr { - $$.val = NewStringf("%s||%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = cparse_cplusplus ? T_BOOL : T_INT; - } - | expr EQUALTO expr { - $$.val = NewStringf("%s==%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = cparse_cplusplus ? T_BOOL : T_INT; - } - | expr NOTEQUALTO expr { - $$.val = NewStringf("%s!=%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3)); - $$.type = cparse_cplusplus ? T_BOOL : T_INT; - } - /* Trying to parse `>` in the general case results in conflicts - * in the parser, but all user-reported cases are actually inside - * parentheses and we can handle that case. - */ - | LPAREN expr GREATERTHAN expr RPAREN { - $$.val = NewStringf("%s > %s", COMPOUND_EXPR_VAL($2), COMPOUND_EXPR_VAL($4)); - $$.type = cparse_cplusplus ? T_BOOL : T_INT; - } - - /* Similarly for `<` except trying to handle exprcompound on the - * left side gives a shift/reduce conflict, so also restrict - * handling to non-compound subexpressions there. Again this - * covers all user-reported cases. - */ - | LPAREN exprsimple LESSTHAN expr RPAREN { - $$.val = NewStringf("%s < %s", COMPOUND_EXPR_VAL($2), COMPOUND_EXPR_VAL($4)); - $$.type = cparse_cplusplus ? T_BOOL : T_INT; - } - | expr GREATERTHANOREQUALTO expr { - $$.val = NewStringf("%s >= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3)); - $$.type = cparse_cplusplus ? T_BOOL : T_INT; - } - | expr LESSTHANOREQUALTO expr { - $$.val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3)); - $$.type = cparse_cplusplus ? T_BOOL : T_INT; - } - | expr LESSEQUALGREATER expr { - $$.val = NewStringf("%s <=> %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3)); - /* Really `<=>` returns one of `std::strong_ordering`, - * `std::partial_ordering` or `std::weak_ordering`, but we - * fake it by treating the return value as `int`. The main - * thing to do with the return value in this context is to - * compare it with 0, for which `int` does the job. */ - $$.type = T_INT; - } - | expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK { - $$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3), COMPOUND_EXPR_VAL($5)); - /* This may not be exactly right, but is probably good enough - * for the purposes of parsing constant expressions. */ - $$.type = promote($3.type, $5.type); - } - | MINUS expr %prec UMINUS { - $$.val = NewStringf("-%s",$2.val); - $$.type = $2.type; - } - | PLUS expr %prec UMINUS { - $$.val = NewStringf("+%s",$2.val); - $$.type = $2.type; - } - | NOT expr { - $$.val = NewStringf("~%s",$2.val); - $$.type = $2.type; - } - | LNOT expr { - $$.val = NewStringf("!%s",COMPOUND_EXPR_VAL($2)); - $$.type = T_INT; - } - | type LPAREN { - String *qty; - skip_balanced('(',')'); - qty = Swig_symbol_type_qualify($1,0); - if (SwigType_istemplate(qty)) { - String *nstr = SwigType_namestr(qty); - Delete(qty); - qty = nstr; - } - $$.val = NewStringf("%s%s",qty,scanner_ccode); - Clear(scanner_ccode); - $$.type = T_INT; - Delete(qty); - } - ; - -variadic : ELLIPSIS { - $$ = NewString("..."); - } - | empty { - $$ = 0; - } - ; - -inherit : raw_inherit { - $$ = $1; - } - ; - -raw_inherit : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list = 0; } - | empty { $$ = 0; } - ; - -base_list : base_specifier { - Hash *list = NewHash(); - Node *base = $1; - Node *name = Getattr(base,"name"); - List *lpublic = NewList(); - List *lprotected = NewList(); - List *lprivate = NewList(); - Setattr(list,"public",lpublic); - Setattr(list,"protected",lprotected); - Setattr(list,"private",lprivate); - Delete(lpublic); - Delete(lprotected); - Delete(lprivate); - Append(Getattr(list,Getattr(base,"access")),name); - $$ = list; - } - - | base_list COMMA base_specifier { - Hash *list = $1; - Node *base = $3; - Node *name = Getattr(base,"name"); - Append(Getattr(list,Getattr(base,"access")),name); - $$ = list; - } - ; - -base_specifier : opt_virtual { - $<intvalue>$ = cparse_line; - } idcolon variadic { - $$ = NewHash(); - Setfile($$,cparse_file); - Setline($$,$<intvalue>2); - Setattr($$,"name",$3); - Setfile($3,cparse_file); - Setline($3,$<intvalue>2); - if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) { - Setattr($$,"access","private"); - Swig_warning(WARN_PARSE_NO_ACCESS, Getfile($$), Getline($$), "No access specifier given for base class '%s' (ignored).\n", SwigType_namestr($3)); - } else { - Setattr($$,"access","public"); - } - if ($4) - SetFlag($$, "variadic"); - } - | opt_virtual access_specifier { - $<intvalue>$ = cparse_line; - } opt_virtual idcolon variadic { - $$ = NewHash(); - Setfile($$,cparse_file); - Setline($$,$<intvalue>3); - Setattr($$,"name",$5); - Setfile($5,cparse_file); - Setline($5,$<intvalue>3); - Setattr($$,"access",$2); - if (Strcmp($2,"public") != 0) { - Swig_warning(WARN_PARSE_PRIVATE_INHERIT, Getfile($$), Getline($$), "%s inheritance from base '%s' (ignored).\n", $2, SwigType_namestr($5)); - } - if ($6) - SetFlag($$, "variadic"); - } - ; - -access_specifier : PUBLIC { $$ = (char*)"public"; } - | PRIVATE { $$ = (char*)"private"; } - | PROTECTED { $$ = (char*)"protected"; } - ; - -templcpptype : CLASS { - $$ = (char*)"class"; - if (!inherit_list) last_cpptype = $$; - } - | TYPENAME { - $$ = (char *)"typename"; - if (!inherit_list) last_cpptype = $$; - } - | CLASS ELLIPSIS { - $$ = (char *)"class..."; - if (!inherit_list) last_cpptype = $$; - } - | TYPENAME ELLIPSIS { - $$ = (char *)"typename..."; - if (!inherit_list) last_cpptype = $$; - } - ; - -cpptype : templcpptype { - $$ = $1; - } - | STRUCT { - $$ = (char*)"struct"; - if (!inherit_list) last_cpptype = $$; - } - | UNION { - $$ = (char*)"union"; - if (!inherit_list) last_cpptype = $$; - } - ; - -classkey : CLASS { - $$ = (char*)"class"; - if (!inherit_list) last_cpptype = $$; - } - | STRUCT { - $$ = (char*)"struct"; - if (!inherit_list) last_cpptype = $$; - } - | UNION { - $$ = (char*)"union"; - if (!inherit_list) last_cpptype = $$; - } - ; - -classkeyopt : classkey { - $$ = $1; - } - | empty { - $$ = 0; - } - ; - -opt_virtual : VIRTUAL - | empty - ; - -virt_specifier_seq : OVERRIDE { - $$ = 0; - } - | FINAL { - $$ = NewString("1"); - } - | FINAL OVERRIDE { - $$ = NewString("1"); - } - | OVERRIDE FINAL { - $$ = NewString("1"); - } - ; - -virt_specifier_seq_opt : virt_specifier_seq { - $$ = $1; - } - | empty { - $$ = 0; - } - ; - -class_virt_specifier_opt : FINAL { - $$ = NewString("1"); - } - | empty { - $$ = 0; - } - ; - -exception_specification : THROW LPAREN parms RPAREN { - $$.throws = $3; - $$.throwf = NewString("1"); - $$.nexcept = 0; - $$.final = 0; - } - | NOEXCEPT { - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = NewString("true"); - $$.final = 0; - } - | virt_specifier_seq { - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = $1; - } - | THROW LPAREN parms RPAREN virt_specifier_seq { - $$.throws = $3; - $$.throwf = NewString("1"); - $$.nexcept = 0; - $$.final = $5; - } - | NOEXCEPT virt_specifier_seq { - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = NewString("true"); - $$.final = $2; - } - | NOEXCEPT LPAREN expr RPAREN { - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = $3.val; - $$.final = 0; - } - ; - -qualifiers_exception_specification : cv_ref_qualifier { - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - $$.qualifier = $1.qualifier; - $$.refqualifier = $1.refqualifier; - } - | exception_specification { - $$ = $1; - $$.qualifier = 0; - $$.refqualifier = 0; - } - | cv_ref_qualifier exception_specification { - $$ = $2; - $$.qualifier = $1.qualifier; - $$.refqualifier = $1.refqualifier; - } - ; - -cpp_const : qualifiers_exception_specification { - $$ = $1; - } - | empty { - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - $$.qualifier = 0; - $$.refqualifier = 0; - } - ; - -ctor_end : cpp_const ctor_initializer SEMI { - Clear(scanner_ccode); - $$.have_parms = 0; - $$.defarg = 0; - $$.throws = $1.throws; - $$.throwf = $1.throwf; - $$.nexcept = $1.nexcept; - $$.final = $1.final; - if ($1.qualifier) - Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n"); - } - | cpp_const ctor_initializer LBRACE { - skip_balanced('{','}'); - $$.have_parms = 0; - $$.defarg = 0; - $$.throws = $1.throws; - $$.throwf = $1.throwf; - $$.nexcept = $1.nexcept; - $$.final = $1.final; - if ($1.qualifier) - Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n"); - } - | LPAREN parms RPAREN SEMI { - Clear(scanner_ccode); - $$.parms = $2; - $$.have_parms = 1; - $$.defarg = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } - | LPAREN parms RPAREN LBRACE { - skip_balanced('{','}'); - $$.parms = $2; - $$.have_parms = 1; - $$.defarg = 0; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } - | EQUAL definetype SEMI { - $$.have_parms = 0; - $$.defarg = $2.val; - $$.throws = 0; - $$.throwf = 0; - $$.nexcept = 0; - $$.final = 0; - } - | exception_specification EQUAL default_delete SEMI { - $$.have_parms = 0; - $$.defarg = $3.val; - $$.throws = $1.throws; - $$.throwf = $1.throwf; - $$.nexcept = $1.nexcept; - $$.final = $1.final; - if ($1.qualifier) - Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n"); - } - ; - -ctor_initializer : COLON mem_initializer_list - | empty - ; - -mem_initializer_list : mem_initializer - | mem_initializer_list COMMA mem_initializer - | mem_initializer ELLIPSIS - | mem_initializer_list COMMA mem_initializer ELLIPSIS - ; - -mem_initializer : idcolon LPAREN { - skip_balanced('(',')'); - Clear(scanner_ccode); - } - /* Uniform initialization in C++11. - Example: - struct MyStruct { - MyStruct(int x, double y) : x_{x}, y_{y} {} - int x_; - double y_; - }; - */ - | idcolon LBRACE { - skip_balanced('{','}'); - Clear(scanner_ccode); - } - ; - -less_valparms_greater : LESSTHAN valparms GREATERTHAN { - String *s = NewStringEmpty(); - SwigType_add_template(s,$2); - $$ = Char(s); - scanner_last_id(1); - } - ; - -/* Identifiers including the C++11 identifiers with special meaning */ -identifier : ID { $$ = $1; } - | OVERRIDE { $$ = Swig_copy_string("override"); } - | FINAL { $$ = Swig_copy_string("final"); } - ; - -idstring : identifier { $$ = $1; } - | default_delete { $$ = Char($1.val); } - | string { $$ = Char($1); } - ; - -idstringopt : idstring { $$ = $1; } - | empty { $$ = 0; } - ; - -idcolon : idtemplate idcolontail { - $$ = 0; - if (!$$) $$ = NewStringf("%s%s", $1,$2); - Delete($2); - } - | NONID DCOLON idtemplatetemplate idcolontail { - $$ = NewStringf("::%s%s",$3,$4); - Delete($4); - } - | idtemplate { - $$ = NewString($1); - } - | NONID DCOLON idtemplatetemplate { - $$ = NewStringf("::%s",$3); - } - | OPERATOR { - $$ = NewStringf("%s", $1); - } - | OPERATOR less_valparms_greater { - $$ = NewStringf("%s%s", $1, $2); - } - | NONID DCOLON OPERATOR { - $$ = NewStringf("::%s",$3); - } - ; - -idcolontail : DCOLON idtemplatetemplate idcolontail { - $$ = NewStringf("::%s%s",$2,$3); - Delete($3); - } - | DCOLON idtemplatetemplate { - $$ = NewStringf("::%s",$2); - } - | DCOLON OPERATOR { - $$ = NewStringf("::%s",$2); - } -/* | DCOLON CONVERSIONOPERATOR { - $$ = NewString($2); - } */ - - | DCNOT idtemplate { - $$ = NewStringf("::~%s",$2); - } - ; - - -idtemplate : identifier { - $$ = NewStringf("%s", $1); - } - | identifier less_valparms_greater { - $$ = NewStringf("%s%s", $1, $2); - } - ; - -idtemplatetemplate : idtemplate { - $$ = $1; - } - | TEMPLATE identifier less_valparms_greater { - $$ = NewStringf("%s%s", $2, $3); - } - ; - -/* Identifier, but no templates */ -idcolonnt : identifier idcolontailnt { - $$ = 0; - if (!$$) $$ = NewStringf("%s%s", $1,$2); - Delete($2); - } - | NONID DCOLON identifier idcolontailnt { - $$ = NewStringf("::%s%s",$3,$4); - Delete($4); - } - | identifier { - $$ = NewString($1); - } - | NONID DCOLON identifier { - $$ = NewStringf("::%s",$3); - } - | OPERATOR { - $$ = NewString($1); - } - | NONID DCOLON OPERATOR { - $$ = NewStringf("::%s",$3); - } - ; - -idcolontailnt : DCOLON identifier idcolontailnt { - $$ = NewStringf("::%s%s",$2,$3); - Delete($3); - } - | DCOLON identifier { - $$ = NewStringf("::%s",$2); - } - | DCOLON OPERATOR { - $$ = NewStringf("::%s",$2); - } - | DCNOT identifier { - $$ = NewStringf("::~%s",$2); - } - ; - -/* Concatenated strings */ -string : string STRING { - $$ = NewStringf("%s%s", $1, $2); - } - | STRING { $$ = NewString($1);} - ; -/* Concatenated wide strings: L"str1" L"str2" */ -wstring : wstring WSTRING { - $$ = NewStringf("%s%s", $1, $2); - } -/* Concatenated wide string and normal string literal: L"str1" "str2" */ -/*not all the compilers support this concatenation mode, so perhaps better to postpone it*/ - /*| wstring STRING { here $2 comes unescaped, we have to escape it back first via NewStringf("%(escape)s)" - $$ = NewStringf("%s%s", $1, $2); - }*/ - | WSTRING { $$ = NewString($1);} - ; - -stringbrace : string { - $$ = $1; - } - | LBRACE { - skip_balanced('{','}'); - $$ = NewString(scanner_ccode); - } - | HBLOCK { - $$ = $1; - } - ; - -options : LPAREN kwargs RPAREN { - Hash *n; - $$ = NewHash(); - n = $2; - while(n) { - String *name, *value; - name = Getattr(n,"name"); - value = Getattr(n,"value"); - if (!value) value = (String *) "1"; - Setattr($$,name, value); - n = nextSibling(n); - } - } - | empty { $$ = 0; }; - - -/* Keyword arguments */ -kwargs : idstring EQUAL stringnum { - $$ = NewHash(); - Setattr($$,"name",$1); - Setattr($$,"value",$3); - } - | idstring EQUAL stringnum COMMA kwargs { - $$ = NewHash(); - Setattr($$,"name",$1); - Setattr($$,"value",$3); - set_nextSibling($$,$5); - } - | idstring { - $$ = NewHash(); - Setattr($$,"name",$1); - } - | idstring COMMA kwargs { - $$ = NewHash(); - Setattr($$,"name",$1); - set_nextSibling($$,$3); - } - | idstring EQUAL stringtype { - $$ = $3; - Setattr($$,"name",$1); - } - | idstring EQUAL stringtype COMMA kwargs { - $$ = $3; - Setattr($$,"name",$1); - set_nextSibling($$,$5); - } - ; - -stringnum : string { - $$ = $1; - } - | exprnum { - $$ = Char($1.val); - } - ; - -empty : ; - -%% - -SwigType *Swig_cparse_type(String *s) { - String *ns; - ns = NewStringf("%s;",s); - Seek(ns,0,SEEK_SET); - scanner_file(ns); - top = 0; - scanner_next_token(PARSETYPE); - yyparse(); - /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */ - return top; -} - - -Parm *Swig_cparse_parm(String *s) { - String *ns; - ns = NewStringf("%s;",s); - Seek(ns,0,SEEK_SET); - scanner_file(ns); - top = 0; - scanner_next_token(PARSEPARM); - yyparse(); - /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */ - Delete(ns); - return top; -} - - -ParmList *Swig_cparse_parms(String *s, Node *file_line_node) { - String *ns; - char *cs = Char(s); - if (cs && cs[0] != '(') { - ns = NewStringf("(%s);",s); - } else { - ns = NewStringf("%s;",s); - } - Setfile(ns, Getfile(file_line_node)); - Setline(ns, Getline(file_line_node)); - Seek(ns,0,SEEK_SET); - scanner_file(ns); - top = 0; - scanner_next_token(PARSEPARMS); - yyparse(); - /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */ - return top; -} - diff --git a/contrib/tools/swig/Source/CParse/templ.c b/contrib/tools/swig/Source/CParse/templ.c deleted file mode 100644 index 0dec2158692..00000000000 --- a/contrib/tools/swig/Source/CParse/templ.c +++ /dev/null @@ -1,976 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * templ.c - * - * Expands a template into a specialized version. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "cparse.h" - -static int template_debug = 0; - - -const char *baselists[3]; - -void SwigType_template_init(void) { - baselists[0] = "baselist"; - baselists[1] = "protectedbaselist"; - baselists[2] = "privatebaselist"; -} - - -static void add_parms(ParmList *p, List *patchlist, List *typelist, int is_pattern) { - while (p) { - SwigType *ty = Getattr(p, "type"); - SwigType *val = Getattr(p, "value"); - Append(typelist, ty); - Append(typelist, val); - if (is_pattern) { - /* Typemap patterns are not simple parameter lists. - * Output style ("out", "ret" etc) typemap names can be - * qualified names and so may need template expansion */ - SwigType *name = Getattr(p, "name"); - Append(typelist, name); - } - Append(patchlist, val); - p = nextSibling(p); - } -} - -void Swig_cparse_debug_templates(int x) { - template_debug = x; -} - -/* ----------------------------------------------------------------------------- - * cparse_template_expand() - * - * Expands a template node into a specialized version. This is done by - * patching typenames and other aspects of the node according to a list of - * template parameters - * ----------------------------------------------------------------------------- */ - -static void cparse_template_expand(Node *templnode, Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) { - static int expanded = 0; - String *nodeType; - if (!n) - return; - nodeType = nodeType(n); - if (Getattr(n, "error")) - return; - - if (Equal(nodeType, "template")) { - /* Change the node type back to normal */ - if (!expanded) { - expanded = 1; - set_nodeType(n, Getattr(n, "templatetype")); - cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist); - expanded = 0; - return; - } else { - /* Called when template appears inside another template */ - /* Member templates */ - - set_nodeType(n, Getattr(n, "templatetype")); - cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist); - set_nodeType(n, "template"); - return; - } - } else if (Equal(nodeType, "cdecl")) { - /* A simple C declaration */ - SwigType *t, *v, *d; - String *code; - t = Getattr(n, "type"); - v = Getattr(n, "value"); - d = Getattr(n, "decl"); - - code = Getattr(n, "code"); - - Append(typelist, t); - Append(typelist, d); - Append(patchlist, v); - Append(cpatchlist, code); - - if (Getattr(n, "conversion_operator")) { - Append(cpatchlist, Getattr(n, "name")); - if (Getattr(n, "sym:name")) { - Append(cpatchlist, Getattr(n, "sym:name")); - } - } - if (checkAttribute(n, "storage", "friend")) { - String *symname = Getattr(n, "sym:name"); - if (symname) { - String *stripped_name = SwigType_templateprefix(symname); - Setattr(n, "sym:name", stripped_name); - Delete(stripped_name); - } - Append(typelist, Getattr(n, "name")); - } - - add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0); - add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0); - - } else if (Equal(nodeType, "class")) { - /* Patch base classes */ - { - int b = 0; - for (b = 0; b < 3; ++b) { - List *bases = Getattr(n, baselists[b]); - if (bases) { - int i; - int ilen = Len(bases); - for (i = 0; i < ilen; i++) { - String *name = Copy(Getitem(bases, i)); - Setitem(bases, i, name); - Append(typelist, name); - } - } - } - } - /* Patch children */ - { - Node *cn = firstChild(n); - while (cn) { - cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist); - cn = nextSibling(cn); - } - } - } else if (Equal(nodeType, "constructor")) { - String *name = Getattr(n, "name"); - if (!(Getattr(n, "templatetype"))) { - String *symname; - String *stripped_name = SwigType_templateprefix(name); - if (Strstr(tname, stripped_name)) { - Replaceid(name, stripped_name, tname); - } - Delete(stripped_name); - symname = Getattr(n, "sym:name"); - if (symname) { - stripped_name = SwigType_templateprefix(symname); - if (Strstr(tname, stripped_name)) { - Replaceid(symname, stripped_name, tname); - } - Delete(stripped_name); - } - if (strchr(Char(name), '<')) { - Append(patchlist, Getattr(n, "name")); - } else { - Append(name, templateargs); - } - name = Getattr(n, "sym:name"); - if (name) { - if (strchr(Char(name), '<')) { - Clear(name); - Append(name, rname); - } else { - String *tmp = Copy(name); - Replace(tmp, tname, rname, DOH_REPLACE_ANY); - Clear(name); - Append(name, tmp); - Delete(tmp); - } - } - /* Setattr(n,"sym:name",name); */ - } - Append(cpatchlist, Getattr(n, "code")); - Append(typelist, Getattr(n, "decl")); - add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0); - add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0); - } else if (Equal(nodeType, "destructor")) { - /* We only need to patch the dtor of the template itself, not the destructors of any nested classes, so check that the parent of this node is the root - * template node, with the special exception for %extend which adds its methods under an intermediate node. */ - Node* parent = parentNode(n); - if (parent == templnode || (parentNode(parent) == templnode && Equal(nodeType(parent), "extend"))) { - String *name = Getattr(n, "name"); - if (name) { - if (strchr(Char(name), '<')) - Append(patchlist, Getattr(n, "name")); - else - Append(name, templateargs); - } - name = Getattr(n, "sym:name"); - if (name) { - if (strchr(Char(name), '<')) { - String *sn = Copy(tname); - Setattr(n, "sym:name", sn); - Delete(sn); - } else { - Replace(name, tname, rname, DOH_REPLACE_ANY); - } - } - /* Setattr(n,"sym:name",name); */ - Append(cpatchlist, Getattr(n, "code")); - } - } else if (Equal(nodeType, "using")) { - String *uname = Getattr(n, "uname"); - if (uname && strchr(Char(uname), '<')) { - Append(patchlist, uname); - } - if (Getattr(n, "namespace")) { - /* Namespace link. This is nasty. Is other namespace defined? */ - - } - } else { - /* Look for obvious parameters */ - Node *cn; - Append(cpatchlist, Getattr(n, "code")); - Append(typelist, Getattr(n, "type")); - Append(typelist, Getattr(n, "decl")); - add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0); - add_parms(Getattr(n, "kwargs"), cpatchlist, typelist, 0); - add_parms(Getattr(n, "pattern"), cpatchlist, typelist, 1); - add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0); - cn = firstChild(n); - while (cn) { - cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist); - cn = nextSibling(cn); - } - } -} - -/* ----------------------------------------------------------------------------- - * cparse_fix_function_decl() - * - * Move the prefix of the "type" attribute (excluding any trailing qualifier) - * to the end of the "decl" attribute. - * Examples: - * decl="f().", type="p.q(const).char" => decl="f().p.", type="q(const).char" - * decl="f().p.", type="p.SomeClass" => decl="f().p.p.", type="SomeClass" - * decl="f().", type="r.q(const).p.int" => decl="f().r.q(const).p.", type="int" - * ----------------------------------------------------------------------------- */ - -static void cparse_fix_function_decl(String *name, SwigType *decl, SwigType *type) { - String *prefix; - int prefixLen; - SwigType *last; - - /* The type's prefix is what potentially has to be moved to the end of 'decl' */ - prefix = SwigType_prefix(type); - - /* First some parts (qualifier and array) have to be removed from prefix - in order to remain in the 'type' attribute. */ - last = SwigType_last(prefix); - while (last) { - if (SwigType_isqualifier(last) || SwigType_isarray(last)) { - /* Keep this part in the 'type' */ - Delslice(prefix, Len(prefix) - Len(last), DOH_END); - Delete(last); - last = SwigType_last(prefix); - } else { - /* Done with processing prefix */ - Delete(last); - last = 0; - } - } - - /* Transfer prefix from the 'type' to the 'decl' attribute */ - prefixLen = Len(prefix); - if (prefixLen > 0) { - Append(decl, prefix); - Delslice(type, 0, prefixLen); - if (template_debug) { - Printf(stdout, " change function '%s' to type='%s', decl='%s'\n", name, type, decl); - } - } - - Delete(prefix); -} - -/* ----------------------------------------------------------------------------- - * cparse_postprocess_expanded_template() - * - * This function postprocesses the given node after template expansion. - * Currently the only task to perform is fixing function decl and type attributes. - * ----------------------------------------------------------------------------- */ - -static void cparse_postprocess_expanded_template(Node *n) { - String *nodeType; - if (!n) - return; - nodeType = nodeType(n); - if (Getattr(n, "error")) - return; - - if (Equal(nodeType, "cdecl")) { - /* A simple C declaration */ - SwigType *d = Getattr(n, "decl"); - if (d && SwigType_isfunction(d)) { - /* A function node */ - SwigType *t = Getattr(n, "type"); - if (t) { - String *name = Getattr(n, "name"); - cparse_fix_function_decl(name, d, t); - } - } - } else { - /* Look for any children */ - Node *cn = firstChild(n); - while (cn) { - cparse_postprocess_expanded_template(cn); - cn = nextSibling(cn); - } - } -} - -/* ----------------------------------------------------------------------------- - * partial_arg() - * ----------------------------------------------------------------------------- */ - -static -String *partial_arg(String *s, String *p) { - char *c; - char *cp = Char(p); - String *prefix; - String *newarg; - - /* Find the prefix on the partial argument */ - - c = strchr(cp, '$'); - if (!c) { - return Copy(s); - } - prefix = NewStringWithSize(cp, (int)(c - cp)); - newarg = Copy(s); - Replace(newarg, prefix, "", DOH_REPLACE_FIRST); - Delete(prefix); - return newarg; -} - -/* ----------------------------------------------------------------------------- - * Swig_cparse_template_expand() - * ----------------------------------------------------------------------------- */ - -int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope) { - List *patchlist, *cpatchlist, *typelist; - String *templateargs; - String *tname; - String *iname; - String *tbase; - patchlist = NewList(); - cpatchlist = NewList(); - typelist = NewList(); - - { - String *tmp = NewStringEmpty(); - if (tparms) { - SwigType_add_template(tmp, tparms); - } - templateargs = Copy(tmp); - Delete(tmp); - } - - tname = Copy(Getattr(n, "name")); - tbase = Swig_scopename_last(tname); - - /* Look for partial specialization matching */ - if (Getattr(n, "partialargs")) { - Parm *p, *tp; - ParmList *ptargs = SwigType_function_parms(Getattr(n, "partialargs"), n); - p = ptargs; - tp = tparms; - while (p && tp) { - SwigType *ptype; - SwigType *tptype; - SwigType *partial_type; - ptype = Getattr(p, "type"); - tptype = Getattr(tp, "type"); - if (ptype && tptype) { - partial_type = partial_arg(tptype, ptype); - /* Printf(stdout,"partial '%s' '%s' ---> '%s'\n", tptype, ptype, partial_type); */ - Setattr(tp, "type", partial_type); - Delete(partial_type); - } - p = nextSibling(p); - tp = nextSibling(tp); - } - assert(ParmList_len(ptargs) == ParmList_len(tparms)); - Delete(ptargs); - } - - /* - Parm *p = tparms; - while (p) { - Printf(stdout, "tparm: '%s' '%s' '%s'\n", Getattr(p, "name"), Getattr(p, "type"), Getattr(p, "value")); - p = nextSibling(p); - } - */ - - /* Printf(stdout,"targs = '%s'\n", templateargs); - Printf(stdout,"rname = '%s'\n", rname); - Printf(stdout,"tname = '%s'\n", tname); */ - cparse_template_expand(n, n, tname, rname, templateargs, patchlist, typelist, cpatchlist); - - /* Set the name */ - { - String *name = Getattr(n, "name"); - if (name) { - Append(name, templateargs); - } - iname = name; - } - - /* Patch all of the types */ - { - Parm *tp = Getattr(n, "templateparms"); - Parm *p = tparms; - /* Printf(stdout,"%s\n", ParmList_str_defaultargs(tp)); */ - - if (tp) { - Symtab *tsdecl = Getattr(n, "sym:symtab"); - String *tsname = Getattr(n, "sym:name"); - while (p && tp) { - String *name, *value, *valuestr, *tmp, *tmpr; - int sz, i; - String *dvalue = 0; - String *qvalue = 0; - - name = Getattr(tp, "name"); - value = Getattr(p, "value"); - - if (name) { - if (!value) - value = Getattr(p, "type"); - qvalue = Swig_symbol_typedef_reduce(value, tsdecl); - dvalue = Swig_symbol_type_qualify(qvalue, tsdecl); - if (SwigType_istemplate(dvalue)) { - String *ty = Swig_symbol_template_deftype(dvalue, tscope); - Delete(dvalue); - dvalue = ty; - } - - assert(dvalue); - valuestr = SwigType_str(dvalue, 0); - /* Need to patch default arguments */ - { - Parm *rp = nextSibling(p); - while (rp) { - String *rvalue = Getattr(rp, "value"); - if (rvalue) { - Replace(rvalue, name, dvalue, DOH_REPLACE_ID); - } - rp = nextSibling(rp); - } - } - sz = Len(patchlist); - for (i = 0; i < sz; i++) { - String *s = Getitem(patchlist, i); - Replace(s, name, dvalue, DOH_REPLACE_ID); - } - sz = Len(typelist); - for (i = 0; i < sz; i++) { - String *s = Getitem(typelist, i); - /* - The approach of 'trivially' replacing template arguments is kind of fragile. - In particular if types with similar name in different namespaces appear. - We will not replace template args if a type/class exists with the same - name which is not a template. - */ - Node * tynode = Swig_symbol_clookup(s, 0); - String *tyname = tynode ? Getattr(tynode, "sym:name") : 0; - if (!tyname || !tsname || !Equal(tyname, tsname) || Getattr(tynode, "templatetype")) { - SwigType_typename_replace(s, name, dvalue); - SwigType_typename_replace(s, tbase, iname); - } - } - - tmp = NewStringf("#%s", name); - tmpr = NewStringf("\"%s\"", valuestr); - - sz = Len(cpatchlist); - for (i = 0; i < sz; i++) { - String *s = Getitem(cpatchlist, i); - Replace(s, tmp, tmpr, DOH_REPLACE_ID); - Replace(s, name, valuestr, DOH_REPLACE_ID); - } - Delete(tmp); - Delete(tmpr); - Delete(valuestr); - Delete(dvalue); - Delete(qvalue); - } - p = nextSibling(p); - tp = nextSibling(tp); - if (!p) - p = tp; - } - } else { - /* No template parameters at all. This could be a specialization */ - int i, sz; - sz = Len(typelist); - for (i = 0; i < sz; i++) { - String *s = Getitem(typelist, i); - SwigType_typename_replace(s, tbase, iname); - } - } - } - cparse_postprocess_expanded_template(n); - - /* Patch bases */ - { - List *bases = Getattr(n, "baselist"); - if (bases) { - Iterator b; - for (b = First(bases); b.item; b = Next(b)) { - String *qn = Swig_symbol_type_qualify(b.item, tscope); - Clear(b.item); - Append(b.item, qn); - Delete(qn); - } - } - } - Delete(patchlist); - Delete(cpatchlist); - Delete(typelist); - Delete(tbase); - Delete(tname); - Delete(templateargs); - - /* set_nodeType(n,"template"); */ - return 0; -} - -typedef enum { ExactNoMatch = -2, PartiallySpecializedNoMatch = -1, PartiallySpecializedMatch = 1, ExactMatch = 2 } EMatch; - -/* ----------------------------------------------------------------------------- - * does_parm_match() - * - * Template argument deduction - check if a template type matches a partially specialized - * template parameter type. Typedef reduce 'partial_parm_type' to see if it matches 'type'. - * - * type - template parameter type to match against - * partial_parm_type - partially specialized template type - a possible match - * partial_parm_type_base - base type of partial_parm_type - * tscope - template scope - * specialization_priority - (output) contains a value indicating how good the match is - * (higher is better) only set if return is set to PartiallySpecializedMatch or ExactMatch. - * ----------------------------------------------------------------------------- */ - -static EMatch does_parm_match(SwigType *type, SwigType *partial_parm_type, const char *partial_parm_type_base, Symtab *tscope, int *specialization_priority) { - static const int EXACT_MATCH_PRIORITY = 99999; /* a number bigger than the length of any conceivable type */ - int matches; - int substitutions; - EMatch match; - SwigType *ty = Swig_symbol_typedef_reduce(type, tscope); - String *base = SwigType_base(ty); - SwigType *t = Copy(partial_parm_type); - substitutions = Replaceid(t, partial_parm_type_base, base); /* eg: Replaceid("p.$1", "$1", "int") returns t="p.int" */ - matches = Equal(ty, t); - *specialization_priority = -1; - if (substitutions == 1) { - /* we have a non-explicit specialized parameter (in partial_parm_type) because a substitution for $1, $2... etc has taken place */ - SwigType *tt = Copy(partial_parm_type); - int len; - /* - check for match to partial specialization type, for example, all of the following could match the type in the %template: - template <typename T> struct XX {}; - template <typename T> struct XX<T &> {}; // r.$1 - template <typename T> struct XX<T const&> {}; // r.q(const).$1 - template <typename T> struct XX<T *const&> {}; // r.q(const).p.$1 - %template(XXX) XX<int *const&>; // r.q(const).p.int - - where type="r.q(const).p.int" will match either of tt="r.", tt="r.q(const)" tt="r.q(const).p" - */ - Replaceid(tt, partial_parm_type_base, ""); /* remove the $1, $2 etc, eg tt="p.$1" => "p." */ - len = Len(tt); - if (Strncmp(tt, ty, len) == 0) { - match = PartiallySpecializedMatch; - *specialization_priority = len; - } else { - match = PartiallySpecializedNoMatch; - } - Delete(tt); - } else { - match = matches ? ExactMatch : ExactNoMatch; - if (matches) - *specialization_priority = EXACT_MATCH_PRIORITY; /* exact matches always take precedence */ - } - /* - Printf(stdout, " does_parm_match %2d %5d [%s] [%s]\n", match, *specialization_priority, type, partial_parm_type); - */ - Delete(t); - Delete(base); - Delete(ty); - return match; -} - -/* ----------------------------------------------------------------------------- - * template_locate() - * - * Search for a template that matches name with given parameters. - * ----------------------------------------------------------------------------- */ - -static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { - Node *n = 0; - String *tname = 0; - Node *templ; - Symtab *primary_scope = 0; - List *possiblepartials = 0; - Parm *p; - Parm *parms = 0; - Parm *targs; - ParmList *expandedparms; - int *priorities_matrix = 0; - int max_possible_partials = 0; - int posslen = 0; - - /* Search for primary (unspecialized) template */ - templ = Swig_symbol_clookup(name, 0); - - if (template_debug) { - tname = Copy(name); - SwigType_add_template(tname, tparms); - Printf(stdout, "\n"); - Swig_diagnostic(cparse_file, cparse_line, "template_debug: Searching for match to: '%s'\n", tname); - Delete(tname); - tname = 0; - } - - if (templ) { - tname = Copy(name); - parms = CopyParmList(tparms); - - /* All template specializations must be in the primary template's scope, store the symbol table for this scope for specialization lookups */ - primary_scope = Getattr(templ, "sym:symtab"); - - /* Add default values from primary template */ - targs = Getattr(templ, "templateparms"); - expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, primary_scope); - - /* reduce the typedef */ - p = expandedparms; - while (p) { - SwigType *ty = Getattr(p, "type"); - if (ty) { - SwigType *nt = Swig_symbol_type_qualify(ty, tscope); - Setattr(p, "type", nt); - Delete(nt); - } - p = nextSibling(p); - } - SwigType_add_template(tname, expandedparms); - - /* Search for an explicit (exact) specialization. Example: template<> class name<int> { ... } */ - { - if (template_debug) { - Printf(stdout, " searching for : '%s' (explicit specialization)\n", tname); - } - n = Swig_symbol_clookup_local(tname, primary_scope); - if (!n) { - SwigType *rname = Swig_symbol_typedef_reduce(tname, tscope); - if (!Equal(rname, tname)) { - if (template_debug) { - Printf(stdout, " searching for : '%s' (explicit specialization with typedef reduction)\n", rname); - } - n = Swig_symbol_clookup_local(rname, primary_scope); - } - Delete(rname); - } - if (n) { - Node *tn; - String *nodeType = nodeType(n); - if (Equal(nodeType, "template")) { - if (template_debug) { - Printf(stdout, " explicit specialization found: '%s'\n", Getattr(n, "name")); - } - goto success; - } - tn = Getattr(n, "template"); - if (tn) { - if (template_debug) { - Printf(stdout, " previous instantiation found: '%s'\n", Getattr(n, "name")); - } - n = tn; - goto success; /* Previously wrapped by a template instantiation */ - } - Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n)); - Delete(tname); - Delete(parms); - return 0; /* Found a match, but it's not a template of any kind. */ - } - } - - /* Search for partial specializations. - * Example: template<typename T> class name<T *> { ... } - - * There are 3 types of template arguments: - * (1) Template type arguments - * (2) Template non type arguments - * (3) Template template arguments - * only (1) is really supported for partial specializations - */ - - /* Rank each template parameter against the desired template parameters then build a matrix of best matches */ - possiblepartials = NewList(); - { - char tmp[32]; - List *partials; - - partials = Getattr(templ, "partials"); /* note that these partial specializations do not include explicit specializations */ - if (partials) { - Iterator pi; - int parms_len = ParmList_len(parms); - int *priorities_row; - max_possible_partials = Len(partials); - priorities_matrix = (int *)Malloc(sizeof(int) * max_possible_partials * parms_len); /* slightly wasteful allocation for max possible matches */ - priorities_row = priorities_matrix; - for (pi = First(partials); pi.item; pi = Next(pi)) { - Parm *p = parms; - int all_parameters_match = 1; - int i = 1; - Parm *partialparms = Getattr(pi.item, "partialparms"); - Parm *pp = partialparms; - String *templcsymname = Getattr(pi.item, "templcsymname"); - if (template_debug) { - Printf(stdout, " checking match: '%s' (partial specialization)\n", templcsymname); - } - if (ParmList_len(partialparms) == parms_len) { - while (p && pp) { - SwigType *t; - sprintf(tmp, "$%d", i); - t = Getattr(p, "type"); - if (!t) - t = Getattr(p, "value"); - if (t) { - EMatch match = does_parm_match(t, Getattr(pp, "type"), tmp, tscope, priorities_row + i - 1); - if (match < (int)PartiallySpecializedMatch) { - all_parameters_match = 0; - break; - } - } - i++; - p = nextSibling(p); - pp = nextSibling(pp); - } - if (all_parameters_match) { - Append(possiblepartials, pi.item); - priorities_row += parms_len; - } - } - } - } - } - - posslen = Len(possiblepartials); - if (template_debug) { - int i; - if (posslen == 0) - Printf(stdout, " matched partials: NONE\n"); - else if (posslen == 1) - Printf(stdout, " chosen partial: '%s'\n", Getattr(Getitem(possiblepartials, 0), "templcsymname")); - else { - Printf(stdout, " possibly matched partials:\n"); - for (i = 0; i < posslen; i++) { - Printf(stdout, " '%s'\n", Getattr(Getitem(possiblepartials, i), "templcsymname")); - } - } - } - - if (posslen > 1) { - /* Now go through all the possibly matched partial specialization templates and look for a non-ambiguous match. - * Exact matches rank the highest and deduced parameters are ranked by how specialized they are, eg looking for - * a match to const int *, the following rank (highest to lowest): - * const int * (exact match) - * const T * - * T * - * T - * - * An ambiguous example when attempting to match as either specialization could match: %template() X<int *, double *>; - * template<typename T1, typename T2> X class {}; // primary template - * template<typename T1> X<T1, double *> class {}; // specialization (1) - * template<typename T2> X<int *, T2> class {}; // specialization (2) - */ - if (template_debug) { - int row, col; - int parms_len = ParmList_len(parms); - Printf(stdout, " parameter priorities matrix (%d parms):\n", parms_len); - for (row = 0; row < posslen; row++) { - int *priorities_row = priorities_matrix + row*parms_len; - Printf(stdout, " "); - for (col = 0; col < parms_len; col++) { - Printf(stdout, "%5d ", priorities_row[col]); - } - Printf(stdout, "\n"); - } - } - { - int row, col; - int parms_len = ParmList_len(parms); - /* Printf(stdout, " parameter priorities inverse matrix (%d parms):\n", parms_len); */ - for (col = 0; col < parms_len; col++) { - int *priorities_col = priorities_matrix + col; - int maxpriority = -1; - /* - Printf(stdout, "max_possible_partials: %d col:%d\n", max_possible_partials, col); - Printf(stdout, " "); - */ - /* determine the highest rank for this nth parameter */ - for (row = 0; row < posslen; row++) { - int *element_ptr = priorities_col + row*parms_len; - int priority = *element_ptr; - if (priority > maxpriority) - maxpriority = priority; - /* Printf(stdout, "%5d ", priority); */ - } - /* Printf(stdout, "\n"); */ - /* flag all the parameters which equal the highest rank */ - for (row = 0; row < posslen; row++) { - int *element_ptr = priorities_col + row*parms_len; - int priority = *element_ptr; - *element_ptr = (priority >= maxpriority) ? 1 : 0; - } - } - } - { - int row, col; - int parms_len = ParmList_len(parms); - Iterator pi = First(possiblepartials); - Node *chosenpartials = NewList(); - if (template_debug) - Printf(stdout, " priority flags matrix:\n"); - for (row = 0; row < posslen; row++) { - int *priorities_row = priorities_matrix + row*parms_len; - int highest_count = 0; /* count of highest priority parameters */ - for (col = 0; col < parms_len; col++) { - highest_count += priorities_row[col]; - } - if (template_debug) { - Printf(stdout, " "); - for (col = 0; col < parms_len; col++) { - Printf(stdout, "%5d ", priorities_row[col]); - } - Printf(stdout, "\n"); - } - if (highest_count == parms_len) { - Append(chosenpartials, pi.item); - } - pi = Next(pi); - } - if (Len(chosenpartials) > 0) { - /* one or more best match found */ - Delete(possiblepartials); - possiblepartials = chosenpartials; - posslen = Len(possiblepartials); - } else { - /* no best match found */ - Delete(chosenpartials); - } - } - } - - if (posslen > 0) { - String *s = Getattr(Getitem(possiblepartials, 0), "templcsymname"); - n = Swig_symbol_clookup_local(s, primary_scope); - if (posslen > 1) { - int i; - if (n) { - Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, cparse_file, cparse_line, "Instantiation of template '%s' is ambiguous,\n", SwigType_namestr(tname)); - Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(n), Getline(n), " instantiation '%s' used,\n", SwigType_namestr(Getattr(n, "name"))); - } - for (i = 1; i < posslen; i++) { - String *templcsymname = Getattr(Getitem(possiblepartials, i), "templcsymname"); - Node *ignored_node = Swig_symbol_clookup_local(templcsymname, primary_scope); - assert(ignored_node); - Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(ignored_node), Getline(ignored_node), " instantiation '%s' ignored.\n", SwigType_namestr(Getattr(ignored_node, "name"))); - } - } - } - - if (!n) { - if (template_debug) { - Printf(stdout, " chosen primary template: '%s'\n", Getattr(templ, "name")); - } - n = templ; - } - } else { - if (template_debug) { - Printf(stdout, " primary template not found\n"); - } - /* Give up if primary (unspecialized) template not found as specializations will only exist if there is a primary template */ - n = 0; - } - - if (!n) { - Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name); - } else if (n) { - String *nodeType = nodeType(n); - if (!Equal(nodeType, "template")) { - Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType); - n = 0; - } - } -success: - Delete(tname); - Delete(possiblepartials); - if ((template_debug) && (n)) { - /* - Printf(stdout, "Node: %p\n", n); - Swig_print_node(n); - */ - Printf(stdout, " chosen template:'%s'\n", Getattr(n, "name")); - } - Delete(parms); - Free(priorities_matrix); - return n; -} - - -/* ----------------------------------------------------------------------------- - * Swig_cparse_template_locate() - * - * Search for a template that matches name with given parameters. - * For templated classes finds the specialized template should there be one. - * For templated functions finds the unspecialized template even if a specialized - * template exists. - * ----------------------------------------------------------------------------- */ - -Node *Swig_cparse_template_locate(String *name, Parm *tparms, Symtab *tscope) { - Node *n = template_locate(name, tparms, tscope); /* this function does what we want for templated classes */ - - if (n) { - String *nodeType = nodeType(n); - int isclass = 0; - assert(Equal(nodeType, "template")); - (void)nodeType; - isclass = (Equal(Getattr(n, "templatetype"), "class")); - if (!isclass) { - /* If not a templated class we must have a templated function. - The template found is not necessarily the one we want when dealing with templated - functions. We don't want any specialized templated functions as they won't have - the default parameters. Let's look for the unspecialized template. Also make sure - the number of template parameters is correct as it is possible to overload a - templated function with different numbers of template parameters. */ - - if (template_debug) { - Printf(stdout, " Not a templated class, seeking most appropriate templated function\n"); - } - - n = Swig_symbol_clookup_local(name, 0); - while (n) { - Parm *tparmsfound = Getattr(n, "templateparms"); - if (ParmList_len(tparms) == ParmList_len(tparmsfound)) { - /* successful match */ - break; - } - /* repeat until we find a match with correct number of templated parameters */ - n = Getattr(n, "sym:nextSibling"); - } - - if (!n) { - Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name); - } - - if ((template_debug) && (n)) { - Printf(stdout, "Templated function found: %p\n", n); - Swig_print_node(n); - } - } - } - - return n; -} diff --git a/contrib/tools/swig/Source/CParse/util.c b/contrib/tools/swig/Source/CParse/util.c deleted file mode 100644 index 00863c03577..00000000000 --- a/contrib/tools/swig/Source/CParse/util.c +++ /dev/null @@ -1,126 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * util.c - * - * Parsing utilities. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "cparse.h" - -/* ----------------------------------------------------------------------------- - * Swig_cparse_replace_descriptor() - * - * Replaces type descriptor string $descriptor() with the SWIG type descriptor - * string. - * ----------------------------------------------------------------------------- */ - -void Swig_cparse_replace_descriptor(String *s) { - char tmp[512]; - String *arg = 0; - SwigType *t; - char *c = 0; - - while ((c = strstr(Char(s), "$descriptor("))) { - char *d = tmp; - int level = 0; - while (*c) { - if (*c == '(') - level++; - if (*c == ')') { - level--; - if (level == 0) { - break; - } - } - *d = *c; - d++; - c++; - } - *d = 0; - arg = NewString(tmp + 12); - t = Swig_cparse_type(arg); - Delete(arg); - arg = 0; - - if (t) { - String *mangle; - String *descriptor; - - mangle = SwigType_manglestr(t); - descriptor = NewStringf("SWIGTYPE%s", mangle); - SwigType_remember(t); - *d = ')'; - d++; - *d = 0; - Replace(s, tmp, descriptor, DOH_REPLACE_ANY); - Delete(mangle); - Delete(descriptor); - Delete(t); - } else { - Swig_error(Getfile(s), Getline(s), "Bad $descriptor() macro.\n"); - break; - } - } -} - -/* ----------------------------------------------------------------------------- - * Swig_cparse_smartptr() - * - * Parse the type in smartptr feature and convert into a SwigType. - * Error out if the parsing fails as this is like a parser syntax error. - * ----------------------------------------------------------------------------- */ - -SwigType *Swig_cparse_smartptr(Node *n) { - SwigType *smart = 0; - String *smartptr = Getattr(n, "feature:smartptr"); - if (smartptr) { - SwigType *cpt = Swig_cparse_type(smartptr); - if (cpt) { - smart = SwigType_typedef_resolve_all(cpt); - Delete(cpt); - } else { - Swig_error(Getfile(n), Getline(n), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, SwigType_namestr(Getattr(n, "name"))); - } - } - return smart; -} - -/* ----------------------------------------------------------------------------- - * cparse_normalize_void() - * - * This function is used to replace arguments of the form (void) with empty - * arguments in C++ - * ----------------------------------------------------------------------------- */ - -void cparse_normalize_void(Node *n) { - String *decl = Getattr(n, "decl"); - Parm *parms = Getattr(n, "parms"); - - if (SwigType_isfunction(decl)) { - if ((ParmList_len(parms) == 1) && (SwigType_type(Getattr(parms, "type")) == T_VOID)) { - Replaceall(decl, "f(void).", "f()."); - Delattr(n, "parms"); - } - } -} - -/* ----------------------------------------------------------------------------- - * Swig_cparse_new_node() - * - * Create an empty parse node, setting file and line number information - * ----------------------------------------------------------------------------- */ - -Node *Swig_cparse_new_node(const_String_or_char_ptr tag) { - Node *n = NewHash(); - set_nodeType(n,tag); - Setfile(n,cparse_file); - Setline(n,cparse_line); - return n; -} diff --git a/contrib/tools/swig/Source/DOH/README b/contrib/tools/swig/Source/DOH/README deleted file mode 100644 index be90f25b46e..00000000000 --- a/contrib/tools/swig/Source/DOH/README +++ /dev/null @@ -1,124 +0,0 @@ -DOH (Dave's Object Hack) - -Overview: ---------- -DOH is a small C library that provides a number of simple yet powerful -data structures. The data structures are built around a dynamic typing -model in which any given object is allowed to support one or more -classes of operations. Furthermore, a simple garbage collection -scheme and a variety of interesting library methods are available. -All and all, the operation of DOH makes massive abuse of the C type -system and would probably make the language purists scream and -performance addicts run away in horror. However, I really don't -care--so there! However, for the rest of us, DOH is actually kind of -fun to use. This is only a short description of the methods and is no -way meant to be exhaustive. - -Common Operations (for all types) ---------------------------------- -Delete(obj) Decrease the reference count and destroy if zero -Copy(obj) Make a copy of an object. -Clear(obj) Clear an object. -Setscope(obj) Set scope of an object (guru's only) -Str(obj) Create a string representation of obj. -Data(obj) Return pointer to raw data in an object -Char(obj) Convert to a char * -Len(obj) Length of an object -Hash(obj) Hash value (used for mapping) -Cmp(obj1,obj2) Compare two objects. -Name(obj) Return the object name -First(obj) Return first object (iterator) -Next(obj) Return next object -Dump(obj,out) Serialize on out -Load(in) Unserialize from in -First(obj) Iterator -Next(iter) Next iterator - -Mapping Operations (for hash table behavior) --------------------------------------------- -Getattr(hash,key) Get an attribute -Setattr(hash,key,value) Set an attribute -Delattr(hash,key) Delete an attribute -First(hash) Get first object (iterator) -Next(hash) Get next object -GetInt(hash,key) Get attribute as an 'int' -SetInt(hash,key,ivalue) Set attribute as an 'int' -GetDouble(hash,key) Get attribute as a 'double' -SetDouble(hash,key,dvalue) Set Attribute as a 'double' -GetChar(hash,key) Get attribute as a 'char *' - -Sequence Operations -------------------- -Getitem(list,index) Get an item -Setitem(list,index,val) Set an item -Delitem(list,index) Delete an item -Insert(list,index,val) Insert an item -Append(list,val) Append to end -Push(list,val) Insert at beginning - -File Operations ---------------- -Read(obj,buffer,len) Read data -Write(obj,buffer,len) Write data -Getc(obj) Get a character -Putc(ch,obj) Put a character -Ungetc(ch,obj) Put character back on input stream -Seek(obj,offset,whence) Seek -Tell(obj) Return file pointer -Delete(obj) Decrease the reference count, close file if zero - -String Operations ------------------ -Replace(obj, orig, rep, flags) Replace occurrences of orig with rep. -Chop(obj) Remove trailing whitespace - -flags is one of the following: - DOH_REPLACE_ID - DOH_REPLACE_ID_BEGIN - DOH_REPLACE_ID_END - DOH_REPLACE_NUMBER_END - -and can be combined with one or more of the following: - DOH_REPLACE_ANY - DOH_REPLACE_NOQUOTE - DOH_REPLACE_NOCOMMENT - DOH_REPLACE_FIRST - -Callable Operations -------------------- -Call(obj, args) Perform a function call with arguments args. - -Miscellaneous library functions -------------------------------- -NewScope() Create a new scope -DelScope(s) Delete scope s -Readline(in) Read a line of input from in -Printf(out,fmt,...) Formatted output -DohEncoding(name, fn) Register a format encoding for Printf - -Currently Available datatypes ------------------------------- -NewString(char *initial) Strings -NewHash() Hash -NewList() List -NewVoid(void *ptr, void (*del)(void *)) Void -NewFile(char *filename, char *mode, List *newfiles) File -NewCallable(DOH *(*func)(DOH *, DOH *)) Callable object - - -Odds and ends: - - 1. All objects are of type 'DOH *' - 2. When in doubt, see rule (1) - 3. In certain cases, DOH performs implicit conversions - of 'char *' to an appropriate DOH string representation. - For operations involving files, DOH works with many - kinds of objects including FILE *, DOH File objects, - and DOH strings. Don't even ask how this works. - - 4. More complete documentation is forthcoming. - - - - - diff --git a/contrib/tools/swig/Source/DOH/base.c b/contrib/tools/swig/Source/DOH/base.c deleted file mode 100644 index 8731a5f118c..00000000000 --- a/contrib/tools/swig/Source/DOH/base.c +++ /dev/null @@ -1,937 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * base.c - * - * This file contains the function entry points for dispatching methods on - * DOH objects. A number of small utility functions are also included. - * ----------------------------------------------------------------------------- */ - -#include "dohint.h" - -/* ----------------------------------------------------------------------------- - * DohDelete() - * ----------------------------------------------------------------------------- */ - -void DohDelete(DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - - if (!obj) - return; - if (!DohCheck(b)) { - fputs("Fatal internal error: Attempt to delete a non-DOH object.\n", stderr); - Exit(EXIT_FAILURE); - } - if (b->flag_intern) - return; - assert(b->refcount > 0); - b->refcount--; - if (b->refcount <= 0) { - objinfo = b->type; - if (objinfo->doh_del) { - (objinfo->doh_del) (b); - } else { - if (b->data) - DohFree(b->data); - } - DohObjFree(b); - } -} - -/* ----------------------------------------------------------------------------- - * DohCopy() - * ----------------------------------------------------------------------------- */ - -DOH *DohCopy(const DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - - if (!obj) - return 0; - if (!DohCheck(b)) { - fputs("Fatal internal error: Attempt to copy a non-DOH object.\n", stderr); - Exit(EXIT_FAILURE); - } - objinfo = b->type; - if (objinfo->doh_copy) { - DohBase *bc = (DohBase *) (objinfo->doh_copy) (b); - if ((bc) && b->meta) { - bc->meta = Copy(b->meta); - } - return (DOH *) bc; - } - return 0; -} - -void DohIncref(DOH *obj) { - Incref(obj); -} - -/* ----------------------------------------------------------------------------- - * DohClear() - * ----------------------------------------------------------------------------- */ - -void DohClear(DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = b->type; - if (objinfo->doh_clear) - (objinfo->doh_clear) (b); -} - -/* ----------------------------------------------------------------------------- - * DohStr() - * ----------------------------------------------------------------------------- */ - -DOH *DohStr(const DOH *obj) { - char buffer[512]; - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (DohCheck(b)) { - objinfo = b->type; - if (objinfo->doh_str) { - return (objinfo->doh_str) (b); - } - sprintf(buffer, "<Object '%s' at %p>", objinfo->objname, (void *) b); - return NewString(buffer); - } else { - return NewString(obj); - } -} - -/* ----------------------------------------------------------------------------- - * DohDump() - * ----------------------------------------------------------------------------- */ - -int DohDump(const DOH *obj, DOH *out) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = b->type; - if (objinfo->doh_dump) { - return (objinfo->doh_dump) (b, out); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohLen() - Defaults to strlen() if not a DOH object - * ----------------------------------------------------------------------------- */ -int DohLen(const DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (!b) - return 0; - if (DohCheck(b)) { - objinfo = b->type; - if (objinfo->doh_len) { - return (objinfo->doh_len) (b); - } - return 0; - } else { - return (int)strlen((char *) obj); - } -} - -/* ----------------------------------------------------------------------------- - * DohHashVal() - * ----------------------------------------------------------------------------- */ - -int DohHashval(const DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - /* obj is already checked and/or converted into DohBase* */ - /* if (DohCheck(b)) */ - { - objinfo = b->type; - if (objinfo->doh_hashval) { - return (objinfo->doh_hashval) (b); - } - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohData() - * ----------------------------------------------------------------------------- */ - -void *DohData(const DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (DohCheck(obj)) { - objinfo = b->type; - if (objinfo->doh_data) { - return (objinfo->doh_data) (b); - } - return 0; - } - return (void *) obj; -} - -/* ----------------------------------------------------------------------------- - * RawData() - * ----------------------------------------------------------------------------- */ - -static void *RawData(DohBase *b) { - DohObjInfo *objinfo = b->type; - return (objinfo->doh_data) ? (objinfo->doh_data) (b) : 0; -} - - -/* ----------------------------------------------------------------------------- - * DohCmp() - * ----------------------------------------------------------------------------- */ - -int DohCmp(const DOH *obj1, const DOH *obj2) { - DohBase *b1, *b2; - DohObjInfo *b1info, *b2info; - int c1, c2; - b1 = (DohBase *) obj1; - b2 = (DohBase *) obj2; - c1 = DohCheck(b1); - c2 = DohCheck(b2); - /* most of the times, obj2 is a plain c string */ - if (!c1 || !c2) { - if ((b1 == 0) && (b2 == 0)) - return 0; - if (b1 && !b2) - return 1; - if (!b1 && b2) - return -1; - return strcmp((char *) (c1 ? RawData(b1) : (void *) obj1), (char *) (c2 ? RawData(b2) : (void *) obj2)); - } - b1info = b1->type; - b2info = b2->type; - if ((b1info == b2info) && (b1info->doh_cmp)) - return (b1info->doh_cmp) (b1, b2); - return 1; -} - -/* ----------------------------------------------------------------------------- - * DohEqual() - * ----------------------------------------------------------------------------- */ - -int DohEqual(const DOH *obj1, const DOH *obj2) { - DohBase *b1 = (DohBase *) obj1; - DohBase *b2 = (DohBase *) obj2; - if (!b1) { - return !b2; - } else if (!b2) { - return 0; - } else { - DohObjInfo *b1info = 0; - DohObjInfo *b2info = 0; - if (DohCheck(b1)) { - b1info = b1->type; - if (DohCheck(b2)) { - b2info = b2->type; - } else { - int len = (b1info->doh_len) (b1); - char *cobj = (char *) obj2; - return len == (int) strlen(cobj) ? (memcmp(RawData(b1), cobj, len) == 0) : 0; - } - } else if (DohCheck(b2)) { - int len = (b2->type->doh_len) (b2); - char *cobj = (char *) obj1; - return len == (int) strlen(cobj) ? (memcmp(RawData(b2), cobj, len) == 0) : 0; - } else { - return strcmp((char *) obj1, (char *) obj2) == 0; - } - - if (!b1info) { - return obj1 == obj2; - } else if (b1info == b2info) { - return b1info->doh_equal ? (b1info->doh_equal) (b1, b2) : (b1info->doh_cmp ? (b1info->doh_cmp) (b1, b2) == 0 : (b1 == b2)); - } else { - return 0; - } - } -} - -/* ----------------------------------------------------------------------------- - * DohFirst() - * ----------------------------------------------------------------------------- */ - -DohIterator DohFirst(DOH *obj) { - DohIterator iter; - DohBase *b; - DohObjInfo *binfo; - - b = (DohBase *) obj; - if (DohCheck(b)) { - binfo = b->type; - if (binfo->doh_first) { - return (binfo->doh_first) (b); - } - } - iter.object = 0; - iter.item = 0; - iter.key = 0; - iter._current = 0; - iter._index = 0; - return iter; -} - -/* ----------------------------------------------------------------------------- - * DohNext() - * ----------------------------------------------------------------------------- */ - -DohIterator DohNext(DohIterator iter) { - DohIterator niter; - - if (iter.object) { - DohBase *b; - DohObjInfo *binfo; - - b = (DohBase *) iter.object; - binfo = b->type; - if (binfo->doh_next) { - return (binfo->doh_next) (iter); - } - } - niter = iter; - return niter; -} - -/* ----------------------------------------------------------------------------- - * DohIsMapping() - * ----------------------------------------------------------------------------- */ -int DohIsMapping(const DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (!DohCheck(b)) - return 0; - objinfo = b->type; - if (objinfo->doh_hash) - return 1; - else - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohGetattr() - * ----------------------------------------------------------------------------- */ - -DOH *DohGetattr(DOH *obj, const DOH *name) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = b->type; - if (objinfo->doh_hash && objinfo->doh_hash->doh_getattr) { - DOH *r = (objinfo->doh_hash->doh_getattr) (b, (DOH *) name); - return (r == DohNone) ? 0 : r; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohSetattr() - * ----------------------------------------------------------------------------- */ - -int DohSetattr(DOH *obj, const DOH *name, const DOH *value) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = b->type; - if (objinfo->doh_hash && objinfo->doh_hash->doh_setattr) { - return (objinfo->doh_hash->doh_setattr) (b, (DOH *) name, (DOH *) value); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohDelattr() - * ----------------------------------------------------------------------------- */ - -int DohDelattr(DOH *obj, const DOH *name) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = b->type; - if (objinfo->doh_hash && objinfo->doh_hash->doh_delattr) { - return (objinfo->doh_hash->doh_delattr) (b, (DOH *) name); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohCheckattr() - * ----------------------------------------------------------------------------- */ - -int DohCheckattr(DOH *obj, const DOH *name, const DOH *value) { - DOH *attr = Getattr(obj,name); - if (!attr) return 0; - return DohEqual(attr,value); -} - -/* ----------------------------------------------------------------------------- - * DohKeys() - * ----------------------------------------------------------------------------- */ - -DOH *DohKeys(DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = b->type; - if (objinfo && objinfo->doh_hash->doh_keys) { - return (objinfo->doh_hash->doh_keys) (b); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohSortedKeys() - * ----------------------------------------------------------------------------- */ - -DOH *DohSortedKeys(DOH *obj, int (*cmp) (const DOH *, const DOH *)) { - DOHList *keys = DohKeys(obj); - if (keys) { - DohSortList(keys, cmp); - } - return keys; -} - -/* ----------------------------------------------------------------------------- - * DohGetInt() - * ----------------------------------------------------------------------------- */ - -int DohGetInt(DOH *obj, const DOH *name) { - DOH *val; - val = Getattr(obj, (DOH *) name); - if (!val) - return 0; - if (DohIsString(val)) { - return atoi((char *) Data(val)); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohGetDouble() - * ----------------------------------------------------------------------------- */ - -double DohGetDouble(DOH *obj, const DOH *name) { - DOH *val; - val = Getattr(obj, (DOH *) name); - if (!val) - return 0; - if (DohIsString(val)) { - return atof((char *) Data(val)); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohGetChar() - * ----------------------------------------------------------------------------- */ - -char *DohGetChar(DOH *obj, const DOH *name) { - DOH *val; - val = Getattr(obj, (DOH *) name); - if (!val) - return 0; - if (DohIsString(val)) { - return (char *) Data(val); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohGetFlagAttr() / DohGetFlag() - * A flag is unset if the attribute (name) does not exist on the node (obj), - * or it is set to "0". If the attribute is set to any other value, - * the flag is set. - * - * DohGetFlag() returns if the flag is set or not - * DohGetFlagAttr() returns the flag value if is set, NULL otherwise - * ----------------------------------------------------------------------------- */ - - -DOH *DohGetFlagAttr(DOH *obj, const DOH *name) { - DOH *val = Getattr(obj, (DOH *) name); - if (!val) { - return NULL; - } else { - const char *cval = Char(val); - if (!cval) - return val; - return (strcmp(cval, "0") != 0) ? val : NULL; - } -} - -int DohGetFlag(DOH *obj, const DOH *name) { - return DohGetFlagAttr(obj, name) ? 1 : 0; -} - - -/* ----------------------------------------------------------------------------- - * DohGetVoid() - * ----------------------------------------------------------------------------- */ - -void *DohGetVoid(DOH *obj, const DOH *name) { - DOH *val; - val = Getattr(obj, (DOH *) name); - if (!val) - return 0; - return (void *) Data(val); -} - -/* ----------------------------------------------------------------------------- - * DohSetInt() - * ----------------------------------------------------------------------------- */ - -void DohSetInt(DOH *obj, const DOH *name, int value) { - DOH *temp; - temp = NewStringEmpty(); - Printf(temp, "%d", value); - Setattr(obj, (DOH *) name, temp); -} - -/* ----------------------------------------------------------------------------- - * DohSetDouble() - * ----------------------------------------------------------------------------- */ - -void DohSetDouble(DOH *obj, const DOH *name, double value) { - DOH *temp; - temp = NewStringEmpty(); - Printf(temp, "%0.17f", value); - Setattr(obj, (DOH *) name, temp); -} - -/* ----------------------------------------------------------------------------- - * DohSetChar() - * ----------------------------------------------------------------------------- */ - -void DohSetChar(DOH *obj, const DOH *name, char *value) { - Setattr(obj, (DOH *) name, NewString(value)); -} - -/* ----------------------------------------------------------------------------- - * DohSetFlag() - * ----------------------------------------------------------------------------- */ - -void DohSetFlagAttr(DOH *obj, const DOH *name, const DOH *attr) { - Setattr(obj, (DOH *) name, attr ? attr : NewString("0")); -} - -void DohSetFlag(DOH *obj, const DOH *name) { - Setattr(obj, (DOH *) name, NewString("1")); -} - -/* ----------------------------------------------------------------------------- - * DohSetVoid() - * ----------------------------------------------------------------------------- */ - -void DohSetVoid(DOH *obj, const DOH *name, void *value) { - Setattr(obj, (DOH *) name, NewVoid(value, 0)); -} - -/* ----------------------------------------------------------------------------- - * DohIsSequence() - * ----------------------------------------------------------------------------- */ - -int DohIsSequence(const DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (!DohCheck(b)) - return 0; - objinfo = b->type; - if (objinfo->doh_list) - return 1; - else - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohGetitem() - * ----------------------------------------------------------------------------- */ - -DOH *DohGetitem(DOH *obj, int index) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = b->type; - if (objinfo->doh_list && objinfo->doh_list->doh_getitem) { - return (objinfo->doh_list->doh_getitem) (b, index); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohSetitem() - * ----------------------------------------------------------------------------- */ - -int DohSetitem(DOH *obj, int index, const DOH *value) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = b->type; - if (objinfo->doh_list && objinfo->doh_list->doh_setitem) { - return (objinfo->doh_list->doh_setitem) (b, index, (DOH *) value); - } - return -1; -} - -/* ----------------------------------------------------------------------------- - * DohDelitem() - * ----------------------------------------------------------------------------- */ - -int DohDelitem(DOH *obj, int index) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = b->type; - if (objinfo->doh_list && objinfo->doh_list->doh_delitem) { - return (objinfo->doh_list->doh_delitem) (b, index); - } - return -1; -} - -/* ----------------------------------------------------------------------------- - * DohInsertitem() - * ----------------------------------------------------------------------------- */ - -int DohInsertitem(DOH *obj, int index, const DOH *value) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = b->type; - if (objinfo->doh_list && objinfo->doh_list->doh_insitem) { - return (objinfo->doh_list->doh_insitem) (b, index, (DOH *) value); - } - return -1; -} - - -/* ----------------------------------------------------------------------------- - * DohDelslice() - * ----------------------------------------------------------------------------- */ - -int DohDelslice(DOH *obj, int sindex, int eindex) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo = b->type; - if (objinfo->doh_list && objinfo->doh_list->doh_delslice) { - return (objinfo->doh_list->doh_delslice) (b, sindex, eindex); - } - return -1; -} - -/* ----------------------------------------------------------------------------- - * DohIsFile() - * ----------------------------------------------------------------------------- */ - -int DohIsFile(const DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (!DohCheck(b)) - return 0; - objinfo = b->type; - if (objinfo->doh_file) - return 1; - else - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohRead() - * ----------------------------------------------------------------------------- */ - -int DohRead(DOH *obj, void *buffer, int length) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (DohCheck(obj)) { - objinfo = b->type; - if ((objinfo->doh_file) && (objinfo->doh_file->doh_read)) { - return (objinfo->doh_file->doh_read) (b, buffer, length); - } - return -1; - } - /* Hmmm. Not a file. Maybe it's a real FILE */ - return (int)fread(buffer, 1, length, (FILE *) b); -} - -/* ----------------------------------------------------------------------------- - * DohWrite() - * ----------------------------------------------------------------------------- */ - -int DohWrite(DOH *obj, const void *buffer, int length) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (DohCheck(obj)) { - objinfo = b->type; - if ((objinfo->doh_file) && (objinfo->doh_file->doh_write)) { - return (objinfo->doh_file->doh_write) (b, buffer, length); - } - return -1; - } - /* Hmmm. Not a file. Maybe it's a real FILE */ - return (int)fwrite(buffer, 1, length, (FILE *) b); -} - -/* ----------------------------------------------------------------------------- - * DohSeek() - * ----------------------------------------------------------------------------- */ - -int DohSeek(DOH *obj, long offset, int whence) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (DohCheck(obj)) { - objinfo = b->type; - if ((objinfo->doh_file) && (objinfo->doh_file->doh_seek)) { - return (objinfo->doh_file->doh_seek) (b, offset, whence); - } - return -1; - } - return fseek((FILE *) b, offset, whence); -} - -/* ----------------------------------------------------------------------------- - * DohTell() - * ----------------------------------------------------------------------------- */ - -long DohTell(DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (DohCheck(obj)) { - objinfo = b->type; - if ((objinfo->doh_file) && (objinfo->doh_file->doh_tell)) { - return (objinfo->doh_file->doh_tell) (b); - } - return -1; - } - return ftell((FILE *) b); -} - -/* ----------------------------------------------------------------------------- - * DohGetc() - * ----------------------------------------------------------------------------- */ - -int DohGetc(DOH *obj) { - static DOH *lastdoh = 0; - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (obj == lastdoh) { - objinfo = b->type; - return (objinfo->doh_file->doh_getc) (b); - } - if (DohCheck(obj)) { - objinfo = b->type; - if (objinfo->doh_file->doh_getc) { - lastdoh = obj; - return (objinfo->doh_file->doh_getc) (b); - } - return EOF; - } - return fgetc((FILE *) b); -} - -/* ----------------------------------------------------------------------------- - * DohPutc() - * ----------------------------------------------------------------------------- */ - -int DohPutc(int ch, DOH *obj) { - static DOH *lastdoh = 0; - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - - if (obj == lastdoh) { - objinfo = b->type; - return (objinfo->doh_file->doh_putc) (b, ch); - } - if (DohCheck(obj)) { - objinfo = b->type; - if (objinfo->doh_file->doh_putc) { - lastdoh = obj; - return (objinfo->doh_file->doh_putc) (b, ch); - } - return EOF; - } - return fputc(ch, (FILE *) b); -} - -/* ----------------------------------------------------------------------------- - * DohUngetc() - * ----------------------------------------------------------------------------- */ - -int DohUngetc(int ch, DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (DohCheck(obj)) { - objinfo = b->type; - if (objinfo->doh_file->doh_ungetc) { - return (objinfo->doh_file->doh_ungetc) (b, ch); - } - return EOF; - } - return ungetc(ch, (FILE *) b); -} - -/* ----------------------------------------------------------------------------- - * DohIsString() - * ----------------------------------------------------------------------------- */ - -int DohIsString(const DOH *obj) { - DohBase *b = (DohBase *) obj; - DohObjInfo *objinfo; - if (!DohCheck(b)) - return 0; - objinfo = b->type; - if (objinfo->doh_string) - return 1; - else - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohReplace() - * ----------------------------------------------------------------------------- */ - -int DohReplace(DOH *src, const DOH *token, const DOH *rep, int flags) { - DohBase *b = (DohBase *) src; - DohObjInfo *objinfo; - if (!token) - return 0; - if (!rep) - rep = ""; - if (DohIsString(src)) { - objinfo = b->type; - if (objinfo->doh_string->doh_replace) { - return (objinfo->doh_string->doh_replace) (b, (DOH *) token, (DOH *) rep, flags); - } - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohChop() - * ----------------------------------------------------------------------------- */ - -void DohChop(DOH *src) { - DohBase *b = (DohBase *) src; - DohObjInfo *objinfo; - if (DohIsString(src)) { - objinfo = b->type; - if (objinfo->doh_string->doh_chop) { - (objinfo->doh_string->doh_chop) (b); - } - } -} - -/* ----------------------------------------------------------------------------- - * DohSetFile() - * ----------------------------------------------------------------------------- */ -void DohSetfile(DOH *ho, DOH *file) { - DohBase *h = (DohBase *) ho; - DohObjInfo *objinfo; - if (!h) - return; - objinfo = h->type; - if (objinfo->doh_setfile) - (objinfo->doh_setfile) (h, file); -} - -/* ----------------------------------------------------------------------------- - * DohGetFile() - * ----------------------------------------------------------------------------- */ -DOH *DohGetfile(const DOH *ho) { - DohBase *h = (DohBase *) ho; - DohObjInfo *objinfo; - if (!h) - return 0; - objinfo = h->type; - if (objinfo->doh_getfile) - return (objinfo->doh_getfile) (h); - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohSetLine() - * ----------------------------------------------------------------------------- */ -void DohSetline(DOH *ho, int l) { - DohBase *h = (DohBase *) ho; - DohObjInfo *objinfo; - if (!h) - return; - objinfo = h->type; - if (objinfo->doh_setline) - (objinfo->doh_setline) (h, l); -} - -/* ----------------------------------------------------------------------------- - * DohGetLine() - * ----------------------------------------------------------------------------- */ -int DohGetline(const DOH *ho) { - DohBase *h = (DohBase *) ho; - DohObjInfo *objinfo; - if (!h) - return 0; - objinfo = h->type; - if (objinfo->doh_getline) - return (objinfo->doh_getline) (h); - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohGetmeta() - * ----------------------------------------------------------------------------- */ - -DOH *DohGetmeta(DOH *ho, const DOH *name) { - DohBase *h = (DohBase *) ho; - if (!DohCheck(ho)) - return 0; - if (!h->meta) - return 0; - return DohGetattr(h->meta, name); -} - -/* ----------------------------------------------------------------------------- - * DohGetmeta() - * ----------------------------------------------------------------------------- */ - -int DohSetmeta(DOH *ho, const DOH *name, const DOH *value) { - DohBase *h = (DohBase *) ho; - if (!DohCheck(ho)) - return 0; - if (!h->meta) - h->meta = NewHash(); - return DohSetattr(h->meta, name, value); -} - -/* ----------------------------------------------------------------------------- - * DohDelmeta() - * ----------------------------------------------------------------------------- */ - -int DohDelmeta(DOH *ho, const DOH *name) { - DohBase *h = (DohBase *) ho; - if (!DohCheck(ho)) - return 0; - if (!h->meta) - return 0; - return DohDelattr(h->meta, name); -} - -/* ----------------------------------------------------------------------------- - * DohSetmark() - * ----------------------------------------------------------------------------- */ - -void DohSetmark(DOH *ho, int x) { - DohBase *h = (DohBase *) ho; - h->flag_usermark = x; -} - -int DohGetmark(DOH *ho) { - DohBase *h = (DohBase *) ho; - return h->flag_usermark; -} - -/* ----------------------------------------------------------------------------- - * DohCall() - * - * Invokes a function via DOH. A Function is represented by a hash table with - * the following attributes: - * - * "builtin" - Pointer to built-in function (if any) - * - * (Additional attributes may be added later) - * - * Returns a DOH object with result on success. Returns NULL on error - * ----------------------------------------------------------------------------- */ - -DOH *DohCall(DOH *func, DOH *args) { - DOH *result; - DohFuncPtr_t builtin; - - builtin.p = GetVoid(func, "builtin"); - - if (!builtin.p) - return 0; - result = (*builtin.func) (args); - return result; -} diff --git a/contrib/tools/swig/Source/DOH/doh.h b/contrib/tools/swig/Source/DOH/doh.h deleted file mode 100644 index 45a1f7fc892..00000000000 --- a/contrib/tools/swig/Source/DOH/doh.h +++ /dev/null @@ -1,507 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * doh.h - * - * This file describes of the externally visible functions in DOH. - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_DOH_H -#define SWIG_DOH_H - -#include "swigconfig.h" - -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> - -/* Set the namespace prefix for DOH API functions. This can be used to control - visibility of the functions in libraries */ - -/* Set this macro if you want to change DOH linkage. You would do this if you - wanted to hide DOH in a library using a different set of names. Note: simply - change "Doh" to a new name. */ - -/* -#define DOH_NAMESPACE(x) Doh ## x -*/ - -#ifdef DOH_NAMESPACE - -/* Namespace control. These macros define all of the public API names in DOH */ - -#define DohCheck DOH_NAMESPACE(Check) -#define DohIntern DOH_NAMESPACE(Intern) -#define DohDelete DOH_NAMESPACE(Delete) -#define DohCopy DOH_NAMESPACE(Copy) -#define DohClear DOH_NAMESPACE(Clear) -#define DohStr DOH_NAMESPACE(Str) -#define DohData DOH_NAMESPACE(Data) -#define DohDump DOH_NAMESPACE(Dump) -#define DohLen DOH_NAMESPACE(Len) -#define DohHashval DOH_NAMESPACE(Hashval) -#define DohCmp DOH_NAMESPACE(Cmp) -#define DohEqual DOH_NAMESPACE(Equal) -#define DohIncref DOH_NAMESPACE(Incref) -#define DohCheckattr DOH_NAMESPACE(Checkattr) -#define DohSetattr DOH_NAMESPACE(Setattr) -#define DohDelattr DOH_NAMESPACE(Delattr) -#define DohKeys DOH_NAMESPACE(Keys) -#define DohSortedKeys DOH_NAMESPACE(SortedKeys) -#define DohGetInt DOH_NAMESPACE(GetInt) -#define DohGetDouble DOH_NAMESPACE(GetDouble) -#define DohGetChar DOH_NAMESPACE(GetChar) -#define DohSetChar DOH_NAMESPACE(SetChar) -#define DohSetInt DOH_NAMESPACE(SetInt) -#define DohSetDouble DOH_NAMESPACE(SetDouble) -#define DohSetVoid DOH_NAMESPACE(SetVoid) -#define DohGetVoid DOH_NAMESPACE(GetVoid) -#define DohGetitem DOH_NAMESPACE(Getitem) -#define DohSetitem DOH_NAMESPACE(Setitem) -#define DohDelitem DOH_NAMESPACE(Delitem) -#define DohInsertitem DOH_NAMESPACE(Insertitem) -#define DohDelslice DOH_NAMESPACE(Delslice) -#define DohWrite DOH_NAMESPACE(Write) -#define DohRead DOH_NAMESPACE(Read) -#define DohSeek DOH_NAMESPACE(Seek) -#define DohTell DOH_NAMESPACE(Tell) -#define DohGetc DOH_NAMESPACE(Getc) -#define DohPutc DOH_NAMESPACE(Putc) -#define DohUngetc DOH_NAMESPACE(Ungetc) -#define DohGetline DOH_NAMESPACE(Getline) -#define DohSetline DOH_NAMESPACE(Setline) -#define DohGetfile DOH_NAMESPACE(Getfile) -#define DohSetfile DOH_NAMESPACE(Setfile) -#define DohReplace DOH_NAMESPACE(Replace) -#define DohChop DOH_NAMESPACE(Chop) -#define DohGetmeta DOH_NAMESPACE(Getmeta) -#define DohSetmeta DOH_NAMESPACE(Setmeta) -#define DohDelmeta DOH_NAMESPACE(Delmeta) -#define DohEncoding DOH_NAMESPACE(Encoding) -#define DohPrintf DOH_NAMESPACE(Printf) -#define DohvPrintf DOH_NAMESPACE(vPrintf) -#define DohPrintv DOH_NAMESPACE(Printv) -#define DohReadline DOH_NAMESPACE(Readline) -#define DohIsMapping DOH_NAMESPACE(IsMapping) -#define DohIsSequence DOH_NAMESPACE(IsSequence) -#define DohIsString DOH_NAMESPACE(IsString) -#define DohIsFile DOH_NAMESPACE(IsFile) -#define DohNewString DOH_NAMESPACE(NewString) -#define DohNewStringEmpty DOH_NAMESPACE(NewStringEmpty) -#define DohNewStringWithSize DOH_NAMESPACE(NewStringWithSize) -#define DohNewStringf DOH_NAMESPACE(NewStringf) -#define DohStrcmp DOH_NAMESPACE(Strcmp) -#define DohStrncmp DOH_NAMESPACE(Strncmp) -#define DohStrstr DOH_NAMESPACE(Strstr) -#define DohStrchr DOH_NAMESPACE(Strchr) -#define DohNewFile DOH_NAMESPACE(NewFile) -#define DohNewFileFromFile DOH_NAMESPACE(NewFileFromFile) -#define DohNewFileFromFd DOH_NAMESPACE(NewFileFromFd) -#define DohFileErrorDisplay DOH_NAMESPACE(FileErrorDisplay) -#define DohCopyto DOH_NAMESPACE(Copyto) -#define DohNewList DOH_NAMESPACE(NewList) -#define DohNewHash DOH_NAMESPACE(NewHash) -#define DohNewVoid DOH_NAMESPACE(NewVoid) -#define DohSplit DOH_NAMESPACE(Split) -#define DohSplitLines DOH_NAMESPACE(SplitLines) -#define DohNone DOH_NAMESPACE(None) -#define DohCall DOH_NAMESPACE(Call) -#define DohObjMalloc DOH_NAMESPACE(ObjMalloc) -#define DohObjFree DOH_NAMESPACE(ObjFree) -#define DohMemoryDebug DOH_NAMESPACE(MemoryDebug) -#define DohStringType DOH_NAMESPACE(StringType) -#define DohListType DOH_NAMESPACE(ListType) -#define DohHashType DOH_NAMESPACE(HashType) -#define DohFileType DOH_NAMESPACE(FileType) -#define DohVoidType DOH_NAMESPACE(VoidType) -#define DohIterator DOH_NAMESPACE(Iterator) -#define DohFirst DOH_NAMESPACE(First) -#define DohNext DOH_NAMESPACE(Next) -#define DohMalloc DOH_NAMESPACE(Malloc) -#define DohRealloc DOH_NAMESPACE(Realloc) -#define DohCalloc DOH_NAMESPACE(Calloc) -#define DohFree DOH_NAMESPACE(Free) -#define DohSetExitHandler DOH_NAMESPACE(SetExitHandler) -#define DohExit DOH_NAMESPACE(Exit) -#endif - -#define DOH_MAJOR_VERSION 0 -#define DOH_MINOR_VERSION 1 - -typedef void DOH; - -/* - * With dynamic typing, all DOH objects are technically of type 'void *'. - * However, to clarify the reading of source code, the following symbolic - * names are used. - */ - -#define DOHString DOH -#define DOHList DOH -#define DOHHash DOH -#define DOHFile DOH -#define DOHVoid DOH -#define DOHString_or_char DOH -#define DOHObj_or_char DOH - -typedef const DOHString_or_char * const_String_or_char_ptr; -typedef const DOHString_or_char * DOHconst_String_or_char_ptr; - -#define DOH_BEGIN -1 -#define DOH_END -2 -#define DOH_CUR -3 -#define DOH_CURRENT -3 - -/* Iterator objects */ - -typedef struct { - void *key; /* Current key (if any) */ - void *item; /* Current item */ - void *object; /* Object being iterated over */ - void *_current; /* Internal use */ - int _index; /* Internal use */ -} DohIterator; - -/* Memory management */ - -/* Wrappers around malloc(), realloc() and calloc() which never return NULL. */ -extern void *DohMalloc(size_t size); -extern void *DohRealloc(void *ptr, size_t size); -extern void *DohCalloc(size_t n, size_t size); - -#ifndef DohFree -#define DohFree free -#endif - -extern int DohCheck(const DOH *ptr); /* Check if a DOH object */ -extern void DohIntern(DOH *); /* Intern an object */ - -/* Basic object methods. Common to most objects */ - -extern void DohDelete(DOH *obj); /* Delete an object */ -extern DOH *DohCopy(const DOH *obj); -extern void DohClear(DOH *obj); -extern DOHString *DohStr(const DOH *obj); -extern void *DohData(const DOH *obj); -extern int DohDump(const DOH *obj, DOHFile * out); -extern int DohLen(const DOH *obj); -extern int DohHashval(const DOH *obj); -extern int DohCmp(const DOH *obj1, const DOH *obj2); -extern int DohEqual(const DOH *obj1, const DOH *obj2); -extern void DohIncref(DOH *obj); - -/* Mapping methods */ - -extern DOH *DohGetattr(DOH *obj, const DOHString_or_char *name); -extern int DohSetattr(DOH *obj, const DOHString_or_char *name, const DOHObj_or_char * value); -extern int DohDelattr(DOH *obj, const DOHString_or_char *name); -extern int DohCheckattr(DOH *obj, const DOHString_or_char *name, const DOHString_or_char *value); -extern DOH *DohKeys(DOH *obj); -extern DOH *DohSortedKeys(DOH *obj, int (*cmp) (const DOH *, const DOH *)); -extern int DohGetInt(DOH *obj, const DOHString_or_char *name); -extern void DohSetInt(DOH *obj, const DOHString_or_char *name, int); -extern double DohGetDouble(DOH *obj, const DOHString_or_char *name); -extern void DohSetDouble(DOH *obj, const DOHString_or_char *name, double); -extern char *DohGetChar(DOH *obj, const DOHString_or_char *name); -extern void DohSetChar(DOH *obj, const DOH *name, char *value); -extern void *DohGetFlagAttr(DOH *obj, const DOHString_or_char *name); -extern int DohGetFlag(DOH *obj, const DOHString_or_char *name); -extern void DohSetFlagAttr(DOH *obj, const DOHString_or_char *name, const DOHString_or_char *attr); -extern void DohSetFlag(DOH *obj, const DOHString_or_char *name); -extern void *DohGetVoid(DOH *obj, const DOHString_or_char *name); -extern void DohSetVoid(DOH *obj, const DOHString_or_char *name, void *value); - -/* Sequence methods */ - -extern DOH *DohGetitem(DOH *obj, int index); -extern int DohSetitem(DOH *obj, int index, const DOHObj_or_char * value); -extern int DohDelitem(DOH *obj, int index); -extern int DohInsertitem(DOH *obj, int index, const DOHObj_or_char * value); -extern int DohDelslice(DOH *obj, int sindex, int eindex); - -/* File methods */ - -extern int DohWrite(DOHFile * obj, const void *buffer, int length); -extern int DohRead(DOHFile * obj, void *buffer, int length); -extern int DohSeek(DOHFile * obj, long offset, int whence); -extern long DohTell(DOHFile * obj); -extern int DohGetc(DOHFile * obj); -extern int DohPutc(int ch, DOHFile * obj); -extern int DohUngetc(int ch, DOHFile * obj); - - - -/* Iterators */ -extern DohIterator DohFirst(DOH *obj); -extern DohIterator DohNext(DohIterator x); - -/* Positional */ - -extern int DohGetline(const DOH *obj); -extern void DohSetline(DOH *obj, int line); -extern DOH *DohGetfile(const DOH *obj); -extern void DohSetfile(DOH *obj, DOH *file); - - /* String Methods */ - -extern int DohReplace(DOHString * src, const DOHString_or_char *token, const DOHString_or_char *rep, int flags); -extern void DohChop(DOHString * src); - -/* Meta-variables */ -extern DOH *DohGetmeta(DOH *, const DOH *); -extern int DohSetmeta(DOH *, const DOH *, const DOH *value); -extern int DohDelmeta(DOH *, const DOH *); - - /* Utility functions */ - -extern void DohEncoding(const char *name, DOH *(*fn) (DOH *s)); -extern int DohPrintf(DOHFile * obj, const char *format, ...); -extern int DohvPrintf(DOHFile * obj, const char *format, va_list ap); -extern int DohPrintv(DOHFile * obj, ...); -extern DOH *DohReadline(DOHFile * in); - - /* Miscellaneous */ - -extern int DohIsMapping(const DOH *obj); -extern int DohIsSequence(const DOH *obj); -extern int DohIsString(const DOH *obj); -extern int DohIsFile(const DOH *obj); - -extern void DohSetMaxHashExpand(int count); -extern int DohGetMaxHashExpand(void); -extern void DohSetmark(DOH *obj, int x); -extern int DohGetmark(DOH *obj); - -/* Set the function for DohExit() to call instead of exit(). - * - * The registered function can perform clean up, etc. It should simply - * return when done and then exit() will get called. Bear in mind that - * the handler function can be called after malloc() has failed, so it's - * a good idea for it to avoid allocating additional memory. - * - * The registered handler function is unregistered by DohExit() before calling - * it to avoid the potential for infinite loops. - * - * Note: This is sort of like C's atexit(), only for DohExit(). However - * only one function can be registered (setting a new function overrides the - * previous one) and the registered function is passed the exit status so can - * vary its actions based on that. - */ -extern void DohSetExitHandler(void (*new_handler)(int)); -extern void DohExit(int status); - -/* ----------------------------------------------------------------------------- - * Strings. - * ----------------------------------------------------------------------------- */ - -extern DOHString *DohNewStringEmpty(void); -extern DOHString *DohNewString(const DOHString_or_char *c); -extern DOHString *DohNewStringWithSize(const DOHString_or_char *c, int len); -extern DOHString *DohNewStringf(const DOHString_or_char *fmt, ...); - -extern int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2); -extern int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n); -extern char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2); -extern char *DohStrchr(const DOHString_or_char *s1, int ch); - -/* String replacement flags */ - -#define DOH_REPLACE_ANY 0x01 -#define DOH_REPLACE_NOQUOTE 0x02 -#define DOH_REPLACE_NOCOMMENT 0x04 -#define DOH_REPLACE_ID 0x08 -#define DOH_REPLACE_FIRST 0x10 -#define DOH_REPLACE_ID_BEGIN 0x20 -#define DOH_REPLACE_ID_END 0x40 -#define DOH_REPLACE_NUMBER_END 0x80 - -#define Replaceall(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ANY) -#define Replaceid(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ID) - -/* ----------------------------------------------------------------------------- - * Files - * ----------------------------------------------------------------------------- */ - -extern DOHFile *DohNewFile(DOHString *filename, const char *mode, DOHList *outfiles); -extern DOHFile *DohNewFileFromFile(FILE *f); -extern DOHFile *DohNewFileFromFd(int fd); -extern void DohFileErrorDisplay(DOHString * filename); -extern int DohCopyto(DOHFile * input, DOHFile * output); -extern void DohCloseAllOpenFiles(void); - - -/* ----------------------------------------------------------------------------- - * List - * ----------------------------------------------------------------------------- */ - -extern DOHList *DohNewList(void); -extern void DohSortList(DOH *lo, int (*cmp) (const DOH *, const DOH *)); - -/* ----------------------------------------------------------------------------- - * Hash - * ----------------------------------------------------------------------------- */ - -extern DOHHash *DohNewHash(void); - -/* ----------------------------------------------------------------------------- - * Void - * ----------------------------------------------------------------------------- */ - -extern DOHVoid *DohNewVoid(void *ptr, void (*del) (void *)); -extern DOHList *DohSplit(DOHFile * input, char ch, int nsplits); -extern DOHList *DohSplitLines(DOHFile * input); -extern DOH *DohNone; - -/* Helper union for converting between function and object pointers. */ -typedef union DohFuncPtr { - void* p; - DOH *(*func)(DOH *); -} DohFuncPtr_t; - -extern void DohMemoryDebug(void); - -#ifndef DOH_LONG_NAMES -/* Macros to invoke the above functions. Includes the location of - the caller to simplify debugging if something goes wrong */ - -#define Delete DohDelete -#define Copy DohCopy -#define Clear DohClear -#define Str DohStr -#define Dump DohDump -#define Getattr DohGetattr -#define Setattr DohSetattr -#define Delattr DohDelattr -#define Checkattr DohCheckattr -#define Hashval DohHashval -#define Getitem DohGetitem -#define Setitem DohSetitem -#define Delitem DohDelitem -#define Insert DohInsertitem -#define Delslice DohDelslice -#define Append(s,x) DohInsertitem(s,DOH_END,x) -#define Push(s,x) DohInsertitem(s,DOH_BEGIN,x) -#define Len DohLen -#define Data DohData -#define Char(X) ((char *) Data(X)) -#define Cmp DohCmp -#define Equal DohEqual -#define Setline DohSetline -#define Getline DohGetline -#define Setfile DohSetfile -#define Getfile DohGetfile -#define Write DohWrite -#define Read DohRead -#define Seek DohSeek -#define Tell DohTell -#define Printf DohPrintf -#define Printv DohPrintv -#define Getc DohGetc -#define Putc DohPutc -#define Ungetc DohUngetc - -/* #define StringPutc DohStringPutc */ -/* #define StringGetc DohStringGetc */ -/* #define StringUngetc DohStringUngetc */ -/* #define StringAppend Append */ -/* #define StringLen DohStringLen */ -/* #define StringChar DohStringChar */ -/* #define StringEqual DohStringEqual */ - -#define vPrintf DohvPrintf -#define GetInt DohGetInt -#define GetDouble DohGetDouble -#define GetChar DohGetChar -#define GetVoid DohGetVoid -#define GetFlagAttr DohGetFlagAttr -#define GetFlag DohGetFlag -#define SetInt DohSetInt -#define SetDouble DohSetDouble -#define SetChar DohSetattr -#define SetVoid DohSetVoid -#define SetFlagAttr DohSetFlagAttr -#define SetFlag DohSetFlag -#define UnsetFlag(o,n) DohSetFlagAttr(o,n,NULL) -#define ClearFlag(o,n) DohSetFlagAttr(o,n,"") -#define Readline DohReadline -#define Replace DohReplace -#define Chop DohChop -#define Getmeta DohGetmeta -#define Setmeta DohSetmeta -#define Delmeta DohDelmeta -#define NewString DohNewString -#define NewStringEmpty DohNewStringEmpty -#define NewStringWithSize DohNewStringWithSize -#define NewStringf DohNewStringf -#define NewHash DohNewHash -#define NewList DohNewList -#define NewFile DohNewFile -#define NewFileFromFile DohNewFileFromFile -#define NewFileFromFd DohNewFileFromFd -#define FileErrorDisplay DohFileErrorDisplay -#define NewVoid DohNewVoid -#define Keys DohKeys -#define SortedKeys DohSortedKeys -#define Strcmp DohStrcmp -#define Strncmp DohStrncmp -#define Strstr DohStrstr -#define Strchr DohStrchr -#define Copyto DohCopyto -#define CloseAllOpenFiles DohCloseAllOpenFiles -#define Split DohSplit -#define SplitLines DohSplitLines -#define Setmark DohSetmark -#define Getmark DohGetmark -#define SetMaxHashExpand DohSetMaxHashExpand -#define GetMaxHashExpand DohGetMaxHashExpand -#define None DohNone -#define Call DohCall -#define First DohFirst -#define Next DohNext -#define Iterator DohIterator -#define SortList DohSortList -#define Malloc DohMalloc -#define Realloc DohRealloc -#define Calloc DohCalloc -#define Free DohFree -#define SetExitHandler DohSetExitHandler -#define Exit DohExit -#endif - -#ifdef NIL -#undef NIL -#endif - -#define NIL (char *) NULL - -/* Defines to allow use of poisoned identifiers. - * - * For DOH-internal use only! - */ -#define doh_internal_calloc calloc -#define doh_internal_exit exit -/* doh_internal_free not needed as Free() is a macro defined above. */ -#define doh_internal_malloc malloc -#define doh_internal_realloc realloc - -#if defined __GNUC__ && defined DOH_POISON -/* Use Malloc(), Realloc(), Calloc(), and Free() instead (which will exit with - * an error rather than return NULL). - */ -# ifndef DOH_NO_POISON_MALLOC_FREE -/* This works around bison's template checking if malloc and free are defined, - * which triggers GCC's poison checks. - */ -# pragma GCC poison malloc free -# endif -# pragma GCC poison realloc calloc -/* Use Exit() instead (which will remove output files on error). */ -# pragma GCC poison abort exit -#endif - -#endif /* SWIG_DOH_H */ diff --git a/contrib/tools/swig/Source/DOH/dohint.h b/contrib/tools/swig/Source/DOH/dohint.h deleted file mode 100644 index b637debd26e..00000000000 --- a/contrib/tools/swig/Source/DOH/dohint.h +++ /dev/null @@ -1,131 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * dohint.h - * - * This file describes internally managed objects. - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_DOHINT_H -#define SWIG_DOHINT_H - -#include "doh.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <ctype.h> -#include <stdarg.h> - -/* Hash objects */ -typedef struct { - DOH *(*doh_getattr) (DOH *obj, DOH *name); /* Get attribute */ - int (*doh_setattr) (DOH *obj, DOH *name, DOH *value); /* Set attribute */ - int (*doh_delattr) (DOH *obj, DOH *name); /* Del attribute */ - DOH *(*doh_keys) (DOH *obj); /* All keys as a list */ -} DohHashMethods; - -/* List objects */ -typedef struct { - DOH *(*doh_getitem) (DOH *obj, int index); /* Get item */ - int (*doh_setitem) (DOH *obj, int index, DOH *value); /* Set item */ - int (*doh_delitem) (DOH *obj, int index); /* Delete item */ - int (*doh_insitem) (DOH *obj, int index, DOH *value); /* Insert item */ - int (*doh_delslice) (DOH *obj, int sindex, int eindex); /* Delete slice */ -} DohListMethods; - -/* File methods */ -typedef struct { - int (*doh_read) (DOH *obj, void *buffer, int nbytes); /* Read bytes */ - int (*doh_write) (DOH *obj, const void *buffer, int nbytes); /* Write bytes */ - int (*doh_putc) (DOH *obj, int ch); /* Put character */ - int (*doh_getc) (DOH *obj); /* Get character */ - int (*doh_ungetc) (DOH *obj, int ch); /* Unget character */ - int (*doh_seek) (DOH *obj, long offset, int whence); /* Seek */ - long (*doh_tell) (DOH *obj); /* Tell */ -} DohFileMethods; - -/* String methods */ -typedef struct { - int (*doh_replace) (DOH *obj, const DOHString_or_char *old, const DOHString_or_char *rep, int flags); - void (*doh_chop) (DOH *obj); -} DohStringMethods; - -/* ----------------------------------------------------------------------------- - * DohObjInfo - * ----------------------------------------------------------------------------- */ - -typedef struct DohObjInfo { - const char *objname; /* Object name */ - - /* Basic object methods */ - void (*doh_del) (DOH *obj); /* Delete object */ - DOH *(*doh_copy) (DOH *obj); /* Copy and object */ - void (*doh_clear) (DOH *obj); /* Clear an object */ - - /* I/O methods */ - DOH *(*doh_str) (DOH *obj); /* Make a full string */ - void *(*doh_data) (DOH *obj); /* Return raw data */ - int (*doh_dump) (DOH *obj, DOH *out); /* Serialize on out */ - - /* Length and hash values */ - int (*doh_len) (DOH *obj); - int (*doh_hashval) (DOH *obj); - - /* Compare */ - int (*doh_cmp) (DOH *obj1, DOH *obj2); - - /* Equal */ - int (*doh_equal) (DOH *obj1, DOH *obj2); - - /* Iterators */ - DohIterator (*doh_first) (DOH *obj); - DohIterator (*doh_next) (DohIterator); - - /* Positional */ - void (*doh_setfile) (DOH *obj, DOHString_or_char *file); - DOH *(*doh_getfile) (DOH *obj); - void (*doh_setline) (DOH *obj, int line); - int (*doh_getline) (DOH *obj); - - DohHashMethods *doh_hash; /* Hash methods */ - DohListMethods *doh_list; /* List methods */ - DohFileMethods *doh_file; /* File methods */ - DohStringMethods *doh_string; /* String methods */ - void *doh_reserved; /* Reserved */ - void *clientdata; /* User data */ -} DohObjInfo; - -typedef struct { - void *data; /* Data pointer */ - DohObjInfo *type; - void *meta; /* Meta data */ - unsigned int flag_intern:1; /* Interned object */ - unsigned int flag_marked:1; /* Mark flag. Used to avoid recursive loops in places */ - unsigned int flag_user:1; /* User flag */ - unsigned int flag_usermark:1; /* User marked */ - unsigned int refcount:28; /* Reference count (max 16 million) */ -} DohBase; - -/* Macros for decrefing and increfing (safe for null objects). */ - -#define Decref(a) if (a) ((DohBase *) a)->refcount-- -#define Incref(a) if (a) ((DohBase *) a)->refcount++ -#define Refcount(a) ((DohBase *) a)->refcount - -/* Macros for manipulating objects in a safe manner */ -#define ObjData(a) ((DohBase *)a)->data -#define ObjSetMark(a,x) ((DohBase *)a)->flag_marked = x -#define ObjGetMark(a) ((DohBase *)a)->flag_marked -#define ObjType(a) ((DohBase *)a)->type - -extern DOH *DohObjMalloc(DohObjInfo *type, void *data); /* Allocate a DOH object */ -extern void DohObjFree(DOH *ptr); /* Free a DOH object */ - -#endif /* SWIG_DOHINT_H */ diff --git a/contrib/tools/swig/Source/DOH/file.c b/contrib/tools/swig/Source/DOH/file.c deleted file mode 100644 index 4bcf5d5e1d7..00000000000 --- a/contrib/tools/swig/Source/DOH/file.c +++ /dev/null @@ -1,342 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * file.c - * - * This file implements a file-like object that can be built around an - * ordinary FILE * or integer file descriptor. - * ----------------------------------------------------------------------------- */ - -#include "dohint.h" - -#ifdef DOH_INTFILE -#include <unistd.h> -#endif -#include <errno.h> - -typedef struct { - FILE *filep; - int fd; - int closeondel; -} DohFile; - -/* ----------------------------------------------------------------------------- - * open_files_list_instance - * open_files_list_add - * open_files_list_remove - * - * Singleton list containing all the files that have been opened by DohNewFile. - * Open file pointers are held in the list as strings so as to not affect the - * reference count of the underlying DOH objects. - * ----------------------------------------------------------------------------- */ - -static DOHList *open_files_list_instance(void) { - static DOHList *all_open_files = 0; - if (!all_open_files) - all_open_files = DohNewList(); - return all_open_files; -} - -static void open_files_list_add(DohFile *f) { - DOHList *all_open_files = open_files_list_instance(); - DOHString *sf = NewStringf("%p", f); - Append(all_open_files, sf); - Delete(sf); -} - -static void open_files_list_remove(DohFile *f) { - int i; - int removed = 0; - DOHList *all_open_files = open_files_list_instance(); - DOHString *sf = NewStringf("%p", f); - for (i = 0; i < DohLen(all_open_files); i++) { - DOHString *sf_i = Getitem(all_open_files, i); - if (Strcmp(sf, sf_i) == 0) { - DohDelitem(all_open_files, i); - removed = 1; - break; - } - } - Delete(sf); - assert(removed); - (void)removed; -} - -/* ----------------------------------------------------------------------------- - * DohCloseAllOpenFiles() - * - * Close all opened files, to be called on program termination - * ----------------------------------------------------------------------------- */ - -void DohCloseAllOpenFiles(void) { - int i; - DOHList *all_open_files = open_files_list_instance(); - for (i = 0; i < DohLen(all_open_files); i++) { - DohFile *f = 0; - DOHString *sf = Getitem(all_open_files, i); - int check = sscanf(Char(sf), "%p", (void **)&f); - assert(check == 1); - (void)check; - if (f->closeondel) { - if (f->filep) { - check = fclose(f->filep); - assert(check == 0); - } - f->closeondel = 0; - f->filep = 0; - } - } - DohClear(all_open_files); -} - -/* ----------------------------------------------------------------------------- - * DelFile() - * ----------------------------------------------------------------------------- */ - -static void DelFile(DOH *fo) { - DohFile *f = (DohFile *) ObjData(fo); - if (f->closeondel) { - if (f->filep) { - fclose(f->filep); - } -#ifdef DOH_INTFILE - if (f->fd) { - close(f->fd); - } -#endif - open_files_list_remove(f); - } - DohFree(f); -} - -/* ----------------------------------------------------------------------------- - * File_read() - * ----------------------------------------------------------------------------- */ - -static int File_read(DOH *fo, void *buffer, int len) { - DohFile *f = (DohFile *) ObjData(fo); - - if (f->filep) { - return (int)fread(buffer, 1, len, f->filep); - } else if (f->fd) { -#ifdef DOH_INTFILE - return read(f->fd, buffer, len); -#endif - } - return -1; -} - -/* ----------------------------------------------------------------------------- - * File_write() - * ----------------------------------------------------------------------------- */ - -static int File_write(DOH *fo, const void *buffer, int len) { - DohFile *f = (DohFile *) ObjData(fo); - if (f->filep) { - int ret = (int) fwrite(buffer, 1, len, f->filep); - int err = (ret != len) ? ferror(f->filep) : 0; - return err ? -1 : ret; - } else if (f->fd) { -#ifdef DOH_INTFILE - return write(f->fd, buffer, len); -#endif - } - return -1; -} - -/* ----------------------------------------------------------------------------- - * File_seek() - * ----------------------------------------------------------------------------- */ - -static int File_seek(DOH *fo, long offset, int whence) { - DohFile *f = (DohFile *) ObjData(fo); - if (f->filep) { - return fseek(f->filep, offset, whence); - } else if (f->fd) { -#ifdef DOH_INTFILE - return lseek(f->fd, offset, whence); -#endif - } - return -1; -} - -/* ----------------------------------------------------------------------------- - * File_tell() - * ----------------------------------------------------------------------------- */ - -static long File_tell(DOH *fo) { - DohFile *f = (DohFile *) ObjData(fo); - if (f->filep) { - return ftell(f->filep); - } else if (f->fd) { -#ifdef DOH_INTFILE - return lseek(f->fd, 0, SEEK_CUR); -#endif - } - return -1; -} - -/* ----------------------------------------------------------------------------- - * File_putc() - * ----------------------------------------------------------------------------- */ - -static int File_putc(DOH *fo, int ch) { - DohFile *f = (DohFile *) ObjData(fo); - if (f->filep) { - return fputc(ch, f->filep); - } else if (f->fd) { -#ifdef DOH_INTFILE - char c; - c = (char) ch; - return write(f->fd, &c, 1); -#endif - } - return -1; -} - -/* ----------------------------------------------------------------------------- - * File_getc() - * ----------------------------------------------------------------------------- */ - -static int File_getc(DOH *fo) { - DohFile *f = (DohFile *) ObjData(fo); - if (f->filep) { - return fgetc(f->filep); - } else if (f->fd) { -#ifdef DOH_INTFILE - unsigned char c; - if (read(f->fd, &c, 1) < 0) - return EOF; - return c; -#endif - } - return EOF; -} - -/* ----------------------------------------------------------------------------- - * File_ungetc() - * - * Put a character back onto the input - * ----------------------------------------------------------------------------- */ - -static int File_ungetc(DOH *fo, int ch) { - DohFile *f = (DohFile *) ObjData(fo); - if (f->filep) { - return ungetc(ch, f->filep); - } else if (f->fd) { -#ifdef DOH_INTFILE - /* Not implemented yet */ -#endif - } - return -1; -} - -static DohFileMethods FileFileMethods = { - File_read, - File_write, - File_putc, - File_getc, - File_ungetc, - File_seek, - File_tell, -}; - -static DohObjInfo DohFileType = { - "DohFile", /* objname */ - DelFile, /* doh_del */ - 0, /* doh_copy */ - 0, /* doh_clear */ - 0, /* doh_str */ - 0, /* doh_data */ - 0, /* doh_dump */ - 0, /* doh_len */ - 0, /* doh_hash */ - 0, /* doh_cmp */ - 0, /* doh_equal */ - 0, /* doh_first */ - 0, /* doh_next */ - 0, /* doh_setfile */ - 0, /* doh_getfile */ - 0, /* doh_setline */ - 0, /* doh_getline */ - 0, /* doh_mapping */ - 0, /* doh_sequence */ - &FileFileMethods, /* doh_file */ - 0, /* doh_string */ - 0, /* doh_callable */ - 0, /* doh_position */ -}; - -/* ----------------------------------------------------------------------------- - * NewFile() - * - * Create a new file from a given filename and mode. - * If newfiles is non-zero, the filename is added to the list of new files. - * ----------------------------------------------------------------------------- */ - -DOH *DohNewFile(DOHString *filename, const char *mode, DOHList *newfiles) { - DohFile *f; - DOH *obj; - FILE *file; - char *filen; - - filen = Char(filename); - file = fopen(filen, mode); - if (!file) - return 0; - - f = (DohFile *) DohMalloc(sizeof(DohFile)); - if (newfiles) - Append(newfiles, filename); - f->filep = file; - f->fd = 0; - f->closeondel = 1; - obj = DohObjMalloc(&DohFileType, f); - open_files_list_add(f); - return obj; -} - -/* ----------------------------------------------------------------------------- - * NewFileFromFile() - * - * Create a file object from an already open FILE *. - * ----------------------------------------------------------------------------- */ - -DOH *DohNewFileFromFile(FILE *file) { - DohFile *f; - f = (DohFile *) DohMalloc(sizeof(DohFile)); - f->filep = file; - f->fd = 0; - f->closeondel = 0; - return DohObjMalloc(&DohFileType, f); -} - -/* ----------------------------------------------------------------------------- - * NewFileFromFd() - * - * Create a file object from an already open FILE *. - * ----------------------------------------------------------------------------- */ - -DOH *DohNewFileFromFd(int fd) { - DohFile *f; - f = (DohFile *) DohMalloc(sizeof(DohFile)); - f->filep = 0; - f->fd = fd; - f->closeondel = 0; - return DohObjMalloc(&DohFileType, f); -} - -/* ----------------------------------------------------------------------------- - * FileErrorDisplay() - * - * Display cause of one of the NewFile functions failing. - * ----------------------------------------------------------------------------- */ - -void DohFileErrorDisplay(DOHString * filename) { - Printf(stderr, "Unable to open file %s: %s\n", filename, strerror(errno)); -} diff --git a/contrib/tools/swig/Source/DOH/fio.c b/contrib/tools/swig/Source/DOH/fio.c deleted file mode 100644 index 972fb23df99..00000000000 --- a/contrib/tools/swig/Source/DOH/fio.c +++ /dev/null @@ -1,599 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * fio.c - * - * This file implements a number of standard I/O operations included - * formatted output, readline, and splitting. - * ----------------------------------------------------------------------------- */ - -#include "dohint.h" - -#define OBUFLEN 512 - -static DOH *encodings = 0; /* Encoding hash */ - -/* ----------------------------------------------------------------------------- - * Writen() - * - * Writes N characters of output and retries until all characters are - * written. This is useful should a write operation encounter a spurious signal. - * ----------------------------------------------------------------------------- */ - -static int Writen(DOH *out, void *buffer, int len) { - int nw = len, ret; - char *cb = (char *) buffer; - while (nw) { - ret = Write(out, cb, nw); - if (ret < 0) - return -1; - nw = nw - ret; - cb += ret; - } - return len; -} - -/* ----------------------------------------------------------------------------- - * DohEncoding() - * - * Registers a new printf encoding method. An encoder function should accept - * two file-like objects and operate as a filter. - * ----------------------------------------------------------------------------- */ - -void DohEncoding(const char *name, DOH *(*fn) (DOH *s)) { - DohFuncPtr_t fp; - - if (!encodings) - encodings = NewHash(); - - fp.func = fn; - Setattr(encodings, (void *) name, NewVoid(fp.p, 0)); -} - -/* internal function for processing an encoding */ -static DOH *encode(char *name, DOH *s) { - DOH *handle, *ns; - DohFuncPtr_t fp; - long pos; - char *cfmt = strchr(name, ':'); - DOH *tmp = 0; - if (cfmt) { - tmp = NewString(cfmt + 1); - Append(tmp, s); - Setfile(tmp, Getfile((DOH *) s)); - Setline(tmp, Getline((DOH *) s)); - *cfmt = '\0'; - } - if (!encodings || !(handle = Getattr(encodings, name))) { - return Copy(s); - } - if (tmp) - s = tmp; - pos = Tell(s); - Seek(s, 0, SEEK_SET); - - fp.p = Data(handle); - ns = (*fp.func) (s); - assert(pos != -1); - (void)Seek(s, pos, SEEK_SET); - if (tmp) - Delete(tmp); - return ns; -} - -/* ----------------------------------------------------------------------------- - * DohvPrintf() - * - * DOH implementation of printf. Output can be directed to any file-like object - * including bare FILE * objects. The same formatting codes as printf are - * recognized with two extensions: - * - * %s - Prints a "char *" or the string representation of any - * DOH object. This will implicitly result in a call to - * Str(obj). - * - * %(encoder)* - Filters the output through an encoding function registered - * with DohEncoder(). - * - * Note: This function is not particularly memory efficient with large strings. - * It's better to use Dump() or some other method instead. - * ----------------------------------------------------------------------------- */ - -int DohvPrintf(DOH *so, const char *format, va_list ap) { - static const char *fmt_codes = "dioxXucsSfeEgGpn"; - int state = 0; - const char *p = format; - char newformat[256]; - char obuffer[OBUFLEN]; - char *fmt = 0; - char temp[64]; - int widthval = 0; - int precval = 0; - int maxwidth; - char *w = 0; - int ivalue; - double dvalue; - void *pvalue; - char *stemp; - int nbytes = 0; - char encoder[128], *ec = 0; - int plevel = 0; - - memset(newformat, 0, sizeof(newformat)); - - while (*p) { - switch (state) { - case 0: /* Ordinary text */ - if (*p != '%') { - Putc(*p, so); - nbytes++; - } else { - fmt = newformat; - widthval = 0; - precval = 0; - *(fmt++) = *p; - encoder[0] = 0; - state = 10; - } - break; - case 10: /* Look for a width and precision */ - if (isdigit((int) *p) && (*p != '0')) { - w = temp; - *(w++) = *p; - *(fmt++) = *p; - state = 20; - } else if (strchr(fmt_codes, *p)) { - /* Got one of the formatting codes */ - p--; - state = 100; - } else if (*p == '*') { - /* Width field is specified in the format list */ - widthval = va_arg(ap, int); - sprintf(temp, "%d", widthval); - for (w = temp; *w; w++) { - *(fmt++) = *w; - } - state = 30; - } else if (*p == '%') { - Putc(*p, so); - fmt = newformat; - nbytes++; - state = 0; - } else if (*p == '(') { - ++plevel; - ec = encoder; - state = 60; - } else { - *(fmt++) = *p; - } - break; - - case 20: /* Hmmm. At the start of a width field */ - if (isdigit((int) *p)) { - *(w++) = *p; - *(fmt++) = *p; - } else if (strchr(fmt_codes, *p)) { - /* Got one of the formatting codes */ - /* Figure out width */ - *w = 0; - widthval = atoi(temp); - p--; - state = 100; - } else if (*p == '.') { - *w = 0; - widthval = atoi(temp); - w = temp; - *(fmt++) = *p; - state = 40; - } else { - /* ??? */ - *w = 0; - widthval = atoi(temp); - state = 50; - } - break; - - case 30: /* Parsed a width from an argument. Look for a . */ - if (*p == '.') { - w = temp; - *(fmt++) = *p; - state = 40; - } else if (strchr(fmt_codes, *p)) { - /* Got one of the formatting codes */ - /* Figure out width */ - p--; - state = 100; - } else { - /* hmmm. Something else. */ - state = 50; - } - break; - - case 40: - /* Start of precision expected */ - if (isdigit((int) *p) && (*p != '0')) { - *(fmt++) = *p; - *(w++) = *p; - state = 41; - } else if (*p == '*') { - /* Precision field is specified in the format list */ - precval = va_arg(ap, int); - sprintf(temp, "%d", precval); - for (w = temp; *w; w++) { - *(fmt++) = *w; - } - state = 50; - } else if (strchr(fmt_codes, *p)) { - p--; - state = 100; - } else { - *(fmt++) = *p; - state = 50; - } - break; - case 41: - if (isdigit((int) *p)) { - *(fmt++) = *p; - *(w++) = *p; - } else if (strchr(fmt_codes, *p)) { - /* Got one of the formatting codes */ - /* Figure out width */ - *w = 0; - precval = atoi(temp); - p--; - state = 100; - } else { - *w = 0; - precval = atoi(temp); - *(fmt++) = *p; - state = 50; - } - break; - /* Hang out, wait for format specifier */ - case 50: - if (strchr(fmt_codes, *p)) { - p--; - state = 100; - } else { - *(fmt++) = *p; - } - break; - - /* Got an encoding header */ - case 60: - if (*p == '(') { - ++plevel; - *ec = *p; - ec++; - } else if (*p == ')') { - --plevel; - if (plevel <= 0) { - *ec = 0; - state = 10; - } else { - *ec = *p; - ec++; - } - } else { - *ec = *p; - ec++; - } - break; - case 100: - /* Got a formatting code */ - if (widthval < precval) - maxwidth = precval; - else - maxwidth = widthval; - if ((*p == 's') || (*p == 'S')) { /* Null-Terminated string */ - DOH *doh; - DOH *Sval; - DOH *enc = 0; - doh = va_arg(ap, DOH *); - if (DohCheck(doh)) { - /* Is a DOH object. */ - if (DohIsString(doh)) { - Sval = doh; - } else { - Sval = Str(doh); - } - if (strlen(encoder)) { - enc = encode(encoder, Sval); - maxwidth = maxwidth + (int)strlen(newformat) + Len(enc); - } else { - maxwidth = maxwidth + (int)strlen(newformat) + Len(Sval); - } - *(fmt++) = 's'; - *fmt = 0; - if ((maxwidth + 1) < OBUFLEN) { - stemp = obuffer; - } else { - stemp = (char *) DohMalloc(maxwidth + 1); - } - if (enc) { - nbytes += sprintf(stemp, newformat, Data(enc)); - } else { - nbytes += sprintf(stemp, newformat, Data(Sval)); - } - if (Writen(so, stemp, (int)strlen(stemp)) < 0) - return -1; - if ((DOH *) Sval != doh) { - Delete(Sval); - } - if (enc) - Delete(enc); - if (*p == 'S') { - Delete(doh); - } - if (stemp != obuffer) { - DohFree(stemp); - } - } else { - if (!doh) - doh = (char *) ""; - - if (strlen(encoder)) { - DOH *s = NewString(doh); - Seek(s, 0, SEEK_SET); - enc = encode(encoder, s); - Delete(s); - doh = Char(enc); - } else { - enc = 0; - } - maxwidth = maxwidth + (int)strlen(newformat) + (int)strlen((char *) doh); - *(fmt++) = 's'; - *fmt = 0; - if ((maxwidth + 1) < OBUFLEN) { - stemp = obuffer; - } else { - stemp = (char *) DohMalloc(maxwidth + 1); - } - nbytes += sprintf(stemp, newformat, doh); - if (Writen(so, stemp, (int)strlen(stemp)) < 0) - return -1; - if (stemp != obuffer) { - DohFree(stemp); - } - if (enc) - Delete(enc); - } - } else { - *(fmt++) = *p; - *fmt = 0; - maxwidth = maxwidth + (int)strlen(newformat) + 64; - - /* Only allocate a buffer if it is too big to fit. Shouldn't have to do - this very often */ - - if (maxwidth < OBUFLEN) - stemp = obuffer; - else - stemp = (char *) DohMalloc(maxwidth + 1); - switch (*p) { - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - case 'c': - ivalue = va_arg(ap, int); - nbytes += sprintf(stemp, newformat, ivalue); - break; - case 'f': - case 'g': - case 'e': - case 'E': - case 'G': - dvalue = va_arg(ap, double); - nbytes += sprintf(stemp, newformat, dvalue); - break; - case 'p': - pvalue = va_arg(ap, void *); - nbytes += sprintf(stemp, newformat, pvalue); - break; - default: - break; - } - if (Writen(so, stemp, (int)strlen(stemp)) < 0) - return -1; - if (stemp != obuffer) - DohFree(stemp); - } - state = 0; - break; - } - p++; - } - if (state) { - int r; - *fmt = 0; - r = Writen(so, fmt, (int)strlen(fmt)); - if (r < 0) - return -1; - nbytes += r; - } - return nbytes; -} - -/* ----------------------------------------------------------------------------- - * DohPrintf() - * - * Variable length argument entry point to Printf - * ----------------------------------------------------------------------------- */ - -int DohPrintf(DOH *obj, const char *format, ...) { - va_list ap; - int ret; - va_start(ap, format); - ret = DohvPrintf(obj, format, ap); - va_end(ap); - return ret; -} - -/* ----------------------------------------------------------------------------- - * DohPrintv() - * - * Print a null-terminated variable length list of DOH objects - * ----------------------------------------------------------------------------- */ - -int DohPrintv(DOHFile * f, ...) { - va_list ap; - int ret = 0; - DOH *obj; - va_start(ap, f); - while (1) { - obj = va_arg(ap, void *); - if ((!obj) || (obj == DohNone)) - break; - if (DohCheck(obj)) { - ret += DohDump(obj, f); - } else { - ret += DohWrite(f, obj, (int)strlen((char *) obj)); - } - } - va_end(ap); - return ret; -} - -/* ----------------------------------------------------------------------------- - * DohCopyto() - * - * Copies all of the input from an input stream to an output stream. Returns the - * number of bytes copied. - * ----------------------------------------------------------------------------- */ - -int DohCopyto(DOH *in, DOH *out) { - int nbytes = 0, ret; - int nwrite = 0, wret; - char *cw; - char buffer[16384]; - - if ((!in) || (!out)) - return 0; - while (1) { - ret = Read(in, buffer, 16384); - if (ret > 0) { - nwrite = ret; - cw = buffer; - while (nwrite) { - wret = Write(out, cw, nwrite); - if (wret < 0) { - nbytes = -1; - break; - } - nwrite = nwrite - wret; - cw += wret; - } - nbytes += ret; - } else { - break; - } - } - return nbytes; -} - - -/* ----------------------------------------------------------------------------- - * DohSplit() - * - * Split an input stream into a list of strings delimited by the specified - * character. Optionally accepts a maximum number of splits to perform. - * ----------------------------------------------------------------------------- */ - -DOH *DohSplit(DOH *in, char ch, int nsplits) { - DOH *list; - DOH *str; - int c; - - list = NewList(); - - if (DohIsString(in)) { - Seek(in, 0, SEEK_SET); - } - - while (1) { - str = NewStringEmpty(); - do { - c = Getc(in); - } while ((c != EOF) && (c == ch)); - if (c != EOF) { - Putc(c, str); - while (1) { - c = Getc(in); - if ((c == EOF) || ((c == ch) && (nsplits != 0))) - break; - Putc(c, str); - } - nsplits--; - } - Append(list, str); - Delete(str); - if (c == EOF) - break; - } - return list; -} - -/* ----------------------------------------------------------------------------- - * DohSplitLines() - * - * Split an input stream into a list of strings delimited by newline characters. - * ----------------------------------------------------------------------------- */ - -DOH *DohSplitLines(DOH *in) { - DOH *list; - DOH *str; - int c = 0; - - list = NewList(); - - if (DohIsString(in)) { - Seek(in, 0, SEEK_SET); - } - - while (c != EOF) { - str = NewStringEmpty(); - while ((c = Getc(in)) != '\n' && c != EOF) { - Putc(c, str); - } - Append(list, str); - Delete(str); - } - return list; -} - - -/* ----------------------------------------------------------------------------- - * DohReadline() - * - * Read a single input line and return it as a string. - * ----------------------------------------------------------------------------- */ - -DOH *DohReadline(DOH *in) { - char c; - int n = 0; - DOH *s = NewStringEmpty(); - while (1) { - if (Read(in, &c, 1) < 0) { - if (n == 0) { - Delete(s); - s = 0; - } - break; - } - if (c == '\n') - break; - if (c == '\r') - continue; - Putc(c, s); - n++; - } - return s; -} diff --git a/contrib/tools/swig/Source/DOH/hash.c b/contrib/tools/swig/Source/DOH/hash.c deleted file mode 100644 index b9d501e3c42..00000000000 --- a/contrib/tools/swig/Source/DOH/hash.c +++ /dev/null @@ -1,583 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * hash.c - * - * Implements a simple hash table object. - * ----------------------------------------------------------------------------- */ - -#include "dohint.h" - -extern DohObjInfo DohHashType; - -/* Hash node */ -typedef struct HashNode { - DOH *key; - DOH *object; - struct HashNode *next; -} HashNode; - -/* Hash object */ -typedef struct Hash { - DOH *file; - int line; - HashNode **hashtable; - int hashsize; - int nitems; -} Hash; - -/* Key interning structure */ -typedef struct KeyValue { - char *cstr; - DOH *sstr; - struct KeyValue *left; - struct KeyValue *right; -} KeyValue; - -static KeyValue *root = 0; -static int max_expand = 1; - -/* Find or create a key in the interned key table */ -static DOH *find_key(DOH *doh_c) { - char *c = (char *) doh_c; - KeyValue *r, *s; - int d = 0; - /* OK, sure, we use a binary tree for maintaining interned - symbols. Then we use their hash values for accessing secondary - hash tables. */ - r = root; - s = 0; - while (r) { - s = r; - d = strcmp(r->cstr, c); - if (d == 0) - return r->sstr; - if (d < 0) - r = r->left; - else - r = r->right; - } - /* fprintf(stderr,"Interning '%s'\n", c); */ - r = (KeyValue *) DohMalloc(sizeof(KeyValue)); - r->cstr = (char *) DohMalloc(strlen(c) + 1); - strcpy(r->cstr, c); - r->sstr = NewString(c); - DohIntern(r->sstr); - r->left = 0; - r->right = 0; - if (!s) { - root = r; - } else { - if (d < 0) - s->left = r; - else - s->right = r; - } - return r->sstr; -} - -#define HASH_INIT_SIZE 7 - -/* Create a new hash node */ -static HashNode *NewNode(DOH *k, void *obj) { - HashNode *hn = (HashNode *) DohMalloc(sizeof(HashNode)); - hn->key = k; - Incref(hn->key); - hn->object = obj; - Incref(obj); - hn->next = 0; - return hn; -} - -/* Delete a hash node */ -static void DelNode(HashNode *hn) { - Delete(hn->key); - Delete(hn->object); - DohFree(hn); -} - -/* ----------------------------------------------------------------------------- - * DelHash() - * - * Delete a hash table. - * ----------------------------------------------------------------------------- */ - -static void DelHash(DOH *ho) { - Hash *h = (Hash *) ObjData(ho); - HashNode *n, *next; - int i; - - for (i = 0; i < h->hashsize; i++) { - n = h->hashtable[i]; - while (n) { - next = n->next; - DelNode(n); - n = next; - } - } - DohFree(h->hashtable); - h->hashtable = 0; - h->hashsize = 0; - DohFree(h); -} - -/* ----------------------------------------------------------------------------- - * Hash_clear() - * - * Clear all of the entries in the hash table. - * ----------------------------------------------------------------------------- */ - -static void Hash_clear(DOH *ho) { - Hash *h = (Hash *) ObjData(ho); - HashNode *n, *next; - int i; - - for (i = 0; i < h->hashsize; i++) { - n = h->hashtable[i]; - while (n) { - next = n->next; - DelNode(n); - n = next; - } - h->hashtable[i] = 0; - } - h->nitems = 0; -} - -/* resize the hash table */ -static void resize(Hash *h) { - HashNode *n, *next, **table; - int oldsize, newsize; - int i, p, hv; - - if (h->nitems < 2 * h->hashsize) - return; - - /* Too big. We have to rescale everything now */ - oldsize = h->hashsize; - - /* Calculate a new size */ - newsize = 2 * oldsize + 1; - p = 3; - while (p < (newsize >> 1)) { - if (((newsize / p) * p) == newsize) { - newsize += 2; - p = 3; - continue; - } - p = p + 2; - } - - table = (HashNode **) DohCalloc(newsize, sizeof(HashNode *)); - - /* Walk down the old set of nodes and re-place */ - h->hashsize = newsize; - for (i = 0; i < oldsize; i++) { - n = h->hashtable[i]; - while (n) { - hv = Hashval(n->key) % newsize; - next = n->next; - n->next = table[hv]; - table[hv] = n; - n = next; - } - } - DohFree(h->hashtable); - h->hashtable = table; -} - -/* ----------------------------------------------------------------------------- - * Hash_setattr() - * - * Set an attribute in the hash table. Deletes the existing entry if it already - * exists. - * ----------------------------------------------------------------------------- */ - -static int Hash_setattr(DOH *ho, DOH *k, DOH *obj) { - int hv; - HashNode *n, *prev; - Hash *h = (Hash *) ObjData(ho); - - if (!obj) { - return DohDelattr(ho, k); - } - if (!DohCheck(k)) - k = find_key(k); - if (!DohCheck(obj)) { - obj = NewString((char *) obj); - Decref(obj); - } - hv = (Hashval(k)) % h->hashsize; - n = h->hashtable[hv]; - prev = 0; - while (n) { - if (Cmp(n->key, k) == 0) { - /* Node already exists. Just replace its contents */ - if (n->object == obj) { - /* Whoa. Same object. Do nothing */ - return 1; - } - Delete(n->object); - n->object = obj; - Incref(obj); - return 1; /* Return 1 to indicate a replacement */ - } else { - prev = n; - n = n->next; - } - } - /* Add this to the table */ - n = NewNode(k, obj); - if (prev) - prev->next = n; - else - h->hashtable[hv] = n; - h->nitems++; - resize(h); - return 0; -} - -/* ----------------------------------------------------------------------------- - * Hash_getattr() - * - * Get an attribute from the hash table. Returns 0 if it doesn't exist. - * ----------------------------------------------------------------------------- */ -typedef int (*binop) (DOH *obj1, DOH *obj2); - - -static DOH *Hash_getattr(DOH *h, DOH *k) { - DOH *obj = 0; - Hash *ho = (Hash *) ObjData(h); - DOH *ko = DohCheck(k) ? k : find_key(k); - int hv = Hashval(ko) % ho->hashsize; - DohObjInfo *k_type = ((DohBase*)ko)->type; - HashNode *n = ho->hashtable[hv]; - if (k_type->doh_equal) { - binop equal = k_type->doh_equal; - while (n) { - DohBase *nk = (DohBase *)n->key; - if ((k_type == nk->type) && equal(ko, nk)) obj = n->object; - n = n->next; - } - } else { - binop cmp = k_type->doh_cmp; - while (n) { - DohBase *nk = (DohBase *)n->key; - if ((k_type == nk->type) && (cmp(ko, nk) == 0)) obj = n->object; - n = n->next; - } - } - return obj; -} - -/* ----------------------------------------------------------------------------- - * Hash_delattr() - * - * Delete an object from the hash table. - * ----------------------------------------------------------------------------- */ - -static int Hash_delattr(DOH *ho, DOH *k) { - HashNode *n, *prev; - int hv; - Hash *h = (Hash *) ObjData(ho); - - if (!DohCheck(k)) - k = find_key(k); - hv = Hashval(k) % h->hashsize; - n = h->hashtable[hv]; - prev = 0; - while (n) { - if (Cmp(n->key, k) == 0) { - /* Found it, kill it */ - - if (prev) { - prev->next = n->next; - } else { - h->hashtable[hv] = n->next; - } - DelNode(n); - h->nitems--; - return 1; - } - prev = n; - n = n->next; - } - return 0; -} - -static DohIterator Hash_firstiter(DOH *ho) { - DohIterator iter; - Hash *h = (Hash *) ObjData(ho); - iter.object = ho; - iter._current = 0; - iter.item = 0; - iter.key = 0; - iter._index = 0; /* Index in hash table */ - while ((iter._index < h->hashsize) && !h->hashtable[iter._index]) - iter._index++; - - if (iter._index >= h->hashsize) { - return iter; - } - iter._current = h->hashtable[iter._index]; - iter.item = ((HashNode *) iter._current)->object; - iter.key = ((HashNode *) iter._current)->key; - - /* Actually save the next slot in the hash. This makes it possible to - delete the item being iterated over without trashing the universe */ - iter._current = ((HashNode *) iter._current)->next; - return iter; -} - -static DohIterator Hash_nextiter(DohIterator iter) { - Hash *h = (Hash *) ObjData(iter.object); - if (!iter._current) { - iter._index++; - while ((iter._index < h->hashsize) && !h->hashtable[iter._index]) { - iter._index++; - } - if (iter._index >= h->hashsize) { - iter.item = 0; - iter.key = 0; - iter._current = 0; - return iter; - } - iter._current = h->hashtable[iter._index]; - } - iter.key = ((HashNode *) iter._current)->key; - iter.item = ((HashNode *) iter._current)->object; - - /* Store the next node to iterator on */ - iter._current = ((HashNode *) iter._current)->next; - return iter; -} - -/* ----------------------------------------------------------------------------- - * Hash_keys() - * - * Return a list of keys - * ----------------------------------------------------------------------------- */ - -static DOH *Hash_keys(DOH *so) { - DOH *keys; - Iterator i; - - keys = NewList(); - for (i = First(so); i.key; i = Next(i)) { - Append(keys, i.key); - } - return keys; -} - -/* ----------------------------------------------------------------------------- - * DohSetMaxHashExpand() - * - * Controls how many Hash objects are displayed in full in Hash_str - * ----------------------------------------------------------------------------- */ - -void DohSetMaxHashExpand(int count) { - max_expand = count; -} - -/* ----------------------------------------------------------------------------- - * DohGetMaxHashExpand() - * - * Returns how many Hash objects are displayed in full in Hash_str - * ----------------------------------------------------------------------------- */ - -int DohGetMaxHashExpand(void) { - return max_expand; -} - -/* ----------------------------------------------------------------------------- - * Hash_str() - * - * Create a string representation of a hash table (mainly for debugging). - * ----------------------------------------------------------------------------- */ - -static DOH *Hash_str(DOH *ho) { - int i, j; - HashNode *n; - DOH *s; - static int expanded = 0; - static const char *tab = " "; - Hash *h = (Hash *) ObjData(ho); - - s = NewStringEmpty(); - if (ObjGetMark(ho)) { - Printf(s, "Hash(%p)", ho); - return s; - } - if (expanded >= max_expand) { - /* replace each hash attribute with a '.' */ - Printf(s, "Hash(%p) {", ho); - for (i = 0; i < h->hashsize; i++) { - n = h->hashtable[i]; - while (n) { - Putc('.', s); - n = n->next; - } - } - Putc('}', s); - return s; - } - ObjSetMark(ho, 1); - Printf(s, "Hash(%p) {\n", ho); - for (i = 0; i < h->hashsize; i++) { - n = h->hashtable[i]; - while (n) { - for (j = 0; j < expanded + 1; j++) - Printf(s, tab); - expanded += 1; - Printf(s, "'%s' : %s, \n", n->key, n->object); - expanded -= 1; - n = n->next; - } - } - for (j = 0; j < expanded; j++) - Printf(s, tab); - Printf(s, "}"); - ObjSetMark(ho, 0); - return s; -} - -/* ----------------------------------------------------------------------------- - * Hash_len() - * - * Return number of entries in the hash table. - * ----------------------------------------------------------------------------- */ - -static int Hash_len(DOH *ho) { - Hash *h = (Hash *) ObjData(ho); - return h->nitems; -} - -/* ----------------------------------------------------------------------------- - * CopyHash() - * - * Make a copy of a hash table. Note: this is a shallow copy. - * ----------------------------------------------------------------------------- */ - -static DOH *CopyHash(DOH *ho) { - Hash *h, *nh; - HashNode *n; - DOH *nho; - - int i; - h = (Hash *) ObjData(ho); - nh = (Hash *) DohMalloc(sizeof(Hash)); - nh->hashsize = h->hashsize; - nh->hashtable = (HashNode **) DohMalloc(nh->hashsize * sizeof(HashNode *)); - for (i = 0; i < nh->hashsize; i++) { - nh->hashtable[i] = 0; - } - nh->nitems = 0; - nh->line = h->line; - nh->file = h->file; - if (nh->file) - Incref(nh->file); - - nho = DohObjMalloc(&DohHashType, nh); - for (i = 0; i < h->hashsize; i++) { - n = h->hashtable[i]; - while (n) { - Hash_setattr(nho, n->key, n->object); - n = n->next; - } - } - return nho; -} - - - -static void Hash_setfile(DOH *ho, DOH *file) { - DOH *fo; - Hash *h = (Hash *) ObjData(ho); - - if (!DohCheck(file)) { - fo = NewString(file); - Decref(fo); - } else - fo = file; - Incref(fo); - Delete(h->file); - h->file = fo; -} - -static DOH *Hash_getfile(DOH *ho) { - Hash *h = (Hash *) ObjData(ho); - return h->file; -} - -static void Hash_setline(DOH *ho, int line) { - Hash *h = (Hash *) ObjData(ho); - h->line = line; -} - -static int Hash_getline(DOH *ho) { - Hash *h = (Hash *) ObjData(ho); - return h->line; -} - -/* ----------------------------------------------------------------------------- - * type information - * ----------------------------------------------------------------------------- */ - -static DohHashMethods HashHashMethods = { - Hash_getattr, - Hash_setattr, - Hash_delattr, - Hash_keys, -}; - -DohObjInfo DohHashType = { - "Hash", /* objname */ - DelHash, /* doh_del */ - CopyHash, /* doh_copy */ - Hash_clear, /* doh_clear */ - Hash_str, /* doh_str */ - 0, /* doh_data */ - 0, /* doh_dump */ - Hash_len, /* doh_len */ - 0, /* doh_hash */ - 0, /* doh_cmp */ - 0, /* doh_equal */ - Hash_firstiter, /* doh_first */ - Hash_nextiter, /* doh_next */ - Hash_setfile, /* doh_setfile */ - Hash_getfile, /* doh_getfile */ - Hash_setline, /* doh_setline */ - Hash_getline, /* doh_getline */ - &HashHashMethods, /* doh_mapping */ - 0, /* doh_sequence */ - 0, /* doh_file */ - 0, /* doh_string */ - 0, /* doh_positional */ - 0, -}; - -/* ----------------------------------------------------------------------------- - * NewHash() - * - * Create a new hash table. - * ----------------------------------------------------------------------------- */ - -DOH *DohNewHash(void) { - Hash *h; - int i; - h = (Hash *) DohMalloc(sizeof(Hash)); - h->hashsize = HASH_INIT_SIZE; - h->hashtable = (HashNode **) DohMalloc(h->hashsize * sizeof(HashNode *)); - for (i = 0; i < h->hashsize; i++) { - h->hashtable[i] = 0; - } - h->nitems = 0; - h->file = 0; - h->line = 0; - return DohObjMalloc(&DohHashType, h); -} diff --git a/contrib/tools/swig/Source/DOH/list.c b/contrib/tools/swig/Source/DOH/list.c deleted file mode 100644 index cc619022d87..00000000000 --- a/contrib/tools/swig/Source/DOH/list.c +++ /dev/null @@ -1,371 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * list.c - * - * Implements a simple list object. - * ----------------------------------------------------------------------------- */ - -#include "dohint.h" - -typedef struct List { - int maxitems; /* Max size */ - int nitems; /* Num items */ - DOH *file; - int line; - DOH **items; -} List; - -extern DohObjInfo DohListType; - -/* Doubles amount of memory in a list */ -static -void more(List *l) { - l->items = (void **) DohRealloc(l->items, l->maxitems * 2 * sizeof(void *)); - l->maxitems *= 2; -} - -/* ----------------------------------------------------------------------------- - * CopyList() - * - * Make a shallow copy of a list. - * ----------------------------------------------------------------------------- */ -static DOH *CopyList(DOH *lo) { - List *l, *nl; - int i; - l = (List *) ObjData(lo); - nl = (List *) DohMalloc(sizeof(List)); - nl->nitems = l->nitems; - nl->maxitems = l->maxitems; - nl->items = (void **) DohMalloc(l->maxitems * sizeof(void *)); - for (i = 0; i < l->nitems; i++) { - nl->items[i] = l->items[i]; - Incref(nl->items[i]); - } - nl->file = l->file; - if (nl->file) - Incref(nl->file); - nl->line = l->line; - return DohObjMalloc(&DohListType, nl); -} - -/* ----------------------------------------------------------------------------- - * DelList() - * - * Delete a list. - * ----------------------------------------------------------------------------- */ - -static void DelList(DOH *lo) { - List *l = (List *) ObjData(lo); - int i; - for (i = 0; i < l->nitems; i++) - Delete(l->items[i]); - DohFree(l->items); - DohFree(l); -} - -/* ----------------------------------------------------------------------------- - * List_clear() - * - * Remove all of the list entries, but keep the list object intact. - * ----------------------------------------------------------------------------- */ - -static void List_clear(DOH *lo) { - List *l = (List *) ObjData(lo); - int i; - for (i = 0; i < l->nitems; i++) { - Delete(l->items[i]); - } - l->nitems = 0; -} - -/* ----------------------------------------------------------------------------- - * List_insert() - * - * Insert an item into the list. If the item is not a DOH object, it is assumed - * to be a 'char *' and is used to construct an equivalent string object. - * ----------------------------------------------------------------------------- */ - -static int List_insert(DOH *lo, int pos, DOH *item) { - List *l = (List *) ObjData(lo); - int i; - - if (!item) - return -1; - if (!DohCheck(item)) { - item = NewString(item); - Decref(item); - } - if (pos == DOH_END) - pos = l->nitems; - if (pos < 0) - pos = 0; - if (pos > l->nitems) - pos = l->nitems; - if (l->nitems == l->maxitems) - more(l); - for (i = l->nitems; i > pos; i--) { - l->items[i] = l->items[i - 1]; - } - l->items[pos] = item; - Incref(item); - l->nitems++; - return 0; -} - -/* ----------------------------------------------------------------------------- - * List_remove() - * - * Remove an item from a list. - * ----------------------------------------------------------------------------- */ - -static int List_remove(DOH *lo, int pos) { - List *l = (List *) ObjData(lo); - int i; - if (pos == DOH_END) - pos = l->nitems - 1; - if (pos == DOH_BEGIN) - pos = 0; - assert(!((pos < 0) || (pos >= l->nitems))); - Delete(l->items[pos]); - for (i = pos; i < l->nitems - 1; i++) { - l->items[i] = l->items[i + 1]; - } - l->nitems--; - return 0; -} - -/* ----------------------------------------------------------------------------- - * List_len() - * - * Return the number of elements in the list - * ----------------------------------------------------------------------------- */ - -static int List_len(DOH *lo) { - List *l = (List *) ObjData(lo); - return l->nitems; -} - -/* ----------------------------------------------------------------------------- - * List_get() - * - * Get the nth item from the list. - * ----------------------------------------------------------------------------- */ - -static DOH *List_get(DOH *lo, int n) { - List *l = (List *) ObjData(lo); - if (n == DOH_END) - n = l->nitems - 1; - if (n == DOH_BEGIN) - n = 0; - assert(!((n < 0) || (n >= l->nitems))); - return l->items[n]; -} - -/* ----------------------------------------------------------------------------- - * List_set() - * - * Set the nth item in the list replacing any previous item. - * ----------------------------------------------------------------------------- */ - -static int List_set(DOH *lo, int n, DOH *val) { - List *l = (List *) ObjData(lo); - if (!val) - return -1; - assert(!((n < 0) || (n >= l->nitems))); - if (!DohCheck(val)) { - val = NewString(val); - Decref(val); - } - Delete(l->items[n]); - l->items[n] = val; - Incref(val); - Delete(val); - return 0; -} - -/* ----------------------------------------------------------------------------- - * List_first() - * - * Return the first item in the list. - * ----------------------------------------------------------------------------- */ - -static DohIterator List_first(DOH *lo) { - DohIterator iter; - List *l = (List *) ObjData(lo); - iter.object = lo; - iter._index = 0; - iter._current = 0; - iter.key = 0; - if (l->nitems > 0) { - iter.item = l->items[0]; - } else { - iter.item = 0; - } - return iter; -} - -/* ----------------------------------------------------------------------------- - * List_next() - * - * Return the next item in the list. - * ----------------------------------------------------------------------------- */ - -static DohIterator List_next(DohIterator iter) { - List *l = (List *) ObjData(iter.object); - iter._index = iter._index + 1; - if (iter._index >= l->nitems) { - iter.item = 0; - iter.key = 0; - } else { - iter.item = l->items[iter._index]; - } - return iter; -} - -/* ----------------------------------------------------------------------------- - * List_str() - * - * Create a string representation of the list. - * ----------------------------------------------------------------------------- */ -static DOH *List_str(DOH *lo) { - DOH *s; - int i; - List *l = (List *) ObjData(lo); - s = NewStringEmpty(); - if (ObjGetMark(lo)) { - Printf(s, "List(%p)", lo); - return s; - } - ObjSetMark(lo, 1); - Printf(s, "List[ "); - for (i = 0; i < l->nitems; i++) { - Printf(s, "%s", l->items[i]); - if ((i + 1) < l->nitems) - Printf(s, ", "); - } - Printf(s, " ]"); - ObjSetMark(lo, 0); - return s; -} - -/* ----------------------------------------------------------------------------- - * List_dump() - * - * Dump the items to an output stream. - * ----------------------------------------------------------------------------- */ - -static int List_dump(DOH *lo, DOH *out) { - int nsent = 0; - int i, ret; - List *l = (List *) ObjData(lo); - for (i = 0; i < l->nitems; i++) { - ret = Dump(l->items[i], out); - if (ret < 0) - return -1; - nsent += ret; - } - return nsent; -} - -static void List_setfile(DOH *lo, DOH *file) { - DOH *fo; - List *l = (List *) ObjData(lo); - - if (!DohCheck(file)) { - fo = NewString(file); - Decref(fo); - } else - fo = file; - Incref(fo); - Delete(l->file); - l->file = fo; -} - -static DOH *List_getfile(DOH *lo) { - List *l = (List *) ObjData(lo); - return l->file; -} - -static void List_setline(DOH *lo, int line) { - List *l = (List *) ObjData(lo); - l->line = line; -} - -static int List_getline(DOH *lo) { - List *l = (List *) ObjData(lo); - return l->line; -} - -static DohListMethods ListListMethods = { - List_get, - List_set, - List_remove, - List_insert, - 0, /* delslice */ -}; - -DohObjInfo DohListType = { - "List", /* objname */ - DelList, /* doh_del */ - CopyList, /* doh_copy */ - List_clear, /* doh_clear */ - List_str, /* doh_str */ - 0, /* doh_data */ - List_dump, /* doh_dump */ - List_len, /* doh_len */ - 0, /* doh_hash */ - 0, /* doh_cmp */ - 0, /* doh_equal */ - List_first, /* doh_first */ - List_next, /* doh_next */ - List_setfile, /* doh_setfile */ - List_getfile, /* doh_getfile */ - List_setline, /* doh_setline */ - List_getline, /* doh_getline */ - 0, /* doh_mapping */ - &ListListMethods, /* doh_sequence */ - 0, /* doh_file */ - 0, /* doh_string */ - 0, /* doh_callable */ - 0, /* doh_position */ -}; - -/* ----------------------------------------------------------------------------- - * NewList() - * - * Create a new list. - * ----------------------------------------------------------------------------- */ - -#define MAXLISTITEMS 8 - -DOH *DohNewList(void) { - List *l = (List *) DohMalloc(sizeof(List)); - l->nitems = 0; - l->maxitems = MAXLISTITEMS; - l->items = (void **) DohCalloc(l->maxitems, sizeof(void *)); - l->file = 0; - l->line = 0; - return DohObjMalloc(&DohListType, l); -} - -static int (*List_sort_compare_func) (const DOH *, const DOH *); -static int List_qsort_compare(const void *a, const void *b) { - return List_sort_compare_func(*((DOH **) a), *((DOH **) b)); -} - -/* Sort a list */ -void DohSortList(DOH *lo, int (*cmp) (const DOH *, const DOH *)) { - List *l = (List *) ObjData(lo); - if (cmp) { - List_sort_compare_func = cmp; - } else { - List_sort_compare_func = DohCmp; - } - qsort(l->items, l->nitems, sizeof(DOH *), List_qsort_compare); -} diff --git a/contrib/tools/swig/Source/DOH/memory.c b/contrib/tools/swig/Source/DOH/memory.c deleted file mode 100644 index f8081d3aeef..00000000000 --- a/contrib/tools/swig/Source/DOH/memory.c +++ /dev/null @@ -1,292 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * memory.c - * - * This file implements all of DOH's memory management including allocation - * of objects and checking of objects. - * ----------------------------------------------------------------------------- */ - -#include "dohint.h" - -#include <stdio.h> -#include <stdlib.h> - -#ifndef DOH_POOL_SIZE -#define DOH_POOL_SIZE 4194304 -#endif - -/* Checks stale DOH object use - will use a lot more memory as pool memory is not re-used. */ -/* -#define DOH_DEBUG_MEMORY_POOLS -*/ - -static int PoolSize = DOH_POOL_SIZE; - -DOH *DohNone = 0; /* The DOH None object */ - -typedef struct pool { - DohBase *ptr; /* Start of pool */ - int len; /* Length of pool */ - int blen; /* Byte length of pool */ - int current; /* Current position for next allocation */ - char *pbeg; /* Beg of pool */ - char *pend; /* End of pool */ - struct pool *next; /* Next pool */ -} Pool; - -static DohBase *FreeList = 0; /* List of free objects */ -static Pool *Pools = 0; -static int pools_initialized = 0; - -/* ---------------------------------------------------------------------- - * CreatePool() - Create a new memory pool - * ---------------------------------------------------------------------- */ - -static void CreatePool(void) { - Pool *p = 0; - p = (Pool *) DohMalloc(sizeof(Pool)); - p->ptr = (DohBase *) DohCalloc(PoolSize, sizeof(DohBase)); - p->len = PoolSize; - p->blen = PoolSize * sizeof(DohBase); - p->current = 0; - p->pbeg = ((char *) p->ptr); - p->pend = p->pbeg + p->blen; - p->next = Pools; - Pools = p; -} - -/* ---------------------------------------------------------------------- - * InitPools() - Initialize the memory allocator - * ---------------------------------------------------------------------- */ - -static void InitPools(void) { - if (pools_initialized) - return; - CreatePool(); /* Create initial pool */ - pools_initialized = 1; - DohNone = NewVoid(0, 0); /* Create the None object */ - DohIntern(DohNone); -} - -/* ---------------------------------------------------------------------- - * DohCheck() - * - * Returns 1 if an arbitrary pointer is a DOH object. - * ---------------------------------------------------------------------- */ - -int DohCheck(const DOH *ptr) { - Pool *p = Pools; - char *cptr = (char *) ptr; - while (p) { - if ((cptr >= p->pbeg) && (cptr < p->pend)) { -#ifdef DOH_DEBUG_MEMORY_POOLS - DohBase *b = (DohBase *) ptr; - int DOH_object_already_deleted = b->type == 0; - assert(!DOH_object_already_deleted); -#endif - return 1; - } - /* - pptr = (char *) p->ptr; - if ((cptr >= pptr) && (cptr < (pptr+(p->current*sizeof(DohBase))))) return 1; */ - p = p->next; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * DohIntern() - * ----------------------------------------------------------------------------- */ - -void DohIntern(DOH *obj) { - DohBase *b = (DohBase *) obj; - b->flag_intern = 1; -} - -/* ---------------------------------------------------------------------- - * DohObjMalloc() - * - * Allocate memory for a new object. - * ---------------------------------------------------------------------- */ - -DOH *DohObjMalloc(DohObjInfo *type, void *data) { - DohBase *obj; - if (!pools_initialized) - InitPools(); -#ifndef DOH_DEBUG_MEMORY_POOLS - if (FreeList) { - obj = FreeList; - FreeList = (DohBase *) obj->data; - } else { -#endif - while (Pools->current == Pools->len) { - CreatePool(); - } - obj = Pools->ptr + Pools->current; - ++Pools->current; -#ifndef DOH_DEBUG_MEMORY_POOLS - } -#endif - obj->type = type; - obj->data = data; - obj->meta = 0; - obj->refcount = 1; - obj->flag_intern = 0; - obj->flag_marked = 0; - obj->flag_user = 0; - obj->flag_usermark = 0; - return (DOH *) obj; -} - -/* ---------------------------------------------------------------------- - * DohObjFree() - Free a DOH object - * ---------------------------------------------------------------------- */ - -void DohObjFree(DOH *ptr) { - DohBase *b, *meta; - b = (DohBase *) ptr; - if (b->flag_intern) - return; - meta = (DohBase *) b->meta; - b->data = (void *) FreeList; - b->meta = 0; - b->type = 0; - b->refcount = 0; - FreeList = b; - if (meta) { - Delete(meta); - } -} - -/* ---------------------------------------------------------------------- - * DohMemoryDebug() - * - * Display memory usage statistics - * ---------------------------------------------------------------------- */ - -void DohMemoryDebug(void) { - extern DohObjInfo DohStringType; - extern DohObjInfo DohListType; - extern DohObjInfo DohHashType; - - Pool *p; - int totsize = 0; - int totused = 0; - int totfree = 0; - - int numstring = 0; - int numlist = 0; - int numhash = 0; - - printf("Memory statistics:\n\n"); - printf("Pools:\n"); - - p = Pools; - while (p) { - /* Calculate number of used, free items */ - int i; - int nused = 0, nfree = 0; - for (i = 0; i < p->len; i++) { - if (p->ptr[i].refcount <= 0) - nfree++; - else { - nused++; - if (p->ptr[i].type == &DohStringType) - numstring++; - else if (p->ptr[i].type == &DohListType) - numlist++; - else if (p->ptr[i].type == &DohHashType) - numhash++; - } - } - printf(" Pool %8p: size = %10d. used = %10d. free = %10d\n", (void *) p, p->len, nused, nfree); - totsize += p->len; - totused += nused; - totfree += nfree; - p = p->next; - } - printf("\n Total: size = %10d, used = %10d, free = %10d\n", totsize, totused, totfree); - - printf("\nObject types\n"); - printf(" Strings : %d\n", numstring); - printf(" Lists : %d\n", numlist); - printf(" Hashes : %d\n", numhash); - -#if 0 - p = Pools; - while (p) { - int i; - for (i = 0; i < p->len; i++) { - if (p->ptr[i].refcount > 0) { - if (p->ptr[i].type == &DohStringType) { - Printf(stdout, "%s\n", p->ptr + i); - } - } - } - p = p->next; - } -#endif - -} - -/* Function to call instead of exit(). */ -static void (*doh_exit_handler)(int) = NULL; - -void DohSetExitHandler(void (*new_handler)(int)) { - doh_exit_handler = new_handler; -} - -void DohExit(int status) { - if (doh_exit_handler) { - void (*handler)(int) = doh_exit_handler; - /* Unset the handler to avoid infinite loops if it tries to do something - * which calls DohExit() (e.g. calling Malloc() and that failing). - */ - doh_exit_handler = NULL; - handler(status); - } - doh_internal_exit(status); -} - -static void allocation_failed(size_t n, size_t size) { - /* Report and exit as directly as possible to try to avoid further issues due - * to lack of memory. */ - if (n == 1) { -#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L - fprintf(stderr, "Failed to allocate %zu bytes\n", size); -#else - fprintf(stderr, "Failed to allocate %lu bytes\n", (unsigned long)size); -#endif - } else { -#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L - fprintf(stderr, "Failed to allocate %zu*%zu bytes\n", n, size); -#else - fprintf(stderr, "Failed to allocate %lu*%lu bytes\n", (unsigned long)n, (unsigned long)size); -#endif - } - DohExit(EXIT_FAILURE); -} - -void *DohMalloc(size_t size) { - void *p = doh_internal_malloc(size); - if (!p) allocation_failed(1, size); - return p; -} - -void *DohRealloc(void *ptr, size_t size) { - void *p = doh_internal_realloc(ptr, size); - if (!p) allocation_failed(1, size); - return p; -} - -void *DohCalloc(size_t n, size_t size) { - void *p = doh_internal_calloc(n, size); - if (!p) allocation_failed(n, size); - return p; -} diff --git a/contrib/tools/swig/Source/DOH/string.c b/contrib/tools/swig/Source/DOH/string.c deleted file mode 100644 index c86cab0be58..00000000000 --- a/contrib/tools/swig/Source/DOH/string.c +++ /dev/null @@ -1,1286 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * string.c - * - * Implements a string object that supports both sequence operations and - * file semantics. - * ----------------------------------------------------------------------------- */ - -#include "dohint.h" - -extern DohObjInfo DohStringType; - -typedef struct String { - DOH *file; - int line; - int maxsize; /* Max size allocated */ - int len; /* Current length */ - int hashkey; /* Hash key value */ - int sp; /* Current position */ - char *str; /* String data */ -} String; - -/* ----------------------------------------------------------------------------- - * String_data() - Return as a 'void *' - * ----------------------------------------------------------------------------- */ - -static void *String_data(DOH *so) { - String *s = (String *) ObjData(so); - s->str[s->len] = 0; - return (void *) s->str; -} - -/* static char *String_char(DOH *so) { - return (char *) String_data(so); -} -*/ - -/* ----------------------------------------------------------------------------- - * String_dump() - Serialize a string onto out - * ----------------------------------------------------------------------------- */ - -static int String_dump(DOH *so, DOH *out) { - int nsent; - int ret; - String *s = (String *) ObjData(so); - nsent = 0; - while (nsent < s->len) { - ret = Write(out, s->str + nsent, (s->len - nsent)); - if (ret < 0) - return ret; - nsent += ret; - } - return nsent; -} - -/* ----------------------------------------------------------------------------- - * CopyString() - Copy a string - * ----------------------------------------------------------------------------- */ - -static DOH *CopyString(DOH *so) { - String *str; - String *s = (String *) ObjData(so); - str = (String *) DohMalloc(sizeof(String)); - str->hashkey = s->hashkey; - str->sp = s->sp; - str->line = s->line; - str->file = s->file; - if (str->file) - Incref(str->file); - str->str = (char *) DohMalloc(s->len + 1); - memcpy(str->str, s->str, s->len); - str->maxsize = s->len; - str->len = s->len; - str->str[str->len] = 0; - - return DohObjMalloc(&DohStringType, str); -} - -/* ----------------------------------------------------------------------------- - * DelString() - Delete a string - * ----------------------------------------------------------------------------- */ - -static void DelString(DOH *so) { - String *s = (String *) ObjData(so); - DohFree(s->str); - DohFree(s); -} - -/* ----------------------------------------------------------------------------- - * DohString_len() - Length of a string - * ----------------------------------------------------------------------------- */ - -static int String_len(DOH *so) { - String *s = (String *) ObjData(so); - return s->len; -} - - -/* ----------------------------------------------------------------------------- - * String_cmp() - Compare two strings - * ----------------------------------------------------------------------------- */ - -static int String_cmp(DOH *so1, DOH *so2) { - String *s1, *s2; - char *c1, *c2; - int maxlen, i; - s1 = (String *) ObjData(so1); - s2 = (String *) ObjData(so2); - maxlen = s1->len; - if (s2->len < maxlen) - maxlen = s2->len; - c1 = s1->str; - c2 = s2->str; - for (i = maxlen; i; --i, c1++, c2++) { - if (*c1 != *c2) - break; - } - if (i != 0) { - if (*c1 < *c2) - return -1; - else - return 1; - } - if (s1->len == s2->len) - return 0; - if (s1->len > s2->len) - return 1; - return -1; -} - -/* ----------------------------------------------------------------------------- - * String_equal() - Say if two string are equal - * ----------------------------------------------------------------------------- */ - -static int String_equal(DOH *so1, DOH *so2) { - String *s1 = (String *) ObjData(so1); - String *s2 = (String *) ObjData(so2); - int len = s1->len; - if (len != s2->len) { - return 0; - } else { - char *c1 = s1->str; - char *c2 = s2->str; -#if 0 - int mlen = len >> 2; - int i = mlen; - for (; i; --i) { - if (*(c1++) != *(c2++)) - return 0; - if (*(c1++) != *(c2++)) - return 0; - if (*(c1++) != *(c2++)) - return 0; - if (*(c1++) != *(c2++)) - return 0; - } - for (i = len - (mlen << 2); i; --i) { - if (*(c1++) != *(c2++)) - return 0; - } - return 1; -#else - return memcmp(c1, c2, len) == 0; -#endif - } -} - -/* ----------------------------------------------------------------------------- - * String_hash() - Compute string hash value - * ----------------------------------------------------------------------------- */ - -static int String_hash(DOH *so) { - String *s = (String *) ObjData(so); - if (s->hashkey >= 0) { - return s->hashkey; - } else { - /* We use the djb2 hash function: https://theartincode.stanis.me/008-djb2/ - * - * One difference is we use initial seed 0. It seems the usual seed value - * is intended to help spread out hash values, which is beneficial if - * linear probing is used but DOH Hash uses a chain of buckets instead, and - * grouped hash values are probably more cache friendly. In tests using - * 0 seems slightly faster anyway. - */ - const char *c = s->str; - unsigned int len = s->len > 50 ? 50 : s->len; - unsigned int h = 0; - unsigned int mlen = len >> 2; - unsigned int i = mlen; - for (; i; --i) { - h = h + (h << 5) + *(c++); - h = h + (h << 5) + *(c++); - h = h + (h << 5) + *(c++); - h = h + (h << 5) + *(c++); - } - for (i = len - (mlen << 2); i; --i) { - h = h + (h << 5) + *(c++); - } - h &= 0x7fffffff; - s->hashkey = (int)h; - return h; - } -} - -/* ----------------------------------------------------------------------------- - * DohString_append() - Append to s - * ----------------------------------------------------------------------------- */ - -static void DohString_append(DOH *so, const DOHString_or_char *str) { - int oldlen, newlen, newmaxsize, l, sp; - char *tc; - String *s = (String *) ObjData(so); - char *newstr = 0; - - if (DohCheck(str)) { - String *ss = (String *) ObjData(str); - newstr = (char *) String_data((DOH *) str); - l = ss->len; - } else { - newstr = (char *) (str); - l = (int) strlen(newstr); - } - if (!newstr) - return; - s->hashkey = -1; - - oldlen = s->len; - newlen = oldlen + l + 1; - if (newlen >= s->maxsize - 1) { - newmaxsize = 2 * s->maxsize; - if (newlen >= newmaxsize - 1) - newmaxsize = newlen + 1; - s->str = (char *) DohRealloc(s->str, newmaxsize); - s->maxsize = newmaxsize; - } - tc = s->str; - memcpy(tc + oldlen, newstr, l + 1); - sp = s->sp; - if (sp >= oldlen) { - int i = oldlen + l - sp; - tc += sp; - for (; i; --i) { - if (*(tc++) == '\n') - s->line++; - } - s->sp = oldlen + l; - } - s->len += l; -} - - -/* ----------------------------------------------------------------------------- - * String_clear() - Clear a string - * ----------------------------------------------------------------------------- */ - -static void String_clear(DOH *so) { - String *s = (String *) ObjData(so); - s->hashkey = -1; - s->len = 0; - *(s->str) = 0; - s->sp = 0; - s->line = 1; -} - -/* ----------------------------------------------------------------------------- - * String_insert() - Insert a string - * ----------------------------------------------------------------------------- */ - -static int String_insert(DOH *so, int pos, DOH *str) { - String *s; - int len; - char *data; - - if (pos == DOH_END) { - DohString_append(so, str); - return 0; - } - - - s = (String *) ObjData(so); - s->hashkey = -1; - if (DohCheck(str)) { - String *ss = (String *) ObjData(str); - data = (char *) String_data(str); - len = ss->len; - } else { - data = (char *) (str); - len = (int) strlen(data); - } - - if (pos < 0) - pos = 0; - else if (pos > s->len) - pos = s->len; - - /* See if there is room to insert the new data */ - while (s->maxsize <= s->len + len) { - int newsize = 2 * s->maxsize; - s->str = (char *) DohRealloc(s->str, newsize); - s->maxsize = newsize; - } - memmove(s->str + pos + len, s->str + pos, (s->len - pos)); - memcpy(s->str + pos, data, len); - if (s->sp >= pos) { - int i; - - for (i = 0; i < len; i++) { - if (data[i] == '\n') - s->line++; - } - s->sp += len; - } - s->len += len; - s->str[s->len] = 0; - return 0; -} - -/* ----------------------------------------------------------------------------- - * String_delitem() - Delete a character - * ----------------------------------------------------------------------------- */ - -static int String_delitem(DOH *so, int pos) { - String *s = (String *) ObjData(so); - s->hashkey = -1; - if (pos == DOH_END) - pos = s->len - 1; - if (pos == DOH_BEGIN) - pos = 0; - if (s->len == 0) - return 0; - - if (s->sp > pos) { - s->sp--; - assert(s->sp >= 0); - if (s->str[pos] == '\n') - s->line--; - } - memmove(s->str + pos, s->str + pos + 1, ((s->len - 1) - pos)); - s->len--; - s->str[s->len] = 0; - return 0; -} - -/* ----------------------------------------------------------------------------- - * String_delslice() - Delete a range - * ----------------------------------------------------------------------------- */ - -static int String_delslice(DOH *so, int sindex, int eindex) { - String *s = (String *) ObjData(so); - int size; - if (s->len == 0) - return 0; - s->hashkey = -1; - if (eindex == DOH_END) - eindex = s->len; - if (sindex == DOH_BEGIN) - sindex = 0; - - size = eindex - sindex; - if (s->sp > sindex) { - /* Adjust the file pointer and line count */ - int i, end; - if (s->sp > eindex) { - end = eindex; - s->sp -= size; - } else { - end = s->sp; - s->sp = sindex; - } - for (i = sindex; i < end; i++) { - if (s->str[i] == '\n') - s->line--; - } - assert(s->sp >= 0); - } - memmove(s->str + sindex, s->str + eindex, s->len - eindex); - s->len -= size; - s->str[s->len] = 0; - return 0; -} - -/* ----------------------------------------------------------------------------- - * String_str() - Returns a string (used by printing commands) - * ----------------------------------------------------------------------------- */ - -static DOH *String_str(DOH *so) { - String *s = (String *) ObjData(so); - s->str[s->len] = 0; - return NewString(s->str); -} - -/* ----------------------------------------------------------------------------- - * String_read() - Read data from a string - * ----------------------------------------------------------------------------- */ - -static int String_read(DOH *so, void *buffer, int len) { - int reallen, retlen; - char *cb; - String *s = (String *) ObjData(so); - if ((s->sp + len) > s->len) - reallen = (s->len - s->sp); - else - reallen = len; - - cb = (char *) buffer; - retlen = reallen; - - if (reallen > 0) { - memmove(cb, s->str + s->sp, reallen); - s->sp += reallen; - } - return retlen; -} - -/* ----------------------------------------------------------------------------- - * String_write() - Write data to a string - * ----------------------------------------------------------------------------- */ -static int String_write(DOH *so, const void *buffer, int len) { - int newlen; - String *s = (String *) ObjData(so); - s->hashkey = -1; - if (s->sp > s->len) - s->sp = s->len; - newlen = s->sp + len + 1; - if (newlen > s->maxsize) { - s->str = (char *) DohRealloc(s->str, newlen); - s->maxsize = newlen; - s->len = s->sp + len; - } - if ((s->sp + len) > s->len) - s->len = s->sp + len; - memmove(s->str + s->sp, buffer, len); - s->sp += len; - s->str[s->len] = 0; - return len; -} - -/* ----------------------------------------------------------------------------- - * String_seek() - Seek to a new position - * ----------------------------------------------------------------------------- */ - -static int String_seek(DOH *so, long offset, int whence) { - int pos, nsp, inc; - String *s = (String *) ObjData(so); - if (whence == SEEK_SET) - pos = 0; - else if (whence == SEEK_CUR) - pos = s->sp; - else if (whence == SEEK_END) { - pos = s->len; - offset = -offset; - } else - pos = s->sp; - - nsp = pos + offset; - if (nsp < 0) - nsp = 0; - if (s->len > 0 && nsp > s->len) - nsp = s->len; - - inc = (nsp > s->sp) ? 1 : -1; - - { -#if 0 - int sp = s->sp; - char *tc = s->str; - int len = s->len; - while (sp != nsp) { - int prev = sp + inc; - if (prev >= 0 && prev <= len && tc[prev] == '\n') - s->line += inc; - sp += inc; - } -#else - int sp = s->sp; - char *tc = s->str; - if (inc > 0) { - while (sp != nsp) { - if (tc[++sp] == '\n') - ++s->line; - } - } else { - while (sp != nsp) { - if (tc[--sp] == '\n') - --s->line; - } - } -#endif - s->sp = sp; - } - assert(s->sp >= 0); - return 0; -} - -/* ----------------------------------------------------------------------------- - * String_tell() - Return current position - * ----------------------------------------------------------------------------- */ - -static long String_tell(DOH *so) { - String *s = (String *) ObjData(so); - return (long) (s->sp); -} - -/* ----------------------------------------------------------------------------- - * String_putc() - * ----------------------------------------------------------------------------- */ - -static int String_putc(DOH *so, int ch) { - String *s = (String *) ObjData(so); - int len = s->len; - int sp = s->sp; - s->hashkey = -1; - if (sp >= len) { - int maxsize = s->maxsize; - char *tc = s->str; - if (len > (maxsize - 2)) { - maxsize *= 2; - tc = (char *) DohRealloc(tc, maxsize); - s->maxsize = (int) maxsize; - s->str = tc; - } - tc += sp; - *tc = (char) ch; - *(++tc) = 0; - s->len = s->sp = sp + 1; - } else { - s->str[s->sp++] = (char) ch; - } - if (ch == '\n') - s->line++; - return ch; -} - -/* ----------------------------------------------------------------------------- - * String_getc() - * ----------------------------------------------------------------------------- */ - -static int String_getc(DOH *so) { - int c; - String *s = (String *) ObjData(so); - if (s->sp >= s->len) - c = EOF; - else - c = (int)(unsigned char) s->str[s->sp++]; - if (c == '\n') - s->line++; - return c; -} - -/* ----------------------------------------------------------------------------- - * String_ungetc() - * ----------------------------------------------------------------------------- */ - -static int String_ungetc(DOH *so, int ch) { - String *s = (String *) ObjData(so); - if (ch == EOF) - return ch; - if (s->sp <= 0) - return EOF; - s->sp--; - if (ch == '\n') - s->line--; - return ch; -} - -static char *end_quote(char *s) { - char *qs; - char qc; - char *q; - char *nl; - qc = *s; - qs = s; - while (1) { - q = strpbrk(s + 1, "\"\'"); - nl = strchr(s + 1, '\n'); - if (nl && (nl < q)) { - /* A new line appears before the end of the string */ - if (*(nl - 1) == '\\') { - s = nl + 1; - continue; - } - /* String was terminated by a newline. Wing it */ - return qs; - } - if (!q && nl) { - return qs; - } - if (!q) - return 0; - if ((*q == qc) && (*(q - 1) != '\\')) - return q; - s = q; - } -} - -static char *end_comment(char *s) { - char *substring = strstr(s, "*/"); - if (substring) - ++substring; - return substring; -} - -static char *match_simple(char *base, char *s, char *token, int tokenlen) { - (void) base; - (void) tokenlen; - return strstr(s, token); -} - -static char *match_identifier(char *base, char *s, char *token, int tokenlen) { - while (s) { - s = strstr(s, token); - if (!s) - return 0; - if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) { - /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */ - ++s; - continue; - } - if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) { - /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */ - ++s; - continue; - } - return s; - } - return 0; -} - - -static char *match_identifier_begin(char *base, char *s, char *token, int tokenlen) { - (void)tokenlen; - while (s) { - s = strstr(s, token); - if (!s) - return 0; - if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) { - /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */ - ++s; - continue; - } - return s; - } - return 0; -} - -static char *match_identifier_end(char *base, char *s, char *token, int tokenlen) { - (void) base; - while (s) { - s = strstr(s, token); - if (!s) - return 0; - if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) { - /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */ - ++s; - continue; - } - return s; - } - return 0; -} - -static char *match_number_end(char *base, char *s, char *token, int tokenlen) { - (void) base; - while (s) { - s = strstr(s, token); - if (!s) - return 0; - if (isdigit((int) *(s + tokenlen))) { - /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */ - ++s; - continue; - } - return s; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * replace_simple() - * - * Replaces count non-overlapping occurrences of token with rep in a string. - * ----------------------------------------------------------------------------- */ - -static int replace_simple(String *str, char *token, char *rep, int flags, int count, char *(*match) (char *, char *, char *, int)) { - int tokenlen; /* Length of the token */ - int replen; /* Length of the replacement */ - int delta, expand = 0; - int ic; - int rcount = 0; - int noquote = 0; - int nocomment = 0; - char *c, *s, *t, *first; - char *q, *q2; - char *base; - int i; - - /* Figure out if anything gets replaced */ - if (!strlen(token)) - return 0; - - base = str->str; - tokenlen = (int)strlen(token); - s = (*match) (base, base, token, tokenlen); - - if (!s) - return 0; /* No matches. Who cares */ - - str->hashkey = -1; - - if (flags & DOH_REPLACE_NOQUOTE) - noquote = 1; - - if (flags & DOH_REPLACE_NOCOMMENT) - nocomment = 1; - - assert(!(noquote && nocomment)); /* quote and comment combination not implemented */ - - /* If we are not replacing inside quotes, we need to do a little extra work */ - if (noquote) { - q = strpbrk(base, "\"\'"); - if (!q) { - noquote = 0; /* Well, no quotes to worry about. Oh well */ - } else { - while (q && (q < s)) { - /* First match was found inside a quote. Try to find another match */ - q2 = end_quote(q); - if (!q2) { - return 0; - } - if (q2 > s) { - /* Find next match */ - s = (*match) (base, q2 + 1, token, tokenlen); - } - if (!s) - return 0; /* Oh well, no matches */ - q = strpbrk(q2 + 1, "\"\'"); - if (!q) - noquote = 0; /* No more quotes */ - } - } - } - - /* If we are not replacing inside comments, we need to do a little extra work */ - if (nocomment) { - q = strstr(base, "/*"); - if (!q) { - nocomment = 0; /* Well, no comments to worry about. Oh well */ - } else { - while (q && (q < s)) { - /* First match was found inside a comment. Try to find another match */ - q2 = end_comment(q); - if (!q2) { - return 0; - } - if (q2 > s) { - /* Find next match */ - s = (*match) (base, q2 + 1, token, tokenlen); - } - if (!s) - return 0; /* Oh well, no matches */ - q = strstr(q2 + 1, "/*"); - if (!q) - nocomment = 0; /* No more comments */ - } - } - } - - first = s; - replen = (int)strlen(rep); - - delta = (replen - tokenlen); - - if (delta <= 0) { - /* String is either shrinking or staying the same size */ - /* In this case, we do the replacement in place without memory reallocation */ - ic = count; - t = s; /* Target of memory copies */ - while (ic && s) { - if (replen) { - memcpy(t, rep, replen); - t += replen; - } - rcount++; - expand += delta; - /* Find the next location */ - s += tokenlen; - if (ic == 1) - break; - c = (*match) (base, s, token, tokenlen); - - if (noquote) { - q = strpbrk(s, "\"\'"); - if (!q) { - noquote = 0; - } else { - while (q && (q < c)) { - /* First match was found inside a quote. Try to find another match */ - q2 = end_quote(q); - if (!q2) { - c = 0; - break; - } - if (q2 > c) - c = (*match) (base, q2 + 1, token, tokenlen); - if (!c) - break; - q = strpbrk(q2 + 1, "\"\'"); - if (!q) - noquote = 0; /* No more quotes */ - } - } - } - if (nocomment) { - q = strstr(s, "/*"); - if (!q) { - nocomment = 0; - } else { - while (q && (q < c)) { - /* First match was found inside a comment. Try to find another match */ - q2 = end_comment(q); - if (!q2) { - c = 0; - break; - } - if (q2 > c) - c = (*match) (base, q2 + 1, token, tokenlen); - if (!c) - break; - q = strstr(q2 + 1, "/*"); - if (!q) - nocomment = 0; /* No more comments */ - } - } - } - if (delta) { - if (c) { - memmove(t, s, c - s); - t += (c - s); - } else { - memmove(t, s, (str->str + str->len) - s + 1); - } - } else { - if (c) { - t += (c - s); - } - } - s = c; - ic--; - } - if (s && delta) { - memmove(t, s, (str->str + str->len) - s + 1); - } - str->len += expand; - str->str[str->len] = 0; - if (str->sp >= str->len) - str->sp += expand; /* Fix the end of file pointer */ - return rcount; - } - /* The string is expanding as a result of the replacement */ - /* Figure out how much expansion is going to occur and allocate a new string */ - { - char *ns; - int newsize; - - rcount++; - ic = count - 1; - s += tokenlen; - while (ic && (c = (*match) (base, s, token, tokenlen))) { - if (noquote) { - q = strpbrk(s, "\"\'"); - if (!q) { - break; - } else { - while (q && (q < c)) { - /* First match was found inside a quote. Try to find another match */ - q2 = end_quote(q); - if (!q2) { - c = 0; - break; - } - if (q2 > c) { - c = (*match) (base, q2 + 1, token, tokenlen); - if (!c) - break; - } - q = strpbrk(q2 + 1, "\"\'"); - if (!q) - noquote = 0; - } - } - } - if (nocomment) { - q = strstr(s, "/*"); - if (!q) { - break; - } else { - while (q && (q < c)) { - /* First match was found inside a comment. Try to find another match */ - q2 = end_comment(q); - if (!q2) { - c = 0; - break; - } - if (q2 > c) { - c = (*match) (base, q2 + 1, token, tokenlen); - if (!c) - break; - } - q = strstr(q2 + 1, "/*"); - if (!q) - nocomment = 0; - } - } - } - if (c) { - rcount++; - ic--; - s = c + tokenlen; - } else { - break; - } - } - - expand = delta * rcount; /* Total amount of expansion for the replacement */ - newsize = str->maxsize; - while ((str->len + expand) >= newsize) - newsize *= 2; - - ns = (char *) DohMalloc(newsize); - t = ns; - s = first; - - /* Copy the first part of the string */ - if (first > str->str) { - memcpy(t, str->str, (first - str->str)); - t += (first - str->str); - } - for (i = 0; i < rcount; i++) { - memcpy(t, rep, replen); - t += replen; - s += tokenlen; - c = (*match) (base, s, token, tokenlen); - if (noquote) { - q = strpbrk(s, "\"\'"); - if (!q) { - noquote = 0; - } else { - while (q && (q < c)) { - /* First match was found inside a quote. Try to find another match */ - q2 = end_quote(q); - if (!q2) { - c = 0; - break; - } - if (q2 > c) { - c = (*match) (base, q2 + 1, token, tokenlen); - if (!c) - break; - } - q = strpbrk(q2 + 1, "\"\'"); - if (!q) - noquote = 0; /* No more quotes */ - } - } - } - if (nocomment) { - q = strstr(s, "/*"); - if (!q) { - nocomment = 0; - } else { - while (q && (q < c)) { - /* First match was found inside a comment. Try to find another match */ - q2 = end_comment(q); - if (!q2) { - c = 0; - break; - } - if (q2 > c) { - c = (*match) (base, q2 + 1, token, tokenlen); - if (!c) - break; - } - q = strstr(q2 + 1, "/*"); - if (!q) - nocomment = 0; /* No more comments */ - } - } - } - if (i < (rcount - 1)) { - memcpy(t, s, c - s); - t += (c - s); - } else { - memcpy(t, s, (str->str + str->len) - s + 1); - } - s = c; - } - c = str->str; - str->str = ns; - if (str->sp >= str->len) - str->sp += expand; - str->len += expand; - str->str[str->len] = 0; - str->maxsize = newsize; - DohFree(c); - return rcount; - } -} - -/* ----------------------------------------------------------------------------- - * String_replace() - * ----------------------------------------------------------------------------- */ - -static int String_replace(DOH *stro, const DOHString_or_char *token, const DOHString_or_char *rep, int flags) { - int count = -1; - String *str = (String *) ObjData(stro); - - if (flags & DOH_REPLACE_FIRST) - count = 1; - - if (flags & DOH_REPLACE_ID_END) { - return replace_simple(str, Char(token), Char(rep), flags, count, match_identifier_end); - } else if (flags & DOH_REPLACE_ID_BEGIN) { - return replace_simple(str, Char(token), Char(rep), flags, count, match_identifier_begin); - } else if (flags & DOH_REPLACE_ID) { - return replace_simple(str, Char(token), Char(rep), flags, count, match_identifier); - } else if (flags & DOH_REPLACE_NUMBER_END) { - return replace_simple(str, Char(token), Char(rep), flags, count, match_number_end); - } else { - return replace_simple(str, Char(token), Char(rep), flags, count, match_simple); - } -} - -/* ----------------------------------------------------------------------------- - * String_chop() - * ----------------------------------------------------------------------------- */ - -static void String_chop(DOH *so) { - char *c; - String *str = (String *) ObjData(so); - /* Replace trailing whitespace */ - c = str->str + str->len - 1; - while ((str->len > 0) && (isspace((int) *c))) { - if (str->sp >= str->len) { - str->sp--; - if (*c == '\n') - str->line--; - } - str->len--; - c--; - } - str->str[str->len] = 0; - assert(str->sp >= 0); - str->hashkey = -1; -} - -static void String_setfile(DOH *so, DOH *file) { - DOH *fo; - String *str = (String *) ObjData(so); - - if (!DohCheck(file)) { - fo = NewString(file); - Decref(fo); - } else - fo = file; - Incref(fo); - Delete(str->file); - str->file = fo; -} - -static DOH *String_getfile(DOH *so) { - String *str = (String *) ObjData(so); - return str->file; -} - -static void String_setline(DOH *so, int line) { - String *str = (String *) ObjData(so); - str->line = line; -} - -static int String_getline(DOH *so) { - String *str = (String *) ObjData(so); - return str->line; -} - -static DohListMethods StringListMethods = { - 0, /* doh_getitem */ - 0, /* doh_setitem */ - String_delitem, /* doh_delitem */ - String_insert, /* doh_insitem */ - String_delslice, /* doh_delslice */ -}; - -static DohFileMethods StringFileMethods = { - String_read, - String_write, - String_putc, - String_getc, - String_ungetc, - String_seek, - String_tell, -}; - -static DohStringMethods StringStringMethods = { - String_replace, - String_chop, -}; - -DohObjInfo DohStringType = { - "String", /* objname */ - DelString, /* doh_del */ - CopyString, /* doh_copy */ - String_clear, /* doh_clear */ - String_str, /* doh_str */ - String_data, /* doh_data */ - String_dump, /* doh_dump */ - String_len, /* doh_len */ - String_hash, /* doh_hash */ - String_cmp, /* doh_cmp */ - String_equal, /* doh_equal */ - 0, /* doh_first */ - 0, /* doh_next */ - String_setfile, /* doh_setfile */ - String_getfile, /* doh_getfile */ - String_setline, /* doh_setline */ - String_getline, /* doh_getline */ - 0, /* doh_mapping */ - &StringListMethods, /* doh_sequence */ - &StringFileMethods, /* doh_file */ - &StringStringMethods, /* doh_string */ - 0, /* doh_position */ - 0 -}; - - -#define INIT_MAXSIZE 16 - -/* ----------------------------------------------------------------------------- - * NewString() - Create a new string - * ----------------------------------------------------------------------------- */ - -DOHString *DohNewString(const DOHString_or_char *so) { - int l = 0, max; - String *str; - char *s; - int hashkey = -1; - if (DohCheck(so)) { - str = (String *) ObjData(so); - s = (char *) String_data((String *) so); - l = s ? str->len : 0; - hashkey = str->hashkey; - } else { - s = (char *) so; - l = s ? (int) strlen(s) : 0; - } - - str = (String *) DohMalloc(sizeof(String)); - str->hashkey = hashkey; - str->sp = 0; - str->line = 1; - str->file = 0; - max = INIT_MAXSIZE; - if (s) { - if ((l + 1) > max) - max = l + 1; - } - str->str = (char *) DohMalloc(max); - str->maxsize = max; - if (s) { - strcpy(str->str, s); - str->len = l; - str->sp = l; - } else { - str->str[0] = 0; - str->len = 0; - } - return DohObjMalloc(&DohStringType, str); -} - - -/* ----------------------------------------------------------------------------- - * NewStringEmpty() - Create a new string - * ----------------------------------------------------------------------------- */ - -DOHString *DohNewStringEmpty(void) { - int max = INIT_MAXSIZE; - String *str = (String *) DohMalloc(sizeof(String)); - str->hashkey = 0; - str->sp = 0; - str->line = 1; - str->file = 0; - str->str = (char *) DohMalloc(max); - str->maxsize = max; - str->str[0] = 0; - str->len = 0; - return DohObjMalloc(&DohStringType, str); -} - -/* ----------------------------------------------------------------------------- - * NewStringWithSize() - Create a new string - * ----------------------------------------------------------------------------- */ - -DOHString *DohNewStringWithSize(const DOHString_or_char *so, int len) { - int l = 0, max; - String *str; - char *s; - if (DohCheck(so)) { - s = (char *) String_data((String *) so); - } else { - s = (char *) so; - } - - str = (String *) DohMalloc(sizeof(String)); - str->hashkey = -1; - str->sp = 0; - str->line = 1; - str->file = 0; - max = INIT_MAXSIZE; - if (s) { - l = (int) len; - if ((l + 1) > max) - max = l + 1; - } - str->str = (char *) DohMalloc(max); - str->maxsize = max; - if (s) { - strncpy(str->str, s, len); - str->str[l] = 0; - str->len = l; - str->sp = l; - } else { - str->str[0] = 0; - str->len = 0; - } - return DohObjMalloc(&DohStringType, str); -} - -/* ----------------------------------------------------------------------------- - * NewStringf() - * - * Create a new string from a list of objects. - * ----------------------------------------------------------------------------- */ - -DOHString *DohNewStringf(const DOHString_or_char *fmt, ...) { - va_list ap; - DOH *r; - va_start(ap, fmt); - r = NewStringEmpty(); - DohvPrintf(r, Char(fmt), ap); - va_end(ap); - return (DOHString *) r; -} - -/* ----------------------------------------------------------------------------- - * Strcmp() - * Strncmp() - * Strstr() - * Strchr() - * - * Some utility functions. - * ----------------------------------------------------------------------------- */ - -int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2) { - const char *c1 = Char(s1); - const char *c2 = Char(s2); - return strcmp(c1, c2); -} - -int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n) { - return strncmp(Char(s1), Char(s2), n); -} - -char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2) { - char *p1 = Char(s1); - char *p2 = Char(s2); - return p1 == 0 || p2 == 0 || *p2 == '\0' ? p1 : strstr(p1, p2); -} - -char *DohStrchr(const DOHString_or_char *s1, int ch) { - return strchr(Char(s1), ch); -} diff --git a/contrib/tools/swig/Source/DOH/void.c b/contrib/tools/swig/Source/DOH/void.c deleted file mode 100644 index bbecca21b4e..00000000000 --- a/contrib/tools/swig/Source/DOH/void.c +++ /dev/null @@ -1,96 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * void.c - * - * Implements a "void" object that is really just a DOH container around - * an arbitrary C object represented as a void *. - * ----------------------------------------------------------------------------- */ - -#include "dohint.h" - -typedef struct { - void *ptr; - void (*del) (void *); -} VoidObj; - -/* ----------------------------------------------------------------------------- - * Void_delete() - * - * Delete a void object. Invokes the destructor supplied at the time of creation. - * ----------------------------------------------------------------------------- */ - -static void Void_delete(DOH *vo) { - VoidObj *v = (VoidObj *) ObjData(vo); - if (v->del) - (*v->del) (v->ptr); - DohFree(v); -} - -/* ----------------------------------------------------------------------------- - * Void_copy() - * - * Copies a void object. This is only a shallow copy. The object destruction - * function is not copied in order to avoid potential double-free problems. - * ----------------------------------------------------------------------------- */ - -static DOH *Void_copy(DOH *vo) { - VoidObj *v = (VoidObj *) ObjData(vo); - return NewVoid(v->ptr, 0); -} - -/* ----------------------------------------------------------------------------- - * Void_data() - * - * Returns the void * stored in the object. - * ----------------------------------------------------------------------------- */ - -static void *Void_data(DOH *vo) { - VoidObj *v = (VoidObj *) ObjData(vo); - return v->ptr; -} - -static DohObjInfo DohVoidType = { - "VoidObj", /* objname */ - Void_delete, /* doh_del */ - Void_copy, /* doh_copy */ - 0, /* doh_clear */ - 0, /* doh_str */ - Void_data, /* doh_data */ - 0, /* doh_dump */ - 0, /* doh_len */ - 0, /* doh_hash */ - 0, /* doh_cmp */ - 0, /* doh_equal */ - 0, /* doh_first */ - 0, /* doh_next */ - 0, /* doh_setfile */ - 0, /* doh_getfile */ - 0, /* doh_setline */ - 0, /* doh_getline */ - 0, /* doh_mapping */ - 0, /* doh_sequence */ - 0, /* doh_file */ - 0, /* doh_string */ - 0, /* doh_reserved */ - 0, /* clientdata */ -}; - -/* ----------------------------------------------------------------------------- - * NewVoid() - * - * Creates a new Void object given a void * and an optional destructor function. - * ----------------------------------------------------------------------------- */ - -DOH *DohNewVoid(void *obj, void (*del) (void *)) { - VoidObj *v; - v = (VoidObj *) DohMalloc(sizeof(VoidObj)); - v->ptr = obj; - v->del = del; - return DohObjMalloc(&DohVoidType, v); -} diff --git a/contrib/tools/swig/Source/Doxygen/doxycommands.h b/contrib/tools/swig/Source/Doxygen/doxycommands.h deleted file mode 100644 index 782b6ab9441..00000000000 --- a/contrib/tools/swig/Source/Doxygen/doxycommands.h +++ /dev/null @@ -1,174 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * doxycommands.h - * - * Part of the Doxygen comment translation module of SWIG. - * ----------------------------------------------------------------------------- */ - -#ifndef DOXYGENCOMMANDS_H -#define DOXYGENCOMMANDS_H - -// doxy commands are not processed inside this block -const char *CMD_HTML_ONLY = "htmlonly"; -// doxy commands are not processed inside this block -const char *CMD_VERBATIM = "verbatim"; -const char *CMD_CODE = "code"; -const char *CMD_LATEX_1 = "f$"; -const char *CMD_LATEX_2 = "f{"; -const char *CMD_LATEX_3 = "f["; -const char *CMD_END_HTML_ONLY = "endhtmlonly"; -const char *CMD_END_VERBATIM = "endverbatim"; -const char *CMD_END_CODE = "endcode"; -const char *CMD_END_LATEX_1 = "f$"; -const char *CMD_END_LATEX_2 = "f}"; -const char *CMD_END_LATEX_3 = "f]"; - -const char *sectionIndicators[] = { - "attention", "author", "authors", "brief", "bug", "cond", "date", - "deprecated", "details", "else", "elseif", "endcond", "endif", - "exception", "if", "ifnot", "invariant", "note", "par", "param", - "tparam", "post", "pre", "remarks", "remark", "result", "return", - "returns", "retval", "sa", "see", "since", "test", "throw", "throws", - "todo", "version", "warning", "xrefitem" -}; - -const int sectionIndicatorsSize = sizeof(sectionIndicators) / sizeof(*sectionIndicators); - -/* All of the doxygen commands divided up by how they are parsed */ -const char *simpleCommands[] = { - // the first line are escaped chars, except \~, which is a language ID command. - "n", "$", "@", "\\", "&", "~", "<", ">", "#", "%", "\"", ".", "::", - // Member groups, which we currently ignore. - "{", "}", - "endcond", - "callgraph", "callergraph", "showinitializer", "hideinitializer", "internal", - "nosubgrouping", "public", "publicsection", "private", "privatesection", - "protected", "protectedsection", "tableofcontents" -}; - -const int simpleCommandsSize = sizeof(simpleCommands) / sizeof(*simpleCommands); - -const char *commandWords[] = { - "a", "b", "c", "e", "em", "p", "def", "enum", "package", "relates", - "namespace", "relatesalso", "anchor", "dontinclude", "include", - "includelineno", "copydoc", "copybrief", "copydetails", "verbinclude", - "htmlinclude", "extends", "implements", "memberof", "related", "relatedalso", - "cite" -}; - -const int commandWordsSize = sizeof(commandWords) / sizeof(*commandWords); - -const char *commandLines[] = { - "addindex", "fn", "name", "line", "var", "skipline", "typedef", "skip", - "until", "property" -}; - -const int commandLinesSize = sizeof(commandLines) / sizeof(*commandLines); - -const char *commandParagraph[] = { - "partofdescription", "result", "return", "returns", "remarks", "remark", - "since", "test", "sa", "see", "pre", "post", "details", "invariant", - "deprecated", "date", "note", "warning", "version", "todo", "bug", - "attention", "brief", "author", "authors", "copyright", "short" -}; - -const int commandParagraphSize = sizeof(commandParagraph) / sizeof(*commandParagraph); - -const char *commandEndCommands[] = { - CMD_HTML_ONLY, "latexonly", "manonly", "xmlonly", "link", "rtfonly" -}; - -const int commandEndCommandsSize = sizeof(commandEndCommands) / sizeof(*commandEndCommands); - -const char *commandWordParagraphs[] = { - "param", "tparam", "throw", "throws", "retval", "exception", "example" -}; - -const int commandWordParagraphsSize = sizeof(commandWordParagraphs) / sizeof(*commandWordParagraphs); - -const char *commandWordLines[] = { - "page", "subsection", "subsubsection", "section", "paragraph", "defgroup", - "snippet", "mainpage" -}; - -const int commandWordLinesSize = sizeof(commandWordLines) / sizeof(*commandWordLines); - -const char *commandWordOWordOWords[] = { - "category", "class", "protocol", "interface", "struct", "union" -}; - -const int commandWordOWordOWordsSize = sizeof(commandWordOWordOWords) / sizeof(*commandWordOWordOWords); - -const char *commandOWords[] = { - "dir", "file", "cond" -}; - -const int commandOWordsSize = sizeof(commandOWords) / sizeof(*commandOWords); - -const char *commandErrorThrowings[] = { - "annotatedclassstd::list", "classhierarchy", "define", "functionindex", "header", - "headerfilestd::list", "inherit", "l", "postheader", "endcode", "enddot", "endmsc", "endhtmlonly", - "endlatexonly", "endmanonly", "endlink", "endverbatim", "endxmlonly", "f]", "f}", "endif", "else", - "endrtfonly" -}; - -const int commandErrorThrowingsSize = sizeof(commandErrorThrowings) / sizeof(*commandErrorThrowings); - -const char *commandUniques[] = { - "xrefitem", "arg", "ingroup", "par", "headerfile", "overload", "weakgroup", "ref", "subpage", "dotfile", "image", "addtogroup", "li", - "if", "ifnot", "elseif", "else", "mscfile", "code", CMD_VERBATIM, "f{", "f[", "f$", "dot", "msc" -}; - -const int commandUniquesSize = sizeof(commandUniques) / sizeof(*commandUniques); - -// These HTML commands are transformed when producing output in other formats. -// Other commands are left intact, but '<' and '> are replaced with entities in HTML -// output. So <varName> appears as <varName> in HTML output. The same -// behavior must be repeated by SWIG. See Doxygen doc for the list of commands. -// '<' is prepended to distinguish HTML tags from Doxygen commands. -const char *commandHtml[] = { - "<a", "<b", "<blockquote", "<body", "<br", "<center", "<caption", "<code", "<dd", "<dfn", - "<div", "<dl", "<dt", "<em", "<form", "<hr", "<h1", "<h2", "<h3", "<i", "<input", "<img", - "<li", "<meta", "<multicol", "<ol", "<p", "<pre", "<small", "<span", "<strong", - "<sub", "<sup", "<table", "<td", "<th", "<tr", "<tt", "<kbd", "<ul", "<var" -}; - -const int commandHtmlSize = sizeof(commandHtml) / sizeof(*commandHtml); - -// Only entities which are translatable to plain text are used here. Others -// are copied unchanged to output. -const char *commandHtmlEntities[] = { - "©", // (C) - "&trade", // (TM) - "®", // (R) - "<", // less-than symbol - ">", // greater-than symbol - "&", // ampersand - "&apos", // single quotation mark (straight) - """, // double quotation mark (straight) - "&lsquo", // left single quotation mark - "&rsquo", // right single quotation mark - "&ldquo", // left double quotation mark - "&rdquo", // right double quotation mark - "&ndash", // n-dash (for numeric ranges, e.g. 2–8) - "&mdash", // -- - " ", // - "×", // x - "&minus", // - - "&sdot", // . - "&sim", // ~ - "&le", // <= - "&ge", // >= - "&larr", // <-- - "&rarr" // --> -}; - -const int commandHtmlEntitiesSize = sizeof(commandHtmlEntities) / sizeof(*commandHtmlEntities); - -#endif diff --git a/contrib/tools/swig/Source/Doxygen/doxyentity.cxx b/contrib/tools/swig/Source/Doxygen/doxyentity.cxx deleted file mode 100644 index 6fe97dd3629..00000000000 --- a/contrib/tools/swig/Source/Doxygen/doxyentity.cxx +++ /dev/null @@ -1,69 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * doxyentity.cxx - * - * Part of the Doxygen comment translation module of SWIG. - * ----------------------------------------------------------------------------- */ - -#include "doxyentity.h" -#include <iostream> - -using std::cout; - -DoxygenEntity::DoxygenEntity(const std::string &typeEnt):typeOfEntity(typeEnt), isLeaf(true) { -} - - -/* Basic node for commands that have - * only 1 item after them - * example: \b word - * OR holding a std::string - */ -DoxygenEntity::DoxygenEntity(const std::string &typeEnt, const std::string ¶m1) : typeOfEntity(typeEnt), data(param1), isLeaf(true) { -} - - -/* Nonterminal node - * contains - */ -DoxygenEntity::DoxygenEntity(const std::string &typeEnt, const DoxygenEntityList &entList) : typeOfEntity(typeEnt), isLeaf(false), entityList(entList) { -} - - -void DoxygenEntity::printEntity(int level) const { - - int thisLevel = level; - - if (isLeaf) { - for (int i = 0; i < thisLevel; i++) { - cout << "\t"; - } - - cout << "Node Leaf Command: '" << typeOfEntity << "', "; - - if (!data.empty()) { - cout << "Node Data: '" << data << "'"; - } - cout << std::endl; - - } else { - - for (int i = 0; i < thisLevel; i++) { - cout << "\t"; - } - - cout << "Node Command: '" << typeOfEntity << "'" << std::endl; - - thisLevel++; - - for (DoxygenEntityListCIt p = entityList.begin(); p != entityList.end(); p++) { - p->printEntity(thisLevel); - } - } -} diff --git a/contrib/tools/swig/Source/Doxygen/doxyentity.h b/contrib/tools/swig/Source/Doxygen/doxyentity.h deleted file mode 100644 index e475141a3a8..00000000000 --- a/contrib/tools/swig/Source/Doxygen/doxyentity.h +++ /dev/null @@ -1,45 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * doxyentity.h - * - * Part of the Doxygen comment translation module of SWIG. - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_DOXYENTITY_H -#define SWIG_DOXYENTITY_H - -#include <string> -#include <list> - - -class DoxygenEntity; - -typedef std::list<DoxygenEntity> DoxygenEntityList; -typedef DoxygenEntityList::iterator DoxygenEntityListIt; -typedef DoxygenEntityList::const_iterator DoxygenEntityListCIt; - - -/* - * Structure to represent a doxygen comment entry - */ -class DoxygenEntity { -public: - std::string typeOfEntity; - std::string data; - bool isLeaf; - DoxygenEntityList entityList; - - DoxygenEntity(const std::string &typeEnt); - DoxygenEntity(const std::string &typeEnt, const std::string ¶m1); - DoxygenEntity(const std::string &typeEnt, const DoxygenEntityList &entList); - - void printEntity(int level) const; -}; - -#endif diff --git a/contrib/tools/swig/Source/Doxygen/doxyparser.cxx b/contrib/tools/swig/Source/Doxygen/doxyparser.cxx deleted file mode 100644 index 0c445f1a04b..00000000000 --- a/contrib/tools/swig/Source/Doxygen/doxyparser.cxx +++ /dev/null @@ -1,1494 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * doxyparser.cxx - * ----------------------------------------------------------------------------- */ - -#include "doxyparser.h" -#include "doxycommands.h" -#include "swig.h" -#include "swigwarn.h" - -#include <iostream> -#include <algorithm> -#include <vector> - -using std::string; -using std::cout; -using std::endl; - -// This constant defines the (only) characters valid inside a Doxygen "word". -// It includes some unusual ones because of the commands such as \f[, \f{, \f], -// \f} and \f$. -static const char *DOXYGEN_WORD_CHARS = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" "$[]{}"; - -// Define static class members -DoxygenParser::DoxyCommandsMap DoxygenParser::doxygenCommands; -std::set<std::string> DoxygenParser::doxygenSectionIndicators; - -const int TOKENSPERLINE = 8; //change this to change the printing behaviour of the token list -const std::string END_HTML_TAG_MARK("/"); - -std::string getBaseCommand(const std::string &cmd) { - if (cmd.substr(0,5) == "param") - return "param"; - else if (cmd.substr(0,4) == "code") - return "code"; - else - return cmd; -} - -// Find the first position beyond the word command. Extra logic is -// used to avoid putting the characters "," and "." in -// DOXYGEN_WORD_CHARS. -static size_t getEndOfWordCommand(const std::string &line, size_t pos) { - size_t endOfWordPos = line.find_first_not_of(DOXYGEN_WORD_CHARS, pos); - if (line.substr(pos, 6) == "param[") - // include ",", which can appear in param[in,out] - endOfWordPos = line.find_first_not_of(string(DOXYGEN_WORD_CHARS)+ ",", pos); - else if (line.substr(pos, 5) == "code{") - // include ".", which can appear in e.g. code{.py} - endOfWordPos = line.find_first_not_of(string(DOXYGEN_WORD_CHARS)+ ".", pos); - return endOfWordPos; -} - - -DoxygenParser::DoxygenParser(bool noisy) : noisy(noisy) { - fillTables(); -} - -DoxygenParser::~DoxygenParser() { -} - -void DoxygenParser::fillTables() { - // run it only once - if (doxygenCommands.size()) - return; - - // fill in tables with data from doxycommands.h - for (int i = 0; i < simpleCommandsSize; i++) - doxygenCommands[simpleCommands[i]] = SIMPLECOMMAND; - - for (int i = 0; i < commandWordsSize; i++) - doxygenCommands[commandWords[i]] = COMMANDWORD; - - for (int i = 0; i < commandLinesSize; i++) - doxygenCommands[commandLines[i]] = COMMANDLINE; - - for (int i = 0; i < commandParagraphSize; i++) - doxygenCommands[commandParagraph[i]] = COMMANDPARAGRAPH; - - for (int i = 0; i < commandEndCommandsSize; i++) - doxygenCommands[commandEndCommands[i]] = COMMANDENDCOMMAND; - - for (int i = 0; i < commandWordParagraphsSize; i++) - doxygenCommands[commandWordParagraphs[i]] = COMMANDWORDPARAGRAPH; - - for (int i = 0; i < commandWordLinesSize; i++) - doxygenCommands[commandWordLines[i]] = COMMANDWORDLINE; - - for (int i = 0; i < commandWordOWordOWordsSize; i++) - doxygenCommands[commandWordOWordOWords[i]] = COMMANDWORDOWORDWORD; - - for (int i = 0; i < commandOWordsSize; i++) - doxygenCommands[commandOWords[i]] = COMMANDOWORD; - - for (int i = 0; i < commandErrorThrowingsSize; i++) - doxygenCommands[commandErrorThrowings[i]] = COMMANDERRORTHROW; - - for (int i = 0; i < commandUniquesSize; i++) - doxygenCommands[commandUniques[i]] = COMMANDUNIQUE; - - for (int i = 0; i < commandHtmlSize; i++) - doxygenCommands[commandHtml[i]] = COMMAND_HTML; - - for (int i = 0; i < commandHtmlEntitiesSize; i++) - doxygenCommands[commandHtmlEntities[i]] = COMMAND_HTML_ENTITY; - - // fill section indicators command set - for (int i = 0; i < sectionIndicatorsSize; i++) - doxygenSectionIndicators.insert(sectionIndicators[i]); -} - -std::string DoxygenParser::stringToLower(const std::string &stringToConvert) { - - string result(stringToConvert.size(), ' '); - - for (size_t i = 0; i < result.size(); i++) { - result[i] = tolower(stringToConvert[i]); - } - - return result; -} - -bool DoxygenParser::isSectionIndicator(const std::string &smallString) { - - std::set<std::string>::iterator it = doxygenSectionIndicators.find(stringToLower(smallString)); - - return it != doxygenSectionIndicators.end(); -} - -void DoxygenParser::printTree(const DoxygenEntityList &rootList) { - DoxygenEntityList::const_iterator p = rootList.begin(); - while (p != rootList.end()) { - (*p).printEntity(0); - p++; - } -} - -DoxygenParser::DoxyCommandEnum DoxygenParser::commandBelongs(const std::string &theCommand) { - DoxyCommandsMapIt it = doxygenCommands.find(stringToLower(getBaseCommand(theCommand))); - - if (it != doxygenCommands.end()) { - return it->second; - } - // Check if this command is defined as an alias. - if (Getattr(m_node, ("feature:doxygen:alias:" + theCommand).c_str())) { - return COMMAND_ALIAS; - } - // Check if this command should be ignored. - if (String *const ignore = getIgnoreFeature(theCommand)) { - // Check that no value is specified for this feature ("1" is the implicit - // one given to it by SWIG itself), we may use the value in the future, but - // for now we only use the attributes. - if (Strcmp(ignore, "1") != 0) { - Swig_warning(WARN_PP_UNEXPECTED_TOKENS, m_fileName.c_str(), m_fileLineNo, - "Feature \"doxygen:ignore\" value ignored for Doxygen command \"%s\".\n", theCommand.c_str()); - } - // Also ensure that the matching end command, if any, will be recognized. - const string endCommand = getIgnoreFeatureEndCommand(theCommand); - if (!endCommand.empty()) { - Setattr(m_node, ("feature:doxygen:ignore:" + endCommand).c_str(), NewString("1")); - } - - return COMMAND_IGNORE; - } - - return NONE; -} - -std::string DoxygenParser::trim(const std::string &text) { - size_t start = text.find_first_not_of(" \t"); - size_t end = text.find_last_not_of(" \t"); - - if (start == string::npos || start > end) { - return ""; - } - return text.substr(start, end - start + 1); -} - -bool DoxygenParser::isEndOfLine() { - if (m_tokenListIt == m_tokenList.end()) { - return false; - } - Token nextToken = *m_tokenListIt; - return nextToken.m_tokenType == END_LINE; -} - -void DoxygenParser::skipWhitespaceTokens() { - if (m_tokenListIt == m_tokenList.end()) { - return; - } - - while (m_tokenListIt != m_tokenList.end() - && (m_tokenListIt->m_tokenType == END_LINE || trim(m_tokenListIt->m_tokenString).empty())) { - - m_tokenListIt++; - } -} - -std::string DoxygenParser::getNextToken() { - - if (m_tokenListIt == m_tokenList.end()) { - return ""; - } - - if (m_tokenListIt->m_tokenType == PLAINSTRING) { - return (m_tokenListIt++)->m_tokenString; - } - - return ""; -} - -std::string DoxygenParser::getNextWord() { - - /* if (m_tokenListIt == m_tokenList.end()) { - return ""; - } - */ - while (m_tokenListIt != m_tokenList.end() - && (m_tokenListIt->m_tokenType == PLAINSTRING)) { - // handle quoted strings as words - string token = m_tokenListIt->m_tokenString; - if (token == "\"") { - - string word = m_tokenListIt->m_tokenString; - m_tokenListIt++; - while (true) { - string nextWord = getNextToken(); - if (nextWord.empty()) { // maybe report unterminated string error - return word; - } - word += nextWord; - if (nextWord == "\"") { - return word; - } - } - } - - string tokenStr = trim(m_tokenListIt->m_tokenString); - m_tokenListIt++; - if (!tokenStr.empty()) { - return tokenStr; - } - } - - return ""; -} - -DoxygenParser::TokenListCIt DoxygenParser::getOneLine(const TokenList &tokList) { - - TokenListCIt endOfLineIt = m_tokenListIt; - - while (endOfLineIt != tokList.end()) { - if (endOfLineIt->m_tokenType == END_LINE) { - return endOfLineIt; - } - endOfLineIt++; - } - - return tokList.end(); -} - -std::string DoxygenParser::getStringTilCommand(const TokenList &tokList) { - - if (m_tokenListIt == tokList.end()) { - return ""; - } - - string description; - - while (m_tokenListIt->m_tokenType == PLAINSTRING) { - const Token ¤tToken = *m_tokenListIt++; - if (currentToken.m_tokenType == PLAINSTRING) { - description = description + currentToken.m_tokenString; // + " "; - } - } - return description; -} - -std::string DoxygenParser::getStringTilEndCommand(const std::string &theCommand, const TokenList &tokList) { - - if (m_tokenListIt == tokList.end()) { - return ""; - } - - string description; - while (m_tokenListIt != tokList.end()) { - - if (m_tokenListIt->m_tokenType == PLAINSTRING) { - description += m_tokenListIt->m_tokenString; - } else if (m_tokenListIt->m_tokenType == END_LINE) { - description += "\n"; - } else if (m_tokenListIt->m_tokenString == theCommand) { - m_tokenListIt++; - return description; - } - - m_tokenListIt++; - } - - printListError(WARN_DOXYGEN_COMMAND_EXPECTED, "Expected Doxygen command: " + theCommand + "."); - - return description; -} - -DoxygenParser::TokenListCIt DoxygenParser::getEndOfParagraph(const TokenList &tokList) { - - TokenListCIt endOfParagraph = m_tokenListIt; - - while (endOfParagraph != tokList.end()) { - // If \code or \verbatim is encountered within a paragraph, then - // go all the way to the end of that command, since the content - // could contain empty lines that would appear to be paragraph - // ends: - if (endOfParagraph->m_tokenType == COMMAND && - (endOfParagraph->m_tokenString == "code" || - endOfParagraph->m_tokenString == "verbatim")) { - const string theCommand = endOfParagraph->m_tokenString; - endOfParagraph = getEndCommand("end" + theCommand, tokList); - endOfParagraph++; // Move after the end command - return endOfParagraph; - } - if (endOfParagraph->m_tokenType == END_LINE) { - endOfParagraph++; - if (endOfParagraph != tokList.end() - && endOfParagraph->m_tokenType == END_LINE) { - endOfParagraph++; - //cout << "ENCOUNTERED END OF PARA" << endl; - return endOfParagraph; - } - - } else if (endOfParagraph->m_tokenType == COMMAND) { - - if (isSectionIndicator(getBaseCommand(endOfParagraph->m_tokenString))) { - return endOfParagraph; - } else { - endOfParagraph++; - } - - } else if (endOfParagraph->m_tokenType == PLAINSTRING) { - endOfParagraph++; - } else { - return tokList.end(); - } - } - - return tokList.end(); -} - -DoxygenParser::TokenListCIt DoxygenParser::getEndOfSection(const std::string &theCommand, const TokenList &tokList) { - - TokenListCIt endOfParagraph = m_tokenListIt; - - while (endOfParagraph != tokList.end()) { - if (endOfParagraph->m_tokenType == COMMAND) { - if (theCommand == endOfParagraph->m_tokenString) - return endOfParagraph; - else - endOfParagraph++; - } else if (endOfParagraph->m_tokenType == PLAINSTRING) { - endOfParagraph++; - } else if (endOfParagraph->m_tokenType == END_LINE) { - endOfParagraph++; - if (endOfParagraph->m_tokenType == END_LINE) { - endOfParagraph++; - return endOfParagraph; - } - } - } - return tokList.end(); -} - -DoxygenParser::TokenListCIt DoxygenParser::getEndCommand(const std::string &theCommand, const TokenList &tokList) { - - TokenListCIt endOfCommand = m_tokenListIt; - - while (endOfCommand != tokList.end()) { - endOfCommand++; - if ((*endOfCommand).m_tokenType == COMMAND) { - if (theCommand == (*endOfCommand).m_tokenString) { - return endOfCommand; - } - } - } - //End command not found - return tokList.end(); -} - -void DoxygenParser::skipEndOfLine() { - if (m_tokenListIt != m_tokenList.end() - && m_tokenListIt->m_tokenType == END_LINE) { - m_tokenListIt++; - } -} - -void DoxygenParser::addSimpleCommand(const std::string &theCommand, DoxygenEntityList &doxyList) { - if (noisy) - cout << "Parsing " << theCommand << endl; - - doxyList.push_back(DoxygenEntity(theCommand)); -} - -void DoxygenParser::addCommandWord(const std::string &theCommand, const TokenList &, DoxygenEntityList &doxyList) { - if (noisy) - cout << "Parsing " << theCommand << endl; - - if (isEndOfLine()) { - // handles cases when command is at the end of line (for example "\c\nreally" - skipWhitespaceTokens(); - doxyList.push_back(DoxygenEntity("plainstd::endl")); - } - std::string name = getNextWord(); - if (!name.empty()) { - DoxygenEntityList aNewList; - aNewList.push_back(DoxygenEntity("plainstd::string", name)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } else { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored."); - } -} - -void DoxygenParser::addCommandLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) { - if (noisy) - cout << "Parsing " << theCommand << endl; - TokenListCIt endOfLine = getOneLine(tokList); - DoxygenEntityList aNewList = parse(endOfLine, tokList); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - skipEndOfLine(); -} - -void DoxygenParser::addCommandParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) { - if (noisy) - cout << "Parsing " << theCommand << endl; - - TokenListCIt endOfParagraph = getEndOfParagraph(tokList); - DoxygenEntityList aNewList; - aNewList = parse(endOfParagraph, tokList); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); -} - -void DoxygenParser::addCommandEndCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) { - if (noisy) - cout << "Parsing " << theCommand << endl; - TokenListCIt endCommand = getEndCommand("end" + theCommand, tokList); - if (endCommand == tokList.end()) { - printListError(WARN_DOXYGEN_COMMAND_EXPECTED, "Expected Doxygen command: end" + theCommand + "."); - return; - } - DoxygenEntityList aNewList; - aNewList = parse(endCommand, tokList); - m_tokenListIt++; - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); -} - -void DoxygenParser::addCommandWordParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) { - if (noisy) - cout << "Parsing " << theCommand << endl; - - std::string name = getNextWord(); - - if (name.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored."); - return; - } - TokenListCIt endOfParagraph = getEndOfParagraph(tokList); - DoxygenEntityList aNewList; - aNewList = parse(endOfParagraph, tokList); - aNewList.push_front(DoxygenEntity("plainstd::string", name)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); -} - -void DoxygenParser::addCommandWordLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) { - if (noisy) - cout << "Parsing " << theCommand << endl; - std::string name = getNextWord(); - if (name.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored."); - return; - } - - TokenListCIt endOfLine = getOneLine(tokList); - DoxygenEntityList aNewList; - aNewList = parse(endOfLine, tokList); - aNewList.push_front(DoxygenEntity("plainstd::string", name)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - //else cout << "No line followed " << theCommand << " command. Not added" << endl; -} - -void DoxygenParser::addCommandWordOWordOWord(const std::string &theCommand, const TokenList &, DoxygenEntityList &doxyList) { - if (noisy) - cout << "Parsing " << theCommand << endl; - - std::string name = getNextWord(); - if (name.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored."); - return; - } - std::string headerfile = getNextWord(); - std::string headername = getNextWord(); - DoxygenEntityList aNewList; - aNewList.push_back(DoxygenEntity("plainstd::string", name)); - if (!headerfile.empty()) - aNewList.push_back(DoxygenEntity("plainstd::string", headerfile)); - if (!headername.empty()) - aNewList.push_back(DoxygenEntity("plainstd::string", headername)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); -} - -void DoxygenParser::addCommandOWord(const std::string &theCommand, const TokenList &, DoxygenEntityList &doxyList) { - if (noisy) - cout << "Parsing " << theCommand << endl; - - std::string name = getNextWord(); - DoxygenEntityList aNewList; - aNewList.push_back(DoxygenEntity("plainstd::string", name)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); -} - -void DoxygenParser::addCommandErrorThrow(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &) { - - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": Unexpectedly encountered this command."); - m_tokenListIt = getOneLine(tokList); -} - -void DoxygenParser::addCommandHtml(const std::string &theCommand, const TokenList &, DoxygenEntityList &doxyList) { - if (noisy) - cout << "Parsing " << theCommand << endl; - - std::string htmlTagArgs = getNextToken(); - doxyList.push_back(DoxygenEntity(theCommand, htmlTagArgs)); -} - -void DoxygenParser::addCommandHtmlEntity(const std::string &theCommand, const TokenList &, DoxygenEntityList &doxyList) { - if (noisy) - cout << "Parsing " << theCommand << endl; - - DoxygenEntityList aNewList; - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); -} - -void DoxygenParser::addCommandUnique(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) { - - static std::map<std::string, std::string> endCommands; - DoxygenEntityList aNewList; - if (theCommand == "arg" || theCommand == "li") { - TokenListCIt endOfSection = getEndOfSection(theCommand, tokList); - DoxygenEntityList aNewList; - aNewList = parse(endOfSection, tokList); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } - // \xrefitem <key> "(heading)" "(std::list title)" {text} - else if (theCommand == "xrefitem") { - if (noisy) - cout << "Parsing " << theCommand << endl; - std::string key = getNextWord(); - if (key.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No key followed the command. Command ignored."); - return; - } - std::string heading = getNextWord(); - if (key.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No heading followed the command. Command ignored."); - return; - } - std::string title = getNextWord(); - if (title.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No title followed the command. Command ignored."); - return; - } - TokenListCIt endOfParagraph = getEndOfParagraph(tokList); - aNewList = parse(endOfParagraph, tokList); - aNewList.push_front(DoxygenEntity("plainstd::string", title)); - aNewList.push_front(DoxygenEntity("plainstd::string", heading)); - aNewList.push_front(DoxygenEntity("plainstd::string", key)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } - // \ingroup (<groupname> [<groupname> <groupname>]) - else if (theCommand == "ingroup") { - std::string name = getNextWord(); - aNewList.push_back(DoxygenEntity("plainstd::string", name)); - name = getNextWord(); - if (!name.empty()) - aNewList.push_back(DoxygenEntity("plainstd::string", name)); - name = getNextWord(); - if (!name.empty()) - aNewList.push_back(DoxygenEntity("plainstd::string", name)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } - // \par [(paragraph title)] { paragraph } - else if (theCommand == "par") { - TokenListCIt endOfLine = getOneLine(tokList); - aNewList = parse(endOfLine, tokList); - DoxygenEntityList aNewList2; - TokenListCIt endOfParagraph = getEndOfParagraph(tokList); - aNewList2 = parse(endOfParagraph, tokList); - aNewList.splice(aNewList.end(), aNewList2); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } - // \headerfile <header-file> [<header-name>] - else if (theCommand == "headerfile") { - DoxygenEntityList aNewList; - std::string name = getNextWord(); - aNewList.push_back(DoxygenEntity("plainstd::string", name)); - name = getNextWord(); - if (!name.empty()) - aNewList.push_back(DoxygenEntity("plainstd::string", name)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } - // \overload [(function declaration)] - else if (theCommand == "overload") { - TokenListCIt endOfLine = getOneLine(tokList); - if (endOfLine != m_tokenListIt) { - DoxygenEntityList aNewList; - aNewList = parse(endOfLine, tokList); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } else - doxyList.push_back(DoxygenEntity(theCommand)); - } - // \weakgroup <name> [(title)] - else if (theCommand == "weakgroup") { - if (noisy) - cout << "Parsing " << theCommand << endl; - std::string name = getNextWord(); - if (name.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored."); - return; - } - DoxygenEntityList aNewList; - TokenListCIt endOfLine = getOneLine(tokList); - if (endOfLine != m_tokenListIt) { - aNewList = parse(endOfLine, tokList); - } - aNewList.push_front(DoxygenEntity("plainstd::string", name)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } - // \ref <name> ["(text)"] - else if (theCommand == "ref") { - if (noisy) - cout << "Parsing " << theCommand << endl; - std::string name = getNextWord(); - if (name.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No key followed the command. Command ignored."); - return; - } - DoxygenEntityList aNewList; - aNewList.push_front(DoxygenEntity("plainstd::string", name)); - // TokenListCIt endOfLine = getOneLine(tokList); - // if (endOfLine != m_tokenListIt) { - // aNewList = parse(endOfLine, tokList); - //} - TokenListCIt tmpIt = m_tokenListIt; - std::string refTitle = getNextWord(); - // If title is following the ref tag, it must be quoted. Otherwise - // doxy puts link on ref id. - if (refTitle.size() > 1 && refTitle[0] == '"') { - // remove quotes - refTitle = refTitle.substr(1, refTitle.size() - 2); - aNewList.push_back(DoxygenEntity("plainstd::string", refTitle)); - } else { - // no quoted string is following, so we have to restore iterator - m_tokenListIt = tmpIt; - } - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } - // \subpage <name> ["(text)"] - else if (theCommand == "subpage") { - if (noisy) - cout << "Parsing " << theCommand << endl; - std::string name = getNextWord(); - if (name.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No name followed the command. Command ignored."); - return; - } - std::string text = getNextWord(); - aNewList.push_back(DoxygenEntity("plainstd::string", name)); - if (!text.empty()) - aNewList.push_back(DoxygenEntity("plainstd::string", text)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } - // \code ... \endcode - // \verbatim ... \endverbatim - // \dot dotcode \enddot - // \msc msccode \endmsc - // \f[ ... \f] - // \f{ ... \f} - // \f{env}{ ... \f} - // \f$ ... \f$ - else if (getBaseCommand(theCommand) == "code" || theCommand == "verbatim" - || theCommand == "dot" || theCommand == "msc" || theCommand == "f[" || theCommand == "f{" || theCommand == "f$") { - if (!endCommands.size()) { - // fill in static table of end commands - endCommands["f["] = "f]"; - endCommands["f{"] = "f}"; - endCommands["f$"] = "f$"; - } - if (noisy) - cout << "Parsing " << theCommand << endl; - - std::string endCommand; - std::map<std::string, std::string>::iterator it; - it = endCommands.find(theCommand); - if (it != endCommands.end()) - endCommand = it->second; - else - endCommand = "end" + getBaseCommand(theCommand); - - std::string content = getStringTilEndCommand(endCommand, tokList); - aNewList.push_back(DoxygenEntity("plainstd::string", content)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } - // \dotfile <file> ["caption"] - // \mscfile <file> ["caption"] - else if (theCommand == "dotfile" || theCommand == "mscfile") { - if (noisy) - cout << "Parsing " << theCommand << endl; - std::string file = getNextWord(); - if (file.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No file followed the command. Command ignored."); - return; - } - std::string caption = getNextWord(); - aNewList.push_back(DoxygenEntity("plainstd::string", file)); - if (!caption.empty()) - aNewList.push_back(DoxygenEntity("plainstd::string", caption)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } - // \image <format> <file> ["caption"] [<sizeindication>=<size>] - else if (theCommand == "image") { - if (noisy) - cout << "Parsing " << theCommand << endl; - std::string format = getNextWord(); - if (format.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No format followed the command. Command ignored."); - return; - } - std::string file = getNextWord(); - if (file.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No name followed the command. Command ignored."); - return; - } - std::string caption = getNextWord(); - std::string size = getNextWord(); - - DoxygenEntityList aNewList; - aNewList.push_back(DoxygenEntity("plainstd::string", format)); - aNewList.push_back(DoxygenEntity("plainstd::string", file)); - if (!caption.empty()) - aNewList.push_back(DoxygenEntity("plainstd::string", caption)); - if (!size.empty()) - aNewList.push_back(DoxygenEntity("plainstd::string", size)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } - // \addtogroup <name> [(title)] - else if (theCommand == "addtogroup") { - if (noisy) - cout << "Parsing " << theCommand << endl; - std::string name = getNextWord(); - if (name.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": There should be at least one word following the command. Command ignored."); - return; - } - DoxygenEntityList aNewList; - TokenListCIt endOfLine = getOneLine(tokList); - if (endOfLine != m_tokenListIt) { - aNewList = parse(endOfLine, tokList); - } - aNewList.push_front(DoxygenEntity("plainstd::string", name)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - skipEndOfLine(); - } - // \if <cond> [\else ...] [\elseif <cond> ...] \endif - else if (theCommand == "if" || theCommand == "ifnot" || theCommand == "else" || theCommand == "elseif") { - if (noisy) - cout << "Parsing " << theCommand << endl; - - std::string cond; - bool skipEndif = false; // if true then we skip endif after parsing block of code - bool needsCond = (theCommand == "if" || theCommand == "ifnot" || theCommand == "elseif"); - if (needsCond) { - cond = getNextWord(); - if (cond.empty()) { - printListError(WARN_DOXYGEN_COMMAND_ERROR, "Error parsing Doxygen command " + theCommand + ": No word followed the command. Command ignored."); - return; - } - } - - int nestedCounter = 1; - TokenListCIt endCommand = tokList.end(); - - // go through the commands and find closing endif or else or elseif - for (TokenListCIt it = m_tokenListIt; it != tokList.end(); it++) { - if (it->m_tokenType == COMMAND) { - if (it->m_tokenString == "if" || it->m_tokenString == "ifnot") - nestedCounter++; - else if (it->m_tokenString == "endif") - nestedCounter--; - if (nestedCounter == 1 && (it->m_tokenString == "else" || it->m_tokenString == "elseif")) { // else found - endCommand = it; - break; - } - if (nestedCounter == 0) { // endif found - endCommand = it; - skipEndif = true; - break; - } - } - } - - if (endCommand == tokList.end()) { - printListError(WARN_DOXYGEN_COMMAND_EXPECTED, "Expected Doxygen command: endif."); - return; - } - - DoxygenEntityList aNewList; - aNewList = parse(endCommand, tokList); - if (skipEndif) - m_tokenListIt++; - if (needsCond) - aNewList.push_front(DoxygenEntity("plainstd::string", cond)); - doxyList.push_back(DoxygenEntity(theCommand, aNewList)); - } -} - -void DoxygenParser::aliasCommand(const std::string &theCommand, const TokenList &/* tokList */ , DoxygenEntityList &doxyList) { - String *const alias = Getattr(m_node, ("feature:doxygen:alias:" + theCommand).c_str()); - if (!alias) - return; - - doxyList.push_back(DoxygenEntity("plainstd::string", Char(alias))); -} - -String *DoxygenParser::getIgnoreFeature(const std::string &theCommand, const char *argument) const { - string feature_name = "feature:doxygen:ignore:" + theCommand; - if (argument) { - feature_name += ':'; - feature_name += argument; - } - - return Getattr(m_node, feature_name.c_str()); -} - -string DoxygenParser::getIgnoreFeatureEndCommand(const std::string &theCommand) const { - // We may be dealing either with a simple command or with the starting command - // of a block, as indicated by the value of "range" starting with "end". - string endCommand; - if (String *const range = getIgnoreFeature(theCommand, "range")) { - const char *const p = Char(range); - if (strncmp(p, "end", 3) == 0) { - if (p[3] == ':') { - // Normally the end command name follows after the colon. - endCommand = p + 4; - } else if (p[3] == '\0') { - // But it may be omitted in which case the default Doxygen convention of - // using "something"/"endsomething" is used. - endCommand = "end" + theCommand; - } - } - } - - return endCommand; -} - -void DoxygenParser::ignoreCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList) { - const string endCommand = getIgnoreFeatureEndCommand(theCommand); - if (!endCommand.empty()) { - TokenListCIt itEnd = getEndCommand(endCommand, tokList); - if (itEnd == tokList.end()) { - printListError(WARN_DOXYGEN_COMMAND_EXPECTED, "Expected Doxygen command: " + endCommand + "."); - return; - } - // If we ignore the command, also ignore any whitespace preceding it as we - // want to avoid having lines consisting of whitespace only or trailing - // whitespace in general (at least Python, with its pep8 tool, really - // doesn't like it). - if (!doxyList.empty()) { - DoxygenEntityList::iterator i = doxyList.end(); - --i; - if (i->typeOfEntity == "plainstd::string" && i->data.find_first_not_of(" \t") == std::string::npos) { - doxyList.erase(i); - } - } - // Determine what to do with the part of the comment between the start and - // end commands: by default, we simply throw it away, but "contents" - // attribute may be used to change this. - if (String *const contents = getIgnoreFeature(theCommand, "contents")) { - // Currently only "parse" is supported but we may need to add "copy" to - // handle custom tags which contain text that is supposed to be copied - // verbatim in the future. - if (Strcmp(contents, "parse") == 0) { - DoxygenEntityList aNewList = parse(itEnd, tokList); - doxyList.splice(doxyList.end(), aNewList); - } else { - Swig_error(m_fileName.c_str(), m_fileLineNo, "Invalid \"doxygen:ignore\" feature \"contents\" attribute \"%s\".\n", Char(contents)); - return; - } - } - - m_tokenListIt = itEnd; - m_tokenListIt++; - } else if (String *const range = getIgnoreFeature(theCommand, "range")) { - // Currently we only support "line" but, in principle, we should also - // support "word" and "paragraph" for consistency with the built-in Doxygen - // commands which can have either of these three ranges (which are indicated - // using <word-arg>, (line-arg) and {para-arg} respectively in Doxygen - // documentation). - if (Strcmp(range, "line") == 0) { - // Consume everything until the end of line. - m_tokenListIt = getOneLine(tokList); - skipEndOfLine(); - } else { - Swig_error(m_fileName.c_str(), m_fileLineNo, "Invalid \"doxygen:ignore\" feature \"range\" attribute \"%s\".\n", Char(range)); - return; - } - } -} - -void DoxygenParser::addCommand(const std::string &commandString, const TokenList &tokList, DoxygenEntityList &doxyList) { - - string theCommand = stringToLower(commandString); - - if (theCommand == "plainstd::string") { - string nextPhrase = getStringTilCommand(tokList); - if (noisy) - cout << "Parsing plain std::string :" << nextPhrase << endl; - doxyList.push_back(DoxygenEntity("plainstd::string", nextPhrase)); - return; - } - - switch (commandBelongs(commandString)) { - case SIMPLECOMMAND: - addSimpleCommand(theCommand, doxyList); - break; - case COMMANDWORD: - addCommandWord(theCommand, tokList, doxyList); - break; - case COMMANDLINE: - addCommandLine(theCommand, tokList, doxyList); - break; - case COMMANDPARAGRAPH: - addCommandParagraph(theCommand, tokList, doxyList); - break; - case COMMANDENDCOMMAND: - addCommandEndCommand(theCommand, tokList, doxyList); - break; - case COMMANDWORDPARAGRAPH: - addCommandWordParagraph(theCommand, tokList, doxyList); - break; - case COMMANDWORDLINE: - addCommandWordLine(theCommand, tokList, doxyList); - break; - case COMMANDWORDOWORDWORD: - addCommandWordOWordOWord(theCommand, tokList, doxyList); - break; - case COMMANDOWORD: - addCommandOWord(theCommand, tokList, doxyList); - break; - case COMMANDERRORTHROW: - addCommandErrorThrow(theCommand, tokList, doxyList); - break; - case COMMANDUNIQUE: - addCommandUnique(theCommand, tokList, doxyList); - break; - case COMMAND_HTML: - addCommandHtml(theCommand, tokList, doxyList); - break; - case COMMAND_HTML_ENTITY: - addCommandHtmlEntity(theCommand, tokList, doxyList); - break; - case COMMAND_ALIAS: - aliasCommand(commandString, tokList, doxyList); - break; - case COMMAND_IGNORE: - ignoreCommand(commandString, tokList, doxyList); - break; - case NONE: - case END_LINE: - case PARAGRAPH_END: - case PLAINSTRING: - case COMMAND: - // TODO: Ensure that these values either are correctly ignored here or can't happen. - break; - } -} - -/** - * This method converts TokenList to DoxygenEntryList. - */ -DoxygenEntityList DoxygenParser::parse(TokenListCIt endParsingIndex, const TokenList &tokList, bool root) { - // if we are root, than any strings should be added as 'partofdescription', else as 'plainstd::string' - std::string currPlainstringCommandType = root ? "partofdescription" : "plainstd::string"; - DoxygenEntityList aNewList; - - // Less than check (instead of not equal) is a safeguard in case the - // iterator is incremented past the end - while (m_tokenListIt < endParsingIndex) { - - Token currToken = *m_tokenListIt; - - if (noisy) - cout << "Parsing for phrase starting in:" << currToken.toString() << endl; - - if (currToken.m_tokenType == END_LINE) { - aNewList.push_back(DoxygenEntity("plainstd::endl")); - m_tokenListIt++; - } else if (currToken.m_tokenType == COMMAND) { - m_tokenListIt++; - addCommand(currToken.m_tokenString, tokList, aNewList); - } else if (currToken.m_tokenType == PLAINSTRING) { - addCommand(currPlainstringCommandType, tokList, aNewList); - } - - // If addCommand above misbehaves, it can move the iterator past endParsingIndex - if (m_tokenListIt > endParsingIndex) - printListError(WARN_DOXYGEN_UNEXPECTED_ITERATOR_VALUE, "Unexpected iterator value in DoxygenParser::parse"); - - if (endParsingIndex != tokList.end() && m_tokenListIt == tokList.end()) { - // this could happen if we can't reach the original endParsingIndex - printListError(WARN_DOXYGEN_UNEXPECTED_END_OF_COMMENT, "Unexpected end of Doxygen comment encountered."); - break; - } - } - return aNewList; -} - -DoxygenEntityList DoxygenParser::createTree(Node *node, String *documentation) { - m_node = node; - - tokenizeDoxygenComment(Char(documentation), Char(Getfile(documentation)), Getline(documentation)); - - if (noisy) { - cout << "---TOKEN LIST---" << endl; - printList(); - } - - DoxygenEntityList rootList = parse(m_tokenList.end(), m_tokenList, true); - - if (noisy) { - cout << "PARSED LIST" << endl; - printTree(rootList); - } - return rootList; -} - -/* - * Splits 'text' on 'separator' chars. Separator chars are not part of the - * strings. - */ -DoxygenParser::StringVector DoxygenParser::split(const std::string &text, char separator) { - StringVector lines; - size_t prevPos = 0, pos = 0; - - while (pos < string::npos) { - pos = text.find(separator, prevPos); - lines.push_back(text.substr(prevPos, pos - prevPos)); - prevPos = pos + 1; - } - - return lines; -} - -/* - * Returns true, if 'c' is one of doxygen comment block start - * characters: *, /, or ! - */ -bool DoxygenParser::isStartOfDoxyCommentChar(char c) { - return (strchr("*/!", c) != NULL); -} - -/* - * Adds token with Doxygen command to token list, but only if command is one of - * Doxygen commands. In that case true is returned. If the command is not - * recognized as a doxygen command, it is ignored and false is returned. - */ -bool DoxygenParser::addDoxyCommand(DoxygenParser::TokenList &tokList, const std::string &cmd) { - if (commandBelongs(cmd) != NONE) { - tokList.push_back(Token(COMMAND, cmd)); - return true; - } else { - if (cmd.empty()) { - // This actually indicates a bug in the code in this file, as this - // function shouldn't be called at all in this case. - printListError(WARN_DOXYGEN_UNKNOWN_COMMAND, "Unexpected empty Doxygen command."); - return false; - } - - // This function is called for the special Doxygen commands, but also for - // HTML commands (or anything that looks like them, actually) and entities. - // We don't recognize all of those, so just ignore them and pass them - // through, but warn about unknown Doxygen commands as ignoring them will - // often result in wrong output being generated. - const char ch = *cmd.begin(); - if (ch != '<' && ch != '&') { - // Before calling printListError() we must ensure that m_tokenListIt used - // by it is valid. - const TokenListCIt itSave = m_tokenListIt; - m_tokenListIt = m_tokenList.end(); - - printListError(WARN_DOXYGEN_UNKNOWN_COMMAND, "Unknown Doxygen command: " + cmd + "."); - - m_tokenListIt = itSave; - } - } - - return false; -} - -/* - * This method copies comment text to output as it is - no processing is - * done, Doxygen commands are ignored. It is used for commands \verbatim, - * \htmlonly, \f$, \f[, and \f{. - */ -size_t DoxygenParser::processVerbatimText(size_t pos, const std::string &line) { - if (line[pos] == '\\' || line[pos] == '@') { // check for end commands - - pos++; - size_t endOfWordPos = line.find_first_not_of(DOXYGEN_WORD_CHARS, pos); - string cmd = line.substr(pos, endOfWordPos - pos); - - if (cmd == CMD_END_HTML_ONLY || cmd == CMD_END_VERBATIM || cmd == CMD_END_LATEX_1 || cmd == CMD_END_LATEX_2 || cmd == CMD_END_LATEX_3 || cmd == CMD_END_CODE) { - - m_isVerbatimText = false; - addDoxyCommand(m_tokenList, cmd); - - } else { - - m_tokenList.push_back(Token(PLAINSTRING, - // include '\' or '@' - line.substr(pos - 1, endOfWordPos - pos + 1))); - } - - pos = endOfWordPos; - - } else { - - // whitespaces are stored as plain strings - size_t startOfPossibleEndCmd = line.find_first_of("\\@", pos); - m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, startOfPossibleEndCmd - pos))); - pos = startOfPossibleEndCmd; - } - - return pos; -} - -/* - * Processes doxy commands for escaped characters: \$ \@ \\ \& \~ \< \> \# \% \" \. \:: - * Handling this separately supports documentation text like \@someText. - */ -bool DoxygenParser::processEscapedChars(size_t &pos, const std::string &line) { - if ((pos + 1) < line.size()) { - - // \ and @ with trailing whitespace or quoted get to output as plain string - string whitespaces = " '\t\n"; - if (whitespaces.find(line[pos + 1]) != string::npos) { - m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, 1))); - pos++; - return true; - } - // these chars can be escaped for doxygen - string escapedChars = "$@\\&~<>#%\"."; - if (escapedChars.find(line[pos + 1]) != string::npos) { - - addDoxyCommand(m_tokenList, line.substr(pos + 1, 1)); - pos += 2; - return true; - - } else if ((pos + 2) < line.size() && line[pos + 1] == ':' && line[pos + 2] == ':') { - - // add command \:: - handling this separately supports documentation - // text like \::someText - addDoxyCommand(m_tokenList, line.substr(pos + 1, 2)); - pos += 3; - return true; - } - } - return false; -} - -/* - * Processes word doxygen commands, like \arg, \c, \b, \return, ... - */ -void DoxygenParser::processWordCommands(size_t &pos, const std::string &line) { - pos++; - size_t endOfWordPos = getEndOfWordCommand(line, pos); - - string cmd = line.substr(pos, endOfWordPos - pos); - if (cmd.empty()) { - // This was a bare backslash, just ignore it. - return; - } - - addDoxyCommand(m_tokenList, cmd); - - // A flag for whether we want to skip leading spaces after the command - bool skipLeadingSpace = true; - - if (cmd == CMD_HTML_ONLY || cmd == CMD_VERBATIM || cmd == CMD_LATEX_1 || cmd == CMD_LATEX_2 || cmd == CMD_LATEX_3 || getBaseCommand(cmd) == CMD_CODE) { - - m_isVerbatimText = true; - - // Skipping leading space is necessary with inline \code command, - // and it won't hurt anything for block \code (TODO: are the other - // commands also compatible with skip leading space? If so, just - // do it every time.) - if (getBaseCommand(cmd) == CMD_CODE) skipLeadingSpace = true; - else skipLeadingSpace = false; - } else if (cmd.substr(0,3) == "end") { - // If processing an "end" command such as "endlink", don't skip - // the space before the next string - skipLeadingSpace = false; - } - - if (skipLeadingSpace) { - // skip any possible spaces after command, because some commands have parameters, - // and spaces between command and parameter must be ignored. - if (endOfWordPos != string::npos) { - endOfWordPos = line.find_first_not_of(" \t", endOfWordPos); - } - } - - pos = endOfWordPos; -} - -void DoxygenParser::processHtmlTags(size_t &pos, const std::string &line) { - bool isEndHtmlTag = false; - pos++; - if (line.size() > pos && line[pos] == '/') { - isEndHtmlTag = true; - pos++; - } - - size_t endHtmlPos = line.find_first_of("\t >", pos); - - string cmd = line.substr(pos, endHtmlPos - pos); - pos = endHtmlPos; - - // prepend '<' to distinguish HTML tags from doxygen commands - if (!cmd.empty() && addDoxyCommand(m_tokenList, '<' + cmd)) { - // it is a valid HTML command - if (pos == string::npos) { - pos = line.size(); - } - if (line[pos] != '>') { - // it should be HTML tag with args, - // for example <A ...>, <IMG ...>, ... - if (isEndHtmlTag) { - m_tokenListIt = m_tokenList.end(); - printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": Illegal end HTML tag without greater-than ('>') found."); - } - - endHtmlPos = line.find(">", pos); - if (endHtmlPos == string::npos) { - m_tokenListIt = m_tokenList.end(); - printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": HTML tag without greater-than ('>') found."); - } - // add args of HTML command, like link URL, image URL, ... - m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, endHtmlPos - pos))); - pos = endHtmlPos; - } else { - if (isEndHtmlTag) { - m_tokenList.push_back(Token(PLAINSTRING, END_HTML_TAG_MARK)); - } else { - // it is a simple tag, so push empty string - m_tokenList.push_back(Token(PLAINSTRING, "")); - } - } - - if (pos < line.size()) { - pos++; // skip '>' - } - } else { - // the command is not HTML supported by Doxygen, < and > will be - // replaced by HTML entities < and > respectively, - addDoxyCommand(m_tokenList, "<"); - m_tokenList.push_back(Token(PLAINSTRING, cmd)); - } -} - -void DoxygenParser::processHtmlEntities(size_t &pos, const std::string &line) { - size_t endOfWordPos = line.find_first_not_of("abcdefghijklmnopqrstuvwxyz", pos + 1); - - if (endOfWordPos != string::npos) { - - if (line[endOfWordPos] == ';' && (endOfWordPos - pos) > 1) { - // if entity is not recognized by Doxygen (not in the list of - // commands) nothing is added (here and in Doxygen). - addDoxyCommand(m_tokenList, line.substr(pos, endOfWordPos - pos)); - endOfWordPos++; // skip ';' - } else { - // it is not an entity - add entity for ampersand and the rest of string - addDoxyCommand(m_tokenList, "&"); - m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos + 1, endOfWordPos - pos - 1))); - } - } - pos = endOfWordPos; -} - -/* - * This method processes normal comment, which has to be tokenized. - */ -size_t DoxygenParser::processNormalComment(size_t pos, const std::string &line) { - switch (line[pos]) { - case '\\': - case '@': - if (processEscapedChars(pos, line)) { - break; - } - // handle word commands \arg, \c, \return, ... and \f[, \f$, ... commands - processWordCommands(pos, line); - break; - - case ' ': // whitespace - case '\t': - { - // whitespaces are stored as plain strings - size_t startOfNextWordPos = line.find_first_not_of(" \t", pos + 1); - m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, startOfNextWordPos - pos))); - pos = startOfNextWordPos; - } - break; - - case '<': - processHtmlTags(pos, line); - break; - case '>': // this char is detected here only when it is not part of HTML tag - addDoxyCommand(m_tokenList, ">"); - pos++; - break; - case '&': - processHtmlEntities(pos, line); - break; - case '"': - m_isInQuotedString = true; - m_tokenList.push_back(Token(PLAINSTRING, "\"")); - pos++; - break; - default: - m_tokenListIt = m_tokenList.end(); - printListError(WARN_DOXYGEN_UNKNOWN_CHARACTER, std::string("Unknown special character in Doxygen comment: ") + line[pos] + "."); - } - - return pos; -} - -/* - * This is the main method, which tokenizes Doxygen comment to words and - * doxygen commands. - */ -void DoxygenParser::tokenizeDoxygenComment(const std::string &doxygenComment, const std::string &fileName, int fileLine) { - m_isVerbatimText = false; - m_isInQuotedString = false; - m_tokenList.clear(); - m_fileLineNo = fileLine; - m_fileName = fileName; - - StringVector lines = split(doxygenComment, '\n'); - - // remove trailing spaces, because they cause additional new line at the end - // comment, which is wrong, because these spaces are space preceding - // end of comment : ' */' - if (!doxygenComment.empty() && doxygenComment[doxygenComment.size() - 1] == ' ') { - - string lastLine = lines[lines.size() - 1]; - - if (trim(lastLine).empty()) { - lines.pop_back(); // remove trailing empty line - } - } - - for (StringVectorCIt it = lines.begin(); it != lines.end(); it++) { - const string &line = *it; - size_t pos = line.find_first_not_of(" \t"); - - if (pos == string::npos) { - m_tokenList.push_back(Token(END_LINE, "\n")); - continue; - } - // skip sequences of '*', '/', and '!' of any length - bool isStartOfCommentLineCharFound = false; - while (pos < line.size() && isStartOfDoxyCommentChar(line[pos])) { - pos++; - isStartOfCommentLineCharFound = true; - } - - if (pos == line.size()) { - m_tokenList.push_back(Token(END_LINE, "\n")); - continue; - } - // if 'isStartOfCommentLineCharFound' then preserve leading spaces, so - // ' * comment' gets translated to ' * comment', not ' * comment' - // This is important to keep formatting for comments translated to Python. - if (isStartOfCommentLineCharFound && line[pos] == ' ') { - pos++; // points to char after ' * ' - if (pos == line.size()) { - m_tokenList.push_back(Token(END_LINE, "\n")); - continue; - } - } - // line[pos] may be ' \t' or start of word, it there was no '*', '/' or '!' - // at beginning of the line. Make sure it points to start of the first word - // in the line. - if (isStartOfCommentLineCharFound) { - size_t firstWordPos = line.find_first_not_of(" \t", pos); - if (firstWordPos == string::npos) { - m_tokenList.push_back(Token(END_LINE, "\n")); - continue; - } - - if (firstWordPos > pos) { - m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, firstWordPos - pos))); - pos = firstWordPos; - } - } else { - m_tokenList.push_back(Token(PLAINSTRING, line.substr(0, pos))); - } - - while (pos != string::npos) { - // find the end of the word - size_t doxyCmdOrHtmlTagPos = line.find_first_of("\\@<>&\" \t", pos); - if (doxyCmdOrHtmlTagPos != pos) { - // plain text found - // if the last char is punctuation, make it a separate word, otherwise - // it may be included with word also when not appropriate, for example: - // colors are \b red, green, and blue --> colors are <b>red,</b> green, and blue - // instead of (comma not bold): - // colors are \b red, green, and blue --> colors are <b>red</b>, green, and blue - // In Python it looks even worse: - // colors are \b red, green, and blue --> colors are 'red,' green, and blue - string text = line.substr(pos, doxyCmdOrHtmlTagPos - pos); - string punctuations(".,:"); - size_t textSize = text.size(); - - if (!text.empty() - && punctuations.find(text[text.size() - 1]) != string::npos && - // but do not break ellipsis (...) - !(textSize > 1 && text[textSize - 2] == '.')) { - m_tokenList.push_back(Token(PLAINSTRING, text.substr(0, text.size() - 1))); - m_tokenList.push_back(Token(PLAINSTRING, text.substr(text.size() - 1))); - } else { - m_tokenList.push_back(Token(PLAINSTRING, text)); - } - } - - pos = doxyCmdOrHtmlTagPos; - if (pos != string::npos) { - if (m_isVerbatimText) { - pos = processVerbatimText(pos, line); - - } else if (m_isInQuotedString) { - - if (line[pos] == '"') { - m_isInQuotedString = false; - } - m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, 1))); - pos++; - - } else { - pos = processNormalComment(pos, line); - } - } - } - m_tokenList.push_back(Token(END_LINE, "\n")); // add when pos == npos - end of line - } - - m_tokenListIt = m_tokenList.begin(); -} - -void DoxygenParser::printList() { - - int tokNo = 0; - for (TokenListCIt it = m_tokenList.begin(); it != m_tokenList.end(); it++, tokNo++) { - - cout << it->toString() << " "; - - if ((tokNo % TOKENSPERLINE) == 0) { - cout << endl; - } - } -} - -void DoxygenParser::printListError(int warningType, const std::string &message) { - int curLine = m_fileLineNo; - for (TokenListCIt it = m_tokenList.begin(); it != m_tokenListIt; it++) { - if (it->m_tokenType == END_LINE) { - curLine++; - } - } - - Swig_warning(warningType, m_fileName.c_str(), curLine, "%s\n", message.c_str()); -} diff --git a/contrib/tools/swig/Source/Doxygen/doxyparser.h b/contrib/tools/swig/Source/Doxygen/doxyparser.h deleted file mode 100644 index a60446517bf..00000000000 --- a/contrib/tools/swig/Source/Doxygen/doxyparser.h +++ /dev/null @@ -1,377 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * doxyparser.h - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_DOXYPARSER_H -#define SWIG_DOXYPARSER_H -#include <string> -#include <list> -#include <map> -#include <vector> -#include <set> - -#include "swig.h" - -#include "doxyentity.h" - -// Utility function to return the base part of a command that may -// include options, e.g. param[in] -> param -std::string getBaseCommand(const std::string &cmd); - - -class DoxygenParser { -private: - - enum DoxyCommandEnum { - NONE = -1, - SIMPLECOMMAND, - COMMANDWORD, - COMMANDLINE, - COMMANDPARAGRAPH, - COMMANDENDCOMMAND, - COMMANDWORDPARAGRAPH, - COMMANDWORDLINE, - COMMANDWORDOWORDWORD, - COMMANDOWORD, - COMMANDERRORTHROW, - COMMANDUNIQUE, - COMMAND_HTML, - COMMAND_HTML_ENTITY, - COMMAND_ALIAS, - COMMAND_IGNORE, - END_LINE, - PARAGRAPH_END, - PLAINSTRING, - COMMAND - }; - - - /** This class contains parts of Doxygen comment as a token. */ - class Token { - public: - DoxyCommandEnum m_tokenType; - std::string m_tokenString; /* the data , such as param for @param */ - - Token(DoxyCommandEnum tType, std::string tString) : m_tokenType(tType), m_tokenString(tString) { - } - - std::string toString() const { - switch (m_tokenType) { - case END_LINE: - return "{END OF LINE}"; - case PARAGRAPH_END: - return "{END OF PARAGRAPH}"; - case PLAINSTRING: - return "{PLAINSTRING :" + m_tokenString + "}"; - case COMMAND: - return "{COMMAND : " + m_tokenString + "}"; - default: - return ""; - } - } - }; - - - typedef std::vector<Token> TokenList; - typedef TokenList::const_iterator TokenListCIt; - typedef TokenList::iterator TokenListIt; - - TokenList m_tokenList; - TokenListCIt m_tokenListIt; - - typedef std::map<std::string, DoxyCommandEnum> DoxyCommandsMap; - typedef DoxyCommandsMap::iterator DoxyCommandsMapIt; - - /* - * Map of Doxygen commands to determine if a string is a - * command and how it needs to be parsed - */ - static DoxyCommandsMap doxygenCommands; - static std::set<std::string> doxygenSectionIndicators; - - bool m_isVerbatimText; // used to handle \htmlonly and \verbatim commands - bool m_isInQuotedString; - - Node *m_node; - std::string m_fileName; - int m_fileLineNo; - - /* - * Return the end command for a command appearing in "ignore" feature or empty - * string if this is a simple command and not a block one. - */ - std::string getIgnoreFeatureEndCommand(const std::string &theCommand) const; - - /* - * Helper for getting the value of doxygen:ignore feature or its argument. - */ - String *getIgnoreFeature(const std::string &theCommand, const char *argument = NULL) const; - - /* - * Whether to print lots of debug info during parsing - */ - bool noisy; - - /* - *Changes a std::string to all lower case - */ - std::string stringToLower(const std::string &stringToConvert); - - /* - * isSectionIndicator returns a boolean if the command is a section indicator - * This is a helper method for finding the end of a paragraph - * by Doxygen's terms - */ - bool isSectionIndicator(const std::string &smallString); - /* - * Determines how a command should be handled (what group it belongs to - * for parsing rules - */ - DoxyCommandEnum commandBelongs(const std::string &theCommand); - - /* - *prints the parse tree - */ - void printTree(const std::list<DoxygenEntity> &rootList); - - /** - * Returns true if the next token is end of line token. This is important - * when single word commands like \c are at the end of line. - */ - bool isEndOfLine(); - - /** - * Skips spaces, tabs, and end of line tokens. - */ - void skipWhitespaceTokens(); - - /** - * Removes all spaces and tabs from beginning end end of string. - */ - std::string trim(const std::string &text); - - /* - * Returns string of the next token if the next token is PLAINSTRING. Returns - * empty string otherwise. - */ - std::string getNextToken(); - - /* - * Returns the next word ON THE CURRENT LINE ONLY - * if a new line is encountered, returns a blank std::string. - * Updates the iterator if successful. - */ - std::string getNextWord(); - - /* - * Returns the next word, which is not necessarily on the same line. - * Updates the iterator if successful. - */ - std::string getNextWordInComment(); - - /* - * Returns the location of the end of the line as - * an iterator. - */ - TokenListCIt getOneLine(const TokenList &tokList); - - /* - * Returns a properly formatted std::string - * up til ANY command or end of line is encountered. - */ - std::string getStringTilCommand(const TokenList &tokList); - - /* - * Returns a properly formatted std::string - * up til the command specified is encountered - */ - //TODO check that this behaves properly for formulas - std::string getStringTilEndCommand(const std::string &theCommand, const TokenList &tokList); - - /* - * Returns the end of a Paragraph as an iterator- - * Paragraph is defined in Doxygen to be a paragraph of text - * separated by either a structural command or a blank line - */ - TokenListCIt getEndOfParagraph(const TokenList &tokList); - - /* - * Returns the end of a section, defined as the first blank line OR first - * encounter of the same command. Example of this behaviour is \arg. - * If no end is encountered, returns the last token of the std::list. - */ - TokenListCIt getEndOfSection(const std::string &theCommand, const TokenList &tokList); - - /* - * This method is for returning the end of a specific form of doxygen command - * that begins with a \command and ends in \endcommand - * such as \code and \endcode. The proper usage is - * progressTilEndCommand("endcode", tokenList); - * If the end is never encountered, it returns the end of the std::list. - */ - TokenListCIt getEndCommand(const std::string &theCommand, const TokenList &tokList); - /* - * A special method for commands such as \arg that end at the end of a - * paragraph OR when another \arg is encountered - //TODO getTilAnyCommand - TokenListCIt getTilAnyCommand(const std::string &theCommand, const TokenList &tokList); - */ - - /** - * This methods skips end of line token, if it is the next token to be - * processed. It is called with comment commands which have args till the - * end of line, such as 'addtogroup' or 'addindex'. - * It is up to translator to specific language to decide whether - * to insert eol or not. For example, if a command is ignored in target - * language, new lines may make formatting ugly (Python). - */ - void skipEndOfLine(); - - /* - * Method for Adding a Simple Command - * Format: @command - * Plain commands, such as newline etc, they contain no other data - * \n \\ \@ \& \$ \# \< \> \% \{ \} - */ - void addSimpleCommand(const std::string &theCommand, DoxygenEntityList &doxyList); - /* - * CommandWord - * Format: @command <word> - * Commands with a single WORD after then such as @b - * "a", "b", "c", "e", "em", "p", "def", "enum", "example", "package", - * "relates", "namespace", "relatesalso","anchor", "dontinclude", "include", - * "includelineno" - */ - void addCommandWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - /* - * CommandLine - * Format: @command (line) - * Commands with a single LINE after then such as @var - * "addindex", "fn", "name", "line", "var", "skipline", "typedef", "skip", - * "until", "property" - */ - void addCommandLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - /* - * CommandParagraph - * Format: @command {paragraph} - * Commands with a single paragraph after then such as @return - * "return", "remarks", "since", "test", "sa", "see", "pre", "post", - * "details", "invariant", "deprecated", "date", "note", "warning", - * "version", "todo", "bug", "attention", "brief", "arg", "author" - */ - void addCommandParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - /* - * Command EndCommand - * Format: @command and ends at @endcommand - * Commands that take in a block of text such as @code: - * "code", "dot", "msc", "f$", "f[", "f{environment}{", "htmlonly", - * "latexonly", "manonly", "verbatim", "xmlonly", "cond", "if", "ifnot", - * "link" - * Returns 1 if success, 0 if the endcommand is never encountered. - */ - void addCommandEndCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - /* - * CommandWordParagraph - * Format: @command <word> {paragraph} - * Commands such as param - * "param", "tparam", "throw", "throws", "retval", "exception" - */ - void addCommandWordParagraph(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - /* - * CommandWordLine - * Format: @command <word> (line) - * Commands such as param - * "page", "subsection", "subsubsection", "section", "paragraph", "defgroup" - */ - void addCommandWordLine(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - /* - * Command Word Optional Word Optional Word - * Format: @command <word> [<header-file>] [<header-name>] - * Commands such as class - * "category", "class", "protocol", "interface", "struct", "union" - */ - void addCommandWordOWordOWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - /* - * Command Optional Word - * Format: @command [<word>] - * Commands such as dir - * "dir", "file", "cond" - */ - void addCommandOWord(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - - /* - * Commands that should not be encountered (such as PHP only) - * goes til the end of line then returns - */ - void addCommandErrorThrow(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - - void addCommandHtml(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - - void addCommandHtmlEntity(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - - /* - *Adds the unique commands- different process for each unique command - */ - void addCommandUnique(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - - /* - * Replace the given command with its predefined alias expansion. - */ - void aliasCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - - /* - * Simply ignore the given command, possibly with the word following it or - * until the matching end command. - */ - void ignoreCommand(const std::string &theCommand, const TokenList &tokList, DoxygenEntityList &doxyList); - - /* - * The actual "meat" of the doxygen parser. Calls the correct addCommand...() - * function. - */ - void addCommand(const std::string &commandString, const TokenList &tokList, DoxygenEntityList &doxyList); - - DoxygenEntityList parse(TokenListCIt endParsingIndex, const TokenList &tokList, bool root = false); - - /* - * Fill static doxygenCommands and sectionIndicators containers - */ - void fillTables(); - - /** Processes comment when \htmlonly and \verbatim commands are encountered. */ - size_t processVerbatimText(size_t pos, const std::string &line); - - bool processEscapedChars(size_t &pos, const std::string &line); - void processWordCommands(size_t &pos, const std::string &line); - void processHtmlTags(size_t &pos, const std::string &line); - void processHtmlEntities(size_t &pos, const std::string &line); - - - /** Processes comment outside \htmlonly and \verbatim commands. */ - size_t processNormalComment(size_t pos, const std::string &line); - - void tokenizeDoxygenComment(const std::string &doxygenComment, const std::string &fileName, int fileLine); - void printList(); - void printListError(int warningType, const std::string &message); - - typedef std::vector<std::string> StringVector; - typedef StringVector::const_iterator StringVectorCIt; - - StringVector split(const std::string &text, char separator); - bool isStartOfDoxyCommentChar(char c); - bool addDoxyCommand(DoxygenParser::TokenList &tokList, const std::string &cmd); - -public: - DoxygenParser(bool noisy = false); - virtual ~DoxygenParser(); - DoxygenEntityList createTree(Node *node, String *documentation); -}; - -#endif diff --git a/contrib/tools/swig/Source/Doxygen/doxytranslator.cxx b/contrib/tools/swig/Source/Doxygen/doxytranslator.cxx deleted file mode 100644 index a638717eca1..00000000000 --- a/contrib/tools/swig/Source/Doxygen/doxytranslator.cxx +++ /dev/null @@ -1,69 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * doxytranslator.cxx - * - * Module to return documentation for nodes formatted for various documentation - * systems. - * ----------------------------------------------------------------------------- */ - -#include "doxytranslator.h" - -DoxygenTranslator::DoxygenTranslator(int flags) : m_flags(flags), parser((flags &debug_parser) != 0) { -} - - -DoxygenTranslator::~DoxygenTranslator() { -} - - -bool DoxygenTranslator::hasDocumentation(Node *node) { - return getDoxygenComment(node) != NULL; -} - - -String *DoxygenTranslator::getDoxygenComment(Node *node) { - return Getattr(node, "doxygen"); -} - -/** - * Indent all lines in the comment by given indentation string - */ -void DoxygenTranslator::extraIndentation(String *comment, const_String_or_char_ptr indentationString) { - if (indentationString || Len(indentationString) > 0) { - int len = Len(comment); - bool trailing_newline = len > 0 && *(Char(comment) + len - 1) == '\n'; - Insert(comment, 0, indentationString); - String *replace = NewStringf("\n%s", indentationString); - Replaceall(comment, "\n", replace); - if (trailing_newline) { - len = Len(comment); - Delslice(comment, len - 2, len); // Remove added trailing spaces on last line - } - Delete(replace); - } -} - -String *DoxygenTranslator::getDocumentation(Node *node, const_String_or_char_ptr indentationString) { - - if (!hasDocumentation(node)) { - return NewString(""); - } - - String *documentation = makeDocumentation(node); - extraIndentation(documentation, indentationString); - return documentation; -} - - -void DoxygenTranslator::printTree(const DoxygenEntityList &entityList) { - - for (DoxygenEntityListCIt p = entityList.begin(); p != entityList.end(); p++) { - p->printEntity(0); - } -} diff --git a/contrib/tools/swig/Source/Doxygen/doxytranslator.h b/contrib/tools/swig/Source/Doxygen/doxytranslator.h deleted file mode 100644 index f0d3b1b0607..00000000000 --- a/contrib/tools/swig/Source/Doxygen/doxytranslator.h +++ /dev/null @@ -1,90 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * doxytranslator.h - * - * Module to return documentation for nodes formatted for various documentation - * systems. - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_DOXYTRANSLATOR_H -#define SWIG_DOXYTRANSLATOR_H - -#include "swig.h" -#include "doxyentity.h" -#include "doxyparser.h" -#include <list> -#include <string> - - -/* - * This is a base class for translator classes. It defines the basic interface - * for translators, which convert Doxygen comments into alternative formats for - * target languages. - */ -class DoxygenTranslator { -public: - /* - * Bit flags for the translator ctor. - * - * Derived classes may define additional flags. - */ - enum { - // Use DoxygenParser in "noisy" mode. - debug_parser = 1, - - // Output results of translating Doxygen comments. - debug_translator = 2 - }; - - /* - * Constructor - */ - DoxygenTranslator(int flags = 0); - - /* - * Virtual destructor. - */ - virtual ~DoxygenTranslator(); - - /* - * Return the documentation for a given node formatted for the correct - * documentation system. - */ - String *getDocumentation(Node *node, const_String_or_char_ptr indentationString); - - /* - * Returns true if the specified node has comment attached. - */ - bool hasDocumentation(Node *node); - - /* - * Get original comment string in Doxygen-format. - */ - String *getDoxygenComment(Node *node); - -protected: - // The flags passed to the ctor. - const int m_flags; - - DoxygenParser parser; - - /* - * Returns the documentation formatted for a target language. - */ - virtual String *makeDocumentation(Node *node) = 0; - - /* - * Prints the details of a parsed entity list to stdout (for debugging). - */ - void printTree(const DoxygenEntityList &entityList); - - void extraIndentation(String *comment, const_String_or_char_ptr indentationString); -}; - -#endif diff --git a/contrib/tools/swig/Source/Doxygen/javadoc.cxx b/contrib/tools/swig/Source/Doxygen/javadoc.cxx deleted file mode 100644 index a1406b23037..00000000000 --- a/contrib/tools/swig/Source/Doxygen/javadoc.cxx +++ /dev/null @@ -1,849 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * javadoc.cxx - * ----------------------------------------------------------------------------- */ - -#include "javadoc.h" -#include "doxyparser.h" -#include <iostream> -#include <vector> -#include <list> -#include "swigmod.h" -#define APPROX_LINE_LENGTH 64 // characters per line allowed -#define TAB_SIZE 8 // current tab size in spaces -//TODO {@link} {@linkplain} {@docRoot}, and other useful doxy commands that are not a javadoc tag - -// define static tables, they are filled in JavaDocConverter's constructor -std::map<std::string, std::pair<JavaDocConverter::tagHandler, std::string> > JavaDocConverter::tagHandlers; - -using std::string; -using std::list; -using std::vector; - -void JavaDocConverter::fillStaticTables() { - if (tagHandlers.size()) // fill only once - return; - - /* - * Some translation rules: - * - * @ and \ must be escaped for both Java and Python to appear on output: \@, \\, - * while Doxygen produces output in both cases. - * Rule: @ and \ with space on the right should get to output. - * - * :: remains intact, even in class::method(). But you can use class#method also - * in C++ comment and it is properly translated to C++ output (changed by doxygen to ::) - * and Java output (remains #). - * Rule: SWIG type system can't be used to convert C::m to C#m, because in Java it is C.m - * Use string replacement :: --> # in tag see and links. - * - * HTML tags must be translated - remain in Java, to markdown in Python - * - * Unknown HTML tags, for example <x> is translated to <x> by doxygen, while - * Java src is <x> and therefore invisible on output - browser ignores unknown command. - * This is handy in syntax descriptions, for example: more <fileName>. - * - * Standalone < and > need not be translated, they are rendered properly in - * all three outputs. - * - * ., %, and " need not to be translated - * - * entities must be translated - remain in Java, something meaningful in Python (<, ...) - * - * - Python - * - add comments also to auto-generated methods like equals(), delete() in Java, - * and methods for std::vector(), ... - * Commenting methods of std types is simple - add comment to std_*.i file. - */ - - // these commands insert HTML tags - tagHandlers["a"] = make_pair(&JavaDocConverter::handleTagHtml, "i"); - tagHandlers["arg"] = make_pair(&JavaDocConverter::handleTagHtml, "li"); - tagHandlers["b"] = make_pair(&JavaDocConverter::handleTagHtml, "b"); - tagHandlers["c"] = make_pair(&JavaDocConverter::handleTagHtml, "code"); - tagHandlers["cite"] = make_pair(&JavaDocConverter::handleTagHtml, "i"); - tagHandlers["e"] = make_pair(&JavaDocConverter::handleTagHtml, "i"); - tagHandlers["em"] = make_pair(&JavaDocConverter::handleTagHtml, "i"); - tagHandlers["li"] = make_pair(&JavaDocConverter::handleTagHtml, "li"); - tagHandlers["p"] = make_pair(&JavaDocConverter::handleTagHtml, "code"); - // these commands insert just a single char, some of them need to be escaped - tagHandlers["$"] = make_pair(&JavaDocConverter::handleTagChar, ""); - tagHandlers["@"] = make_pair(&JavaDocConverter::handleTagChar, ""); - tagHandlers["\\"] = make_pair(&JavaDocConverter::handleTagChar, ""); - tagHandlers["<"] = make_pair(&JavaDocConverter::handleTagChar, "<"); - tagHandlers[">"] = make_pair(&JavaDocConverter::handleTagChar, ">"); - tagHandlers["&"] = make_pair(&JavaDocConverter::handleTagChar, "&"); - tagHandlers["#"] = make_pair(&JavaDocConverter::handleTagChar, ""); - tagHandlers["%"] = make_pair(&JavaDocConverter::handleTagChar, ""); - tagHandlers["~"] = make_pair(&JavaDocConverter::handleTagChar, ""); - tagHandlers["\""] = make_pair(&JavaDocConverter::handleTagChar, """); - tagHandlers["."] = make_pair(&JavaDocConverter::handleTagChar, ""); - tagHandlers["::"] = make_pair(&JavaDocConverter::handleTagChar, ""); - // these commands are stripped out - tagHandlers["attention"] = make_pair(&JavaDocConverter::handleParagraph, ""); - tagHandlers["anchor"] = make_pair(&JavaDocConverter::handleTagAnchor, ""); - tagHandlers["brief"] = make_pair(&JavaDocConverter::handleParagraph, ""); - tagHandlers["bug"] = make_pair(&JavaDocConverter::handleParagraph, ""); - tagHandlers["date"] = make_pair(&JavaDocConverter::handleParagraph, ""); - tagHandlers["details"] = make_pair(&JavaDocConverter::handleParagraph, ""); - // this command is inserts text accumulated after cmd htmlonly - - // see DoxygenParser - CMD_HTML_ONLY. - tagHandlers["htmlonly"] = make_pair(&JavaDocConverter::handleParagraph, ""); - tagHandlers["invariant"] = make_pair(&JavaDocConverter::handleParagraph, ""); - tagHandlers["latexonly"] = make_pair(&JavaDocConverter::handleParagraph, ""); - tagHandlers["manonly"] = make_pair(&JavaDocConverter::handleParagraph, ""); - tagHandlers["partofdescription"] = make_pair(&JavaDocConverter::handleParagraph, ""); - tagHandlers["rtfonly"] = make_pair(&JavaDocConverter::handleParagraph, ""); - tagHandlers["short"] = make_pair(&JavaDocConverter::handleParagraph, ""); - tagHandlers["xmlonly"] = make_pair(&JavaDocConverter::handleParagraph, ""); - // these commands are kept as-is, they are supported by JavaDoc - tagHandlers["author"] = make_pair(&JavaDocConverter::handleTagSame, ""); - tagHandlers["authors"] = make_pair(&JavaDocConverter::handleTagSame, "author"); - tagHandlers["deprecated"] = make_pair(&JavaDocConverter::handleTagSame, ""); - tagHandlers["exception"] = make_pair(&JavaDocConverter::handleTagSame, ""); - tagHandlers["package"] = make_pair(&JavaDocConverter::handleTagSame, ""); - tagHandlers["param"] = make_pair(&JavaDocConverter::handleTagParam, ""); - tagHandlers["tparam"] = make_pair(&JavaDocConverter::handleTagParam, ""); - tagHandlers["ref"] = make_pair(&JavaDocConverter::handleTagRef, ""); - tagHandlers["result"] = make_pair(&JavaDocConverter::handleTagSame, "return"); - tagHandlers["return"] = make_pair(&JavaDocConverter::handleTagSame, ""); - tagHandlers["returns"] = make_pair(&JavaDocConverter::handleTagSame, "return"); - //tagHandlers["see"] = make_pair(&JavaDocConverter::handleTagSame, ""); - //tagHandlers["sa"] = make_pair(&JavaDocConverter::handleTagSame, "see"); - tagHandlers["since"] = make_pair(&JavaDocConverter::handleTagSame, ""); - tagHandlers["throws"] = make_pair(&JavaDocConverter::handleTagSame, ""); - tagHandlers["throw"] = make_pair(&JavaDocConverter::handleTagSame, "throws"); - tagHandlers["version"] = make_pair(&JavaDocConverter::handleTagSame, ""); - // these commands have special handlers - tagHandlers["code"] = make_pair(&JavaDocConverter::handleTagExtended, "code"); - tagHandlers["cond"] = make_pair(&JavaDocConverter::handleTagMessage, "Conditional comment: "); - tagHandlers["copyright"] = make_pair(&JavaDocConverter::handleTagMessage, "Copyright: "); - tagHandlers["else"] = make_pair(&JavaDocConverter::handleTagIf, "Else: "); - tagHandlers["elseif"] = make_pair(&JavaDocConverter::handleTagIf, "Else if: "); - tagHandlers["endcond"] = make_pair(&JavaDocConverter::handleTagMessage, "End of conditional comment."); - // space in second arg prevents Javadoc to treat '@ example' as command. File name of - // example is still informative to user. - tagHandlers["example"] = make_pair(&JavaDocConverter::handleTagSame, " example"); - tagHandlers["if"] = make_pair(&JavaDocConverter::handleTagIf, "If: "); - tagHandlers["ifnot"] = make_pair(&JavaDocConverter::handleTagIf, "If not: "); - tagHandlers["image"] = make_pair(&JavaDocConverter::handleTagImage, ""); - tagHandlers["link"] = make_pair(&JavaDocConverter::handleTagLink, ""); - tagHandlers["see"] = make_pair(&JavaDocConverter::handleTagSee, ""); - tagHandlers["sa"] = make_pair(&JavaDocConverter::handleTagSee, ""); - tagHandlers["note"] = make_pair(&JavaDocConverter::handleTagMessage, "Note: "); - tagHandlers["overload"] = make_pair(&JavaDocConverter::handleTagMessage, - "This is an overloaded member function, provided for" - " convenience. It differs from the above function only in what" " argument(s) it accepts."); - tagHandlers["par"] = make_pair(&JavaDocConverter::handleTagPar, ""); - tagHandlers["remark"] = make_pair(&JavaDocConverter::handleTagMessage, "Remarks: "); - tagHandlers["remarks"] = make_pair(&JavaDocConverter::handleTagMessage, "Remarks: "); - tagHandlers["todo"] = make_pair(&JavaDocConverter::handleTagMessage, "TODO: "); - tagHandlers["verbatim"] = make_pair(&JavaDocConverter::handleTagExtended, "literal"); - - // \f commands output literal Latex formula, which is still better than nothing. - tagHandlers["f$"] = make_pair(&JavaDocConverter::handleTagVerbatim, ""); - tagHandlers["f["] = make_pair(&JavaDocConverter::handleTagVerbatim, ""); - tagHandlers["f{"] = make_pair(&JavaDocConverter::handleTagVerbatim, ""); - - tagHandlers["warning"] = make_pair(&JavaDocConverter::handleTagMessage, "Warning: "); - // this command just prints its contents - // (it is internal command of swig's parser, contains plain text) - tagHandlers["plainstd::string"] = make_pair(&JavaDocConverter::handlePlainString, ""); - tagHandlers["plainstd::endl"] = make_pair(&JavaDocConverter::handleNewLine, ""); - tagHandlers["n"] = make_pair(&JavaDocConverter::handleNewLine, ""); - - // HTML tags - tagHandlers["<a"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<a"); - tagHandlers["<b"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<b"); - tagHandlers["<blockquote"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<blockquote"); - tagHandlers["<body"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<body"); - tagHandlers["<br"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<br"); - tagHandlers["<center"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<center"); - tagHandlers["<caption"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<caption"); - tagHandlers["<code"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<code"); - tagHandlers["<dd"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dd"); - tagHandlers["<dfn"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dfn"); - tagHandlers["<div"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<div"); - tagHandlers["<dl"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dl"); - tagHandlers["<dt"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<dt"); - tagHandlers["<em"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<em"); - tagHandlers["<form"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<form"); - tagHandlers["<hr"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<hr"); - tagHandlers["<h1"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h1"); - tagHandlers["<h2"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h2"); - tagHandlers["<h3"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<h3"); - tagHandlers["<i"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<i"); - tagHandlers["<input"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<input"); - tagHandlers["<img"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<img"); - tagHandlers["<li"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<li"); - tagHandlers["<meta"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<meta"); - tagHandlers["<multicol"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<multicol"); - tagHandlers["<ol"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<ol"); - tagHandlers["<p"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<p"); - tagHandlers["<pre"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<pre"); - tagHandlers["<small"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<small"); - tagHandlers["<span"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<span"); - tagHandlers["<strong"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<strong"); - tagHandlers["<sub"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<sub"); - tagHandlers["<sup"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<sup"); - tagHandlers["<table"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<table"); - tagHandlers["<td"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<td"); - tagHandlers["<th"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<th"); - tagHandlers["<tr"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<tr"); - tagHandlers["<tt"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<tt"); - tagHandlers["<kbd"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<kbd"); - tagHandlers["<ul"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<ul"); - tagHandlers["<var"] = make_pair(&JavaDocConverter::handleDoxyHtmlTag, "<var"); - - // HTML entities - tagHandlers["©"] = make_pair(&JavaDocConverter::handleHtmlEntity, "©"); - tagHandlers["&trade"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&trade"); - tagHandlers["®"] = make_pair(&JavaDocConverter::handleHtmlEntity, "®"); - tagHandlers["<"] = make_pair(&JavaDocConverter::handleHtmlEntity, "<"); - tagHandlers[">"] = make_pair(&JavaDocConverter::handleHtmlEntity, ">"); - tagHandlers["&"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&"); - tagHandlers["&apos"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&apos"); - tagHandlers["""] = make_pair(&JavaDocConverter::handleHtmlEntity, """); - tagHandlers["&lsquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&lsquo"); - tagHandlers["&rsquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rsquo"); - tagHandlers["&ldquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ldquo"); - tagHandlers["&rdquo"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rdquo"); - tagHandlers["&ndash"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ndash"); - tagHandlers["&mdash"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&mdash"); - tagHandlers[" "] = make_pair(&JavaDocConverter::handleHtmlEntity, " "); - tagHandlers["×"] = make_pair(&JavaDocConverter::handleHtmlEntity, "×"); - tagHandlers["&minus"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&minus"); - tagHandlers["&sdot"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&sdot"); - tagHandlers["&sim"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&sim"); - tagHandlers["&le"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&le"); - tagHandlers["&ge"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&ge"); - tagHandlers["&larr"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&larr"); - tagHandlers["&rarr"] = make_pair(&JavaDocConverter::handleHtmlEntity, "&rarr"); -} - -JavaDocConverter::JavaDocConverter(int flags) : - DoxygenTranslator(flags) { - fillStaticTables(); -} - -/** - * Formats comment lines by inserting '\n *' at to long lines and tabs for - * indent. Currently it is disabled, which means original comment format is - * preserved. Experience shows, that this is usually better than breaking - * lines automatically, especially because original line endings are not removed, - * which results in short lines. To be useful, this function should have much - * better algorithm. - */ -std::string JavaDocConverter::formatCommand(std::string unformattedLine, int indent) { - std::string formattedLines; - return unformattedLine; // currently disabled - std::string::size_type lastPosition = 0; - std::string::size_type i = 0; - int isFirstLine = 1; - while (i != std::string::npos && i < unformattedLine.length()) { - lastPosition = i; - if (isFirstLine) { - i += APPROX_LINE_LENGTH; - } else { - i += APPROX_LINE_LENGTH - indent * TAB_SIZE; - } - - i = unformattedLine.find(" ", i); - - if (i > 0 && i + 1 < unformattedLine.length()) { - if (!isFirstLine) - for (int j = 0; j < indent; j++) { - formattedLines.append("\t"); - } else { - isFirstLine = 0; - } - formattedLines.append(unformattedLine.substr(lastPosition, i - lastPosition + 1)); - formattedLines.append("\n *"); - - } - } - if (lastPosition < unformattedLine.length()) { - if (!isFirstLine) { - for (int j = 0; j < indent; j++) { - formattedLines.append("\t"); - } - } - formattedLines.append(unformattedLine.substr(lastPosition, unformattedLine.length() - lastPosition)); - } - - return formattedLines; -} - -/** - * Returns true, if the given parameter exists in the current node - * (for example param is a name of function parameter). If feature - * 'doxygen:nostripparams' is set, then this method always returns - * true - parameters are copied to output regardless of presence in - * function params list. - */ -bool JavaDocConverter::paramExists(std::string param) { - - if (GetFlag(currentNode, "feature:doxygen:nostripparams")) { - return true; - } - - ParmList *plist = CopyParmList(Getattr(currentNode, "parms")); - - for (Parm *p = plist; p;) { - - if (Getattr(p, "name") && Char(Getattr(p, "name")) == param) { - return true; - } - /* doesn't seem to work always: in some cases (especially for 'self' parameters) - * tmap:in is present, but tmap:in:next is not and so this code skips all the parameters - */ - //p = Getattr(p, "tmap:in") ? Getattr(p, "tmap:in:next") : nextSibling(p); - p = nextSibling(p); - } - - Delete(plist); - - return false; -} - -std::string JavaDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) { - std::string translatedComment; - - if (doxygenEntity.isLeaf) { - return translatedComment; - } - - for (DoxygenEntityListIt p = doxygenEntity.entityList.begin(); p != doxygenEntity.entityList.end(); p++) { - - translateEntity(*p, translatedComment); - translateSubtree(*p); - } - - return translatedComment; -} - -/** - * Checks if a handler for the given tag exists, and calls it. - */ -void JavaDocConverter::translateEntity(DoxygenEntity &tag, std::string &translatedComment) { - - std::map<std::string, std::pair<tagHandler, std::string> >::iterator it; - it = tagHandlers.find(getBaseCommand(tag.typeOfEntity)); - - if (it != tagHandlers.end()) { - (this->*(it->second.first))(tag, translatedComment, it->second.second); - } else { - // do NOT print warning, since there are many tags, which are not - // translatable - many warnings hide important ones - // addError(WARN_DOXYGEN_COMMAND_ERROR, "Unknown doxygen or HTML tag: " + tag.typeOfEntity); - } -} - - -void JavaDocConverter::handleTagAnchor(DoxygenEntity &tag, std::string &translatedComment, std::string &) { - translatedComment += "<a id=\"" + translateSubtree(tag) + "\"></a>"; -} - - -void JavaDocConverter::handleTagHtml(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) { - if (tag.entityList.size()) { // do not include empty tags - std::string tagData = translateSubtree(tag); - // wrap the thing, ignoring whitespace - size_t wsPos = tagData.find_last_not_of("\n\t "); - if (wsPos != std::string::npos) - translatedComment += "<" + arg + ">" + tagData.substr(0, wsPos + 1) + "</" + arg + ">" + tagData.substr(wsPos + 1); - else - translatedComment += "<" + arg + ">" + translateSubtree(tag) + "</" + arg + "> "; - } -} - -void JavaDocConverter::handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) { - std::string htmlTagArgs = tag.data; - if (htmlTagArgs == "/") { - // end html tag, for example "</ul> - translatedComment += "</" + arg.substr(1) + ">"; - } else { - translatedComment += arg + htmlTagArgs + ">"; - } -} - -void JavaDocConverter::handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, std::string &arg) { - // html entities can be preserved for Java - translatedComment += arg + ';'; -} - -void JavaDocConverter::handleNewLine(DoxygenEntity &, std::string &translatedComment, std::string &) { - // <br> tag is added, because otherwise to much text is joined - // into same paragraph by javadoc. For example, doxy list: - // - item one - // - item two - // becomes one paragraph with surrounding text without newlines. - // This way we get to many empty lines in javadoc output, but this - // is still better than joined lines. Possibility for improvements - // exists. - translatedComment += "<br>\n * "; -} - -void JavaDocConverter::handleTagChar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) { - // escape it if we need to, else just print - if (arg.size()) - translatedComment += arg; - else - translatedComment += tag.typeOfEntity; -} - -// handles tags which are the same in Doxygen and Javadoc. -void JavaDocConverter::handleTagSame(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) { - if (arg.size()) - tag.typeOfEntity = arg; - translatedComment += formatCommand(std::string("@" + tag.typeOfEntity + " " + translateSubtree(tag)), 2); -} - -void JavaDocConverter::handleParagraph(DoxygenEntity &tag, std::string &translatedComment, std::string &) { - translatedComment += formatCommand(translateSubtree(tag), 0); -} - -void JavaDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translatedComment, std::string &) { - translatedComment += tag.data; - // if (tag.data.size() && tag.data[tag.data.size()-1] != ' ') - // translatedComment += " "; -} - -void JavaDocConverter::handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) { - translatedComment += arg + " "; - for (DoxygenEntityListCIt it = tag.entityList.begin(); it != tag.entityList.end(); it++) { - translatedComment += it->data; - } -} - -void JavaDocConverter::handleTagExtended(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) { - std::string dummy; - translatedComment += "{@" + arg + " "; - handleParagraph(tag, translatedComment, dummy); - translatedComment += "}"; -} - -void JavaDocConverter::handleTagIf(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) { - std::string dummy; - translatedComment += arg; - if (tag.entityList.size()) { - translatedComment += tag.entityList.begin()->data; - tag.entityList.pop_front(); - translatedComment += " {" + translateSubtree(tag) + "}"; - } -} - -void JavaDocConverter::handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg) { - std::string dummy; - translatedComment += formatCommand(arg, 0); - handleParagraph(tag, translatedComment, dummy); -} - -void JavaDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translatedComment, std::string &) { - if (tag.entityList.size() < 2) - return; - - std::string file; - std::string title; - - std::list<DoxygenEntity>::iterator it = tag.entityList.begin(); - if (it->data != "html") - return; - - it++; - file = it->data; - - it++; - if (it != tag.entityList.end()) - title = it->data; - - translatedComment += "<img src="; - if (file.size() >= 2 && file[0] == '"' && file[file.size() - 1] == '"') - translatedComment += file; - else - translatedComment += "\"" + file + "\""; - if (title.size()) - translatedComment += " alt=" + title; - - // the size indication is supported for Latex only in Doxygen, see manual - - translatedComment += "/>"; -} - -void JavaDocConverter::handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &) { - std::string dummy; - translatedComment += "<p"; - if (tag.entityList.size()) { - translatedComment += " alt=\"" + tag.entityList.begin()->data + "\""; - translatedComment += ">"; - tag.entityList.pop_front(); - handleParagraph(tag, translatedComment, dummy); - } - translatedComment += "</p>"; -} - - -void JavaDocConverter::handleTagParam(DoxygenEntity &tag, std::string &translatedComment, std::string &) { - std::string dummy; - - if (!tag.entityList.size()) - return; - if (!paramExists(tag.entityList.begin()->data)) - return; - - translatedComment += "@param "; - translatedComment += tag.entityList.begin()->data; - tag.entityList.pop_front(); - handleParagraph(tag, translatedComment, dummy); -} - - -void JavaDocConverter::handleTagRef(DoxygenEntity &tag, std::string &translatedComment, std::string &) { - std::string dummy; - if (!tag.entityList.size()) - return; - - // we translate to link, although \page is not supported in Java, but - // reader at least knows what to look at. Also for \anchor tag on the same - // page this link works. - string anchor = tag.entityList.begin()->data; - tag.entityList.pop_front(); - string anchorText = anchor; - if (!tag.entityList.empty()) { - anchorText = tag.entityList.begin()->data; - } - translatedComment += "<a href=\"#" + anchor + "\">" + anchorText + "</a>"; -} - - -string JavaDocConverter::convertLink(string linkObject) { - if (GetFlag(currentNode, "feature:doxygen:nolinktranslate")) - return linkObject; - // find the params in function in linkObject (if any) - size_t lbracePos = linkObject.find('(', 0); - size_t rbracePos = linkObject.find(')', 0); - if (lbracePos == string::npos || rbracePos == string::npos || lbracePos >= rbracePos) - return ""; - - string paramsStr = linkObject.substr(lbracePos + 1, - rbracePos - lbracePos - 1); - // strip the params, to fill them later - string additionalObject = linkObject.substr(rbracePos + 1, string::npos); - linkObject = linkObject.substr(0, lbracePos); - - // find all the params - vector<string> params; - size_t lastPos = 0, commaPos = 0; - while (true) { - commaPos = paramsStr.find(',', lastPos); - if (commaPos == string::npos) - commaPos = paramsStr.size(); - string param = paramsStr.substr(lastPos, commaPos - lastPos); - // if any param type is empty, we are failed - if (!param.size()) - return ""; - params.push_back(param); - lastPos = commaPos + 1; - if (lastPos >= paramsStr.size()) - break; - } - - linkObject += "("; - for (size_t i = 0; i < params.size(); i++) { - // translate c/c++ type string to swig's type - // i e 'int **arr[100][10]' -> 'a(100).a(10).p.p.int' - // also converting arrays to pointers - string paramStr = params[i]; - String *swigType = NewString(""); - - // handle const qualifier - if (paramStr.find("const") != string::npos) - SwigType_add_qualifier(swigType, "const"); - - // handle pointers, references and arrays - for (int j = (int)params[i].size() - 1; j >= 0; j--) { - // skip all the [...] blocks, write 'p.' for every of it - if (paramStr[j] == ']') { - while (j >= 0 && paramStr[j] != '[') - j--; - // no closing brace - if (j < 0) - return ""; - SwigType_add_pointer(swigType); - continue; - } else if (paramStr[j] == '*') - SwigType_add_pointer(swigType); - else if (paramStr[j] == '&') - SwigType_add_reference(swigType); - else if (isalnum(paramStr[j])) { - size_t typeNameStart = paramStr.find_last_of(' ', j + 1); - if (typeNameStart == string::npos) - typeNameStart = 0; - else - typeNameStart++; - Append(swigType, paramStr.substr(typeNameStart, j - typeNameStart + 1).c_str()); - break; - } - } - - // make dummy param list, to lookup typemaps for it - Parm *dummyParam = NewParm(swigType, "", 0); - Swig_typemap_attach_parms("jstype", dummyParam, NULL); - Language::instance()->replaceSpecialVariables(0, Getattr(dummyParam, "tmap:jstype"), dummyParam); - - //Swig_print(dummyParam, 1); - linkObject += Char(Getattr(dummyParam, "tmap:jstype")); - if (i != params.size() - 1) - linkObject += ","; - - Delete(dummyParam); - Delete(swigType); - } - linkObject += ")"; - - return linkObject + additionalObject; -} - -void JavaDocConverter::handleTagLink(DoxygenEntity &tag, std::string &translatedComment, std::string &) { - std::string dummy; - if (!tag.entityList.size()) - return; - - string linkObject = convertLink(tag.entityList.begin()->data); - if (!linkObject.size()) - linkObject = tag.entityList.begin()->data; - tag.entityList.pop_front(); - - translatedComment += "{@link "; - translatedComment += linkObject + " "; - handleParagraph(tag, translatedComment, dummy); - translatedComment += "}"; -} - -void JavaDocConverter::handleTagSee(DoxygenEntity &tag, std::string &translatedComment, std::string &) { - std::string dummy; - if (!tag.entityList.size()) - return; - - // tag.entity list contains contents of the @see paragraph. It should contain - // one link (references) to method with or without parameters. Doxygen supports - // arbitrary text and types mixed, but this feature is not supported here. - // :: or # may be used as a separator between class name and method name. - list<DoxygenEntity>::iterator it; - string methodRef; - for (it = tag.entityList.begin(); it != tag.entityList.end(); it++) { - if (it->typeOfEntity == "plainstd::endl") { - // handleNewLine(*it, translatedComment, dummy); - continue; - } - // restore entities which may be used in C++ type declaration - if (it->typeOfEntity == "&") { - methodRef += '&'; - } else if (it->typeOfEntity == "<") { - methodRef += '<'; - } else if (it->typeOfEntity == ">") { - methodRef += '>'; - } else { - methodRef += it->data; - } - } - - // replace :: with #, but only if it appears before left brace - size_t lbrace = methodRef.find('('); - size_t dblColon = methodRef.find("::"); - if (dblColon < lbrace) { - methodRef = methodRef.substr(0, dblColon) + '#' + methodRef.substr(dblColon + 2); - } - - translatedComment += "@see "; - string linkObject = convertLink(methodRef); - if (!linkObject.size()) { - linkObject = methodRef; - } - translatedComment += linkObject; -} - -/* This function moves all line endings at the end of child entities - * out of the child entities to the parent. - * For example, entity tree: - - -root - |-param - |-paramText - |-endline - - should be turned to - - -root - |-param - |-paramText - |-endline - * - */ -int JavaDocConverter::shiftEndlinesUpTree(DoxygenEntity &root, int level) { - DoxygenEntityListIt it = root.entityList.begin(); - while (it != root.entityList.end()) { - // remove line endings - int ret = shiftEndlinesUpTree(*it, level + 1); - // insert them after this element - it++; - for (int i = 0; i < ret; i++) { - root.entityList.insert(it, DoxygenEntity("plainstd::endl")); - } - } - - // continue only if we are not root - if (!level) { - return 0; - } - - int removedCount = 0; - while (!root.entityList.empty() - && root.entityList.rbegin()->typeOfEntity == "plainstd::endl") { - root.entityList.pop_back(); - removedCount++; - } - return removedCount; -} - -/** - * This makes sure that all comment lines contain '*'. It is not mandatory in doxygen, - * but highly recommended for Javadoc. '*' in empty lines are indented according - * to indentation of the first line. Indentation of non-empty lines is not - * changed - garbage in garbage out. - */ -std::string JavaDocConverter::indentAndInsertAsterisks(const string &doc) { - - size_t idx = doc.find('\n'); - size_t indent = 0; - bool singleLineComment = idx == string::npos; - // Detect indentation. - // The first line in comment is the one after '/**', which may be - // spaces and '\n' or the text. In any case it is not suitable to detect - // indentation, so we have to skip the first '\n'. - // However, if there is just one line, then use that line to detect indentation. - if (idx != string::npos) { - size_t nonspaceIdx = doc.find_first_not_of(" \t", idx + 1); - if (nonspaceIdx != string::npos) { - indent = nonspaceIdx - idx; - } - } - - if (indent == 0) { - // we can't indent the first line less than 0 - indent = 1; - } - // Create the first line of Javadoc comment. - string indentStr(indent - 1, ' '); - string translatedStr = indentStr + "/**"; - if (indent > 1) { - // remove the first space, so that '*' will be aligned - translatedStr = translatedStr.substr(1); - } - - translatedStr += doc; - - // insert '*' before each comment line, if it does not have it - idx = translatedStr.find('\n'); - - while (idx != string::npos) { - - size_t nonspaceIdx = translatedStr.find_first_not_of(" \t", idx + 1); - if (nonspaceIdx != string::npos && translatedStr[nonspaceIdx] != '*') { - // line without '*' found - is it empty? - if (translatedStr[nonspaceIdx] != '\n') { - // add '* ' to each line without it - translatedStr = translatedStr.substr(0, nonspaceIdx) + "* " + translatedStr.substr(nonspaceIdx); - //printf(translatedStr.c_str()); - } else { - // we found empty line, replace it with indented '*' - translatedStr = translatedStr.substr(0, idx + 1) + indentStr + "* " + translatedStr.substr(nonspaceIdx); - } - } - idx = translatedStr.find('\n', nonspaceIdx); - } - - // Add the last comment line properly indented - size_t nonspaceEndIdx = translatedStr.find_last_not_of(" \t"); - if (nonspaceEndIdx != string::npos) { - if (translatedStr[nonspaceEndIdx] != '\n') { - if (!singleLineComment) - translatedStr += '\n'; - } else { - // remove trailing spaces - translatedStr = translatedStr.substr(0, nonspaceEndIdx + 1); - } - } - translatedStr += indentStr + "*/\n"; - - return translatedStr; -} - -String *JavaDocConverter::makeDocumentation(Node *node) { - - String *documentation = getDoxygenComment(node); - - if (documentation == NULL) { - return NewString(""); - } - - if (GetFlag(node, "feature:doxygen:notranslate")) { - - string doc = Char(documentation); - - string translatedStr = indentAndInsertAsterisks(doc); - - return NewString(translatedStr.c_str()); - } - - DoxygenEntityList entityList = parser.createTree(node, documentation); - - // entityList.sort(CompareDoxygenEntities()); sorting currently not used, - - if (m_flags & debug_translator) { - std::cout << "---RESORTED LIST---" << std::endl; - printTree(entityList); - } - // store the current node - // (currently just to handle params) - currentNode = node; - - std::string javaDocString = "/**\n * "; - - DoxygenEntity root("root", entityList); - - shiftEndlinesUpTree(root); - - // strip line endings at the beginning - while (!root.entityList.empty() - && root.entityList.begin()->typeOfEntity == "plainstd::endl") { - root.entityList.pop_front(); - } - - // and at the end - while (!root.entityList.empty() - && root.entityList.rbegin()->typeOfEntity == "plainstd::endl") { - root.entityList.pop_back(); - } - - javaDocString += translateSubtree(root); - - javaDocString += "\n */\n"; - - if (m_flags & debug_translator) { - std::cout << "\n---RESULT IN JAVADOC---" << std::endl; - std::cout << javaDocString; - } - - return NewString(javaDocString.c_str()); -} - -void JavaDocConverter::addError(int warningType, const std::string &message) { - Swig_warning(warningType, "", 0, "Doxygen parser warning: %s. \n", message.c_str()); -} diff --git a/contrib/tools/swig/Source/Doxygen/javadoc.h b/contrib/tools/swig/Source/Doxygen/javadoc.h deleted file mode 100644 index d2c956c9dbf..00000000000 --- a/contrib/tools/swig/Source/Doxygen/javadoc.h +++ /dev/null @@ -1,169 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * javadoc.h - * - * Module to return documentation for nodes formatted for JavaDoc - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_JAVADOC_H -#define SWIG_JAVADOC_H - -#include "doxytranslator.h" -#include <map> - -/* - * A class to translate doxygen comments into JavaDoc style comments. - */ -class JavaDocConverter : public DoxygenTranslator { -public: - JavaDocConverter(int flags = 0); - String *makeDocumentation(Node *node); - -protected: - /* - * Used to properly format JavaDoc-style command - */ - std::string formatCommand(std::string unformattedLine, int indent); - - /* - * Translate every entity in a tree. - */ - std::string translateSubtree(DoxygenEntity &doxygenEntity); - - /* - * Translate one entity with the appropriate handler, according - * to the tagHandlers - */ - void translateEntity(DoxygenEntity &tag, std::string &translatedComment); - - /* - * Fix all endlines location, etc - */ - int shiftEndlinesUpTree(DoxygenEntity &root, int level = 0); - - /* - * Convert params in link-objects and references - */ - std::string convertLink(std::string linkObject); - - /* - * Typedef for the function that handles one tag - * arg - some string argument to easily pass it through lookup table - */ - typedef void (JavaDocConverter::*tagHandler) (DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /** - * Copies verbatim args of the tag to output, used for commands like \f$, ... - */ - void handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /** Creates anchor link. */ - void handleTagAnchor(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Wrap the command data with the html tag - * arg - html tag, with no braces - */ - void handleTagHtml(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* Handles HTML tags recognized by Doxygen, like <A ...>, <ul>, <table>, ... */ - void handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* Handles HTML entities recognized by Doxygen, like <, ©, ... */ - void handleHtmlEntity(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Just prints new line - */ - void handleNewLine(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Print the name of tag to the output, used for escape-commands - * arg - html-escaped variant, if not provided the command data is used - */ - void handleTagChar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Do not translate and print as-is - * arg - the new tag name, if it needs to be renamed - */ - void handleTagSame(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Print only the content and strip original tag - */ - void handleParagraph(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Print only data part of code - */ - void handlePlainString(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Print extended Javadoc command, like {@code ...} or {@literal ...} - * arg - command name - */ - void handleTagExtended(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Print the if-elseif-else-endif section - */ - void handleTagIf(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Prints the specified message, than the contents of the tag - * arg - message - */ - void handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Insert <img src=... /> tag if the 'format' field is specified as 'html' - */ - void handleTagImage(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Insert <p alt='title'>...</p> - */ - void handleTagPar(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Insert \@param command, if it is really a function param - */ - void handleTagParam(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Writes link for \ref tag. - */ - void handleTagRef(DoxygenEntity &tag, std::string &translatedComment, std::string &); - - /* - * Insert {@link...} command, and handle all the <link-object>s correctly - * (like converting types of params, etc) - */ - void handleTagLink(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - - /* - * Insert @see command, and handle all the <link-object>s correctly - * (like converting types of params, etc) - */ - void handleTagSee(DoxygenEntity &tag, std::string &translatedComment, std::string &arg); - -private: - Node *currentNode; - // this contains the handler pointer and one string argument - static std::map<std::string, std::pair<tagHandler, std::string> > tagHandlers; - void fillStaticTables(); - - bool paramExists(std::string param); - std::string indentAndInsertAsterisks(const std::string &doc); - - void addError(int warningType, const std::string &message); -}; - -#endif diff --git a/contrib/tools/swig/Source/Doxygen/pydoc.cxx b/contrib/tools/swig/Source/Doxygen/pydoc.cxx deleted file mode 100644 index 28f6051a724..00000000000 --- a/contrib/tools/swig/Source/Doxygen/pydoc.cxx +++ /dev/null @@ -1,993 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * pydoc.cxx - * - * Module to return documentation for nodes formatted for PyDoc - * ----------------------------------------------------------------------------- */ - -#include "pydoc.h" -#include "doxyparser.h" -#include <sstream> -#include <string> -#include <vector> -#include <iostream> - -#include "swigmod.h" - -// define static tables, they are filled in PyDocConverter's constructor -PyDocConverter::TagHandlersMap PyDocConverter::tagHandlers; -std::map<std::string, std::string> PyDocConverter::sectionTitles; - -using std::string; - -// Helper class increasing the provided indent string in its ctor and decreasing -// it in its dtor. -class IndentGuard { -public: - // One indent level. - static const char *Level() { - return " "; - } - // Default ctor doesn't do anything and prevents the dtor from doing anything// too and should only be used when the guard needs to be initialized// conditionally as Init() can then be called after checking some condition.// Otherwise, prefer to use the non default ctor below. - IndentGuard() { - m_initialized = false; - } - - // Ctor takes the output to determine the current indent and to remove the - // extra indent added to it in the dtor and the variable containing the indent - // to use, which must be used after every new line by the code actually - // updating the output. - IndentGuard(string &output, string &indent) { - Init(output, indent); - } - - // Really initializes the object created using the default ctor. - void Init(string &output, string &indent) { - m_output = &output; - m_indent = &indent; - - const string::size_type lastNonSpace = m_output->find_last_not_of(' '); - if (lastNonSpace == string::npos) { - m_firstLineIndent = m_output->length(); - } else if ((*m_output)[lastNonSpace] == '\n') { - m_firstLineIndent = m_output->length() - (lastNonSpace + 1); - } else { - m_firstLineIndent = 0; - } - - // Notice that the indent doesn't include the first line indent because it's - // implicit, i.e. it is present in the input and so is copied into the - // output anyhow. - *m_indent = Level(); - - m_initialized = true; - } - - // Get the indent for the first line of the paragraph, which is smaller than - // the indent for the subsequent lines. - string getFirstLineIndent() const { - return string(m_firstLineIndent, ' '); - } - - ~IndentGuard() { - if (!m_initialized) - return; - - m_indent->clear(); - - // Get rid of possible remaining extra indent, e.g. if there were any trailing - // new lines: we shouldn't add the extra indent level to whatever follows - // this paragraph. - static const size_t lenIndentLevel = strlen(Level()); - if (m_output->length() > lenIndentLevel) { - const size_t start = m_output->length() - lenIndentLevel; - if (m_output->compare(start, string::npos, Level()) == 0) - m_output->erase(start); - } - } - -private: - string *m_output; - string *m_indent; - string::size_type m_firstLineIndent; - bool m_initialized; - - IndentGuard(const IndentGuard &); - IndentGuard &operator=(const IndentGuard &); -}; - -// Return the indent of the given multiline string, i.e. the maximal number of -// spaces present in the beginning of all its non-empty lines. -static size_t determineIndent(const string &s) { - size_t minIndent = static_cast<size_t>(-1); - - for (size_t lineStart = 0; lineStart < s.length();) { - const size_t lineEnd = s.find('\n', lineStart); - const size_t firstNonSpace = s.find_first_not_of(' ', lineStart); - - // If inequality doesn't hold, it means that this line contains only spaces - // (notice that this works whether lineEnd is valid or string::npos), in - // which case it doesn't matter when determining the indent. - if (firstNonSpace < lineEnd) { - // Here we can be sure firstNonSpace != string::npos. - const size_t lineIndent = firstNonSpace - lineStart; - if (lineIndent < minIndent) - minIndent = lineIndent; - } - - if (lineEnd == string::npos) - break; - - lineStart = lineEnd + 1; - } - - return minIndent; -} - -static void trimWhitespace(string &s) { - const string::size_type lastNonSpace = s.find_last_not_of(' '); - if (lastNonSpace == string::npos) - s.clear(); - else - s.erase(lastNonSpace + 1); -} - -// Erase the first character in the string if it is a newline -static void eraseLeadingNewLine(string &s) { - if (!s.empty() && s[0] == '\n') - s.erase(s.begin()); -} - -// Erase the last character in the string if it is a newline -static void eraseTrailingNewLine(string &s) { - if (!s.empty() && s[s.size() - 1] == '\n') - s.erase(s.size() - 1); -} - -// Check the generated docstring line by line and make sure that any -// code and verbatim blocks have an empty line preceding them, which -// is necessary for Sphinx. Additionally, this strips any empty lines -// appearing at the beginning of the docstring. -static string padCodeAndVerbatimBlocks(const string &docString) { - std::string result; - - std::istringstream iss(docString); - - // Initialize to false because there is no previous line yet - bool lastLineWasNonBlank = false; - - for (string line; std::getline(iss, line); result += line) { - if (!result.empty()) { - // Terminate the previous line - result += '\n'; - } - - const size_t pos = line.find_first_not_of(" \t"); - if (pos == string::npos) { - lastLineWasNonBlank = false; - } else { - if (lastLineWasNonBlank && - (line.compare(pos, 13, ".. code-block") == 0 || - line.compare(pos, 7, ".. math") == 0 || - line.compare(pos, 3, ">>>") == 0)) { - // Must separate code or math blocks from the previous line - result += '\n'; - } - lastLineWasNonBlank = true; - } - } - return result; -} - -// Helper function to extract the option value from a command, -// e.g. param[in] -> in -static std::string getCommandOption(const std::string &command, char openChar, char closeChar) { - string option; - - size_t opt_begin, opt_end; - opt_begin = command.find(openChar); - opt_end = command.find(closeChar); - if (opt_begin != string::npos && opt_end != string::npos) - option = command.substr(opt_begin+1, opt_end-opt_begin-1); - - return option; -} - - -/* static */ -PyDocConverter::TagHandlersMap::mapped_type PyDocConverter::make_handler(tagHandler handler) { - return make_pair(handler, std::string()); -} - -/* static */ -PyDocConverter::TagHandlersMap::mapped_type PyDocConverter::make_handler(tagHandler handler, const char *arg) { - return make_pair(handler, arg); -} - -void PyDocConverter::fillStaticTables() { - if (tagHandlers.size()) // fill only once - return; - - // table of section titles, they are printed only once - // for each group of specified doxygen commands - sectionTitles["author"] = "Author: "; - sectionTitles["authors"] = "Authors: "; - sectionTitles["copyright"] = "Copyright: "; - sectionTitles["deprecated"] = "Deprecated: "; - sectionTitles["example"] = "Example: "; - sectionTitles["note"] = "Notes: "; - sectionTitles["remark"] = "Remarks: "; - sectionTitles["remarks"] = "Remarks: "; - sectionTitles["warning"] = "Warning: "; -// sectionTitles["sa"] = "See also: "; -// sectionTitles["see"] = "See also: "; - sectionTitles["since"] = "Since: "; - sectionTitles["todo"] = "TODO: "; - sectionTitles["version"] = "Version: "; - - tagHandlers["a"] = make_handler(&PyDocConverter::handleTagWrap, "*"); - tagHandlers["b"] = make_handler(&PyDocConverter::handleTagWrap, "**"); - // \c command is translated as single quotes around next word - tagHandlers["c"] = make_handler(&PyDocConverter::handleTagWrap, "``"); - tagHandlers["cite"] = make_handler(&PyDocConverter::handleTagWrap, "'"); - tagHandlers["e"] = make_handler(&PyDocConverter::handleTagWrap, "*"); - // these commands insert just a single char, some of them need to be escaped - tagHandlers["$"] = make_handler(&PyDocConverter::handleTagChar); - tagHandlers["@"] = make_handler(&PyDocConverter::handleTagChar); - tagHandlers["\\"] = make_handler(&PyDocConverter::handleTagChar); - tagHandlers["<"] = make_handler(&PyDocConverter::handleTagChar); - tagHandlers[">"] = make_handler(&PyDocConverter::handleTagChar); - tagHandlers["&"] = make_handler(&PyDocConverter::handleTagChar); - tagHandlers["#"] = make_handler(&PyDocConverter::handleTagChar); - tagHandlers["%"] = make_handler(&PyDocConverter::handleTagChar); - tagHandlers["~"] = make_handler(&PyDocConverter::handleTagChar); - tagHandlers["\""] = make_handler(&PyDocConverter::handleTagChar); - tagHandlers["."] = make_handler(&PyDocConverter::handleTagChar); - tagHandlers["::"] = make_handler(&PyDocConverter::handleTagChar); - // these commands are stripped out, and only their content is printed - tagHandlers["attention"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["author"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["authors"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["brief"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["bug"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["code"] = make_handler(&PyDocConverter::handleCode); - tagHandlers["copyright"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["date"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["deprecated"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["details"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["em"] = make_handler(&PyDocConverter::handleTagWrap, "*"); - tagHandlers["example"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["exception"] = tagHandlers["throw"] = tagHandlers["throws"] = make_handler(&PyDocConverter::handleTagException); - tagHandlers["htmlonly"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["invariant"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["latexonly"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["link"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["manonly"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["note"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["p"] = make_handler(&PyDocConverter::handleTagWrap, "``"); - tagHandlers["partofdescription"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["rtfonly"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["remark"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["remarks"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["sa"] = make_handler(&PyDocConverter::handleTagMessage, "See also: "); - tagHandlers["see"] = make_handler(&PyDocConverter::handleTagMessage, "See also: "); - tagHandlers["since"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["short"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["todo"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["version"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["verbatim"] = make_handler(&PyDocConverter::handleVerbatimBlock); - tagHandlers["warning"] = make_handler(&PyDocConverter::handleParagraph); - tagHandlers["xmlonly"] = make_handler(&PyDocConverter::handleParagraph); - // these commands have special handlers - tagHandlers["arg"] = make_handler(&PyDocConverter::handleTagMessage, "* "); - tagHandlers["cond"] = make_handler(&PyDocConverter::handleTagMessage, "Conditional comment: "); - tagHandlers["else"] = make_handler(&PyDocConverter::handleTagIf, "Else: "); - tagHandlers["elseif"] = make_handler(&PyDocConverter::handleTagIf, "Else if: "); - tagHandlers["endcond"] = make_handler(&PyDocConverter::handleTagMessage, "End of conditional comment."); - tagHandlers["if"] = make_handler(&PyDocConverter::handleTagIf, "If: "); - tagHandlers["ifnot"] = make_handler(&PyDocConverter::handleTagIf, "If not: "); - tagHandlers["image"] = make_handler(&PyDocConverter::handleTagImage); - tagHandlers["li"] = make_handler(&PyDocConverter::handleTagMessage, "* "); - tagHandlers["overload"] = make_handler(&PyDocConverter::handleTagMessage, - "This is an overloaded member function, provided for" - " convenience.\nIt differs from the above function only in what" " argument(s) it accepts."); - tagHandlers["par"] = make_handler(&PyDocConverter::handleTagPar); - tagHandlers["param"] = tagHandlers["tparam"] = make_handler(&PyDocConverter::handleTagParam); - tagHandlers["ref"] = make_handler(&PyDocConverter::handleTagRef); - tagHandlers["result"] = tagHandlers["return"] = tagHandlers["returns"] = make_handler(&PyDocConverter::handleTagReturn); - - // this command just prints its contents - // (it is internal command of swig's parser, contains plain text) - tagHandlers["plainstd::string"] = make_handler(&PyDocConverter::handlePlainString); - tagHandlers["plainstd::endl"] = make_handler(&PyDocConverter::handleNewLine); - tagHandlers["n"] = make_handler(&PyDocConverter::handleNewLine); - - // \f commands output literal Latex formula, which is still better than nothing. - tagHandlers["f$"] = tagHandlers["f["] = tagHandlers["f{"] = make_handler(&PyDocConverter::handleMath); - - // HTML tags - tagHandlers["<a"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_A); - tagHandlers["<b"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**"); - tagHandlers["<blockquote"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_A, "Quote: "); - tagHandlers["<body"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<br"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "\n"); - - // there is no formatting for this tag as it was deprecated in HTML 4.01 and - // not used in HTML 5 - tagHandlers["<center"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<caption"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<code"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "``"); - - tagHandlers["<dl"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<dd"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " "); - tagHandlers["<dt"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - - tagHandlers["<dfn"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<div"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<em"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**"); - tagHandlers["<form"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<hr"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "--------------------------------------------------------------------\n"); - tagHandlers["<h1"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "# "); - tagHandlers["<h2"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "## "); - tagHandlers["<h3"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "### "); - tagHandlers["<i"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "*"); - tagHandlers["<input"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<img"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "Image:"); - tagHandlers["<li"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "* "); - tagHandlers["<meta"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<multicol"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<ol"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<p"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, "\n"); - tagHandlers["<pre"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<small"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<span"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "'"); - tagHandlers["<strong"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "**"); - - // make a space between text and super/sub script. - tagHandlers["<sub"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " "); - tagHandlers["<sup"] = make_handler(&PyDocConverter::handleDoxyHtmlTag, " "); - - tagHandlers["<table"] = make_handler(&PyDocConverter::handleDoxyHtmlTagNoParam); - tagHandlers["<td"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_td); - tagHandlers["<th"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_th); - tagHandlers["<tr"] = make_handler(&PyDocConverter::handleDoxyHtmlTag_tr); - tagHandlers["<tt"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<kbd"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<ul"] = make_handler(&PyDocConverter::handleDoxyHtmlTag); - tagHandlers["<var"] = make_handler(&PyDocConverter::handleDoxyHtmlTag2, "*"); - - // HTML entities - tagHandlers["©"] = make_handler(&PyDocConverter::handleHtmlEntity, "(C)"); - tagHandlers["&trade"] = make_handler(&PyDocConverter::handleHtmlEntity, " TM"); - tagHandlers["®"] = make_handler(&PyDocConverter::handleHtmlEntity, "(R)"); - tagHandlers["<"] = make_handler(&PyDocConverter::handleHtmlEntity, "<"); - tagHandlers[">"] = make_handler(&PyDocConverter::handleHtmlEntity, ">"); - tagHandlers["&"] = make_handler(&PyDocConverter::handleHtmlEntity, "&"); - tagHandlers["&apos"] = make_handler(&PyDocConverter::handleHtmlEntity, "'"); - tagHandlers["""] = make_handler(&PyDocConverter::handleHtmlEntity, "\""); - tagHandlers["&lsquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "`"); - tagHandlers["&rsquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "'"); - tagHandlers["&ldquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "\""); - tagHandlers["&rdquo"] = make_handler(&PyDocConverter::handleHtmlEntity, "\""); - tagHandlers["&ndash"] = make_handler(&PyDocConverter::handleHtmlEntity, "-"); - tagHandlers["&mdash"] = make_handler(&PyDocConverter::handleHtmlEntity, "--"); - tagHandlers[" "] = make_handler(&PyDocConverter::handleHtmlEntity, " "); - tagHandlers["×"] = make_handler(&PyDocConverter::handleHtmlEntity, "x"); - tagHandlers["&minus"] = make_handler(&PyDocConverter::handleHtmlEntity, "-"); - tagHandlers["&sdot"] = make_handler(&PyDocConverter::handleHtmlEntity, "."); - tagHandlers["&sim"] = make_handler(&PyDocConverter::handleHtmlEntity, "~"); - tagHandlers["&le"] = make_handler(&PyDocConverter::handleHtmlEntity, "<="); - tagHandlers["&ge"] = make_handler(&PyDocConverter::handleHtmlEntity, ">="); - tagHandlers["&larr"] = make_handler(&PyDocConverter::handleHtmlEntity, "<--"); - tagHandlers["&rarr"] = make_handler(&PyDocConverter::handleHtmlEntity, "-->"); -} - -PyDocConverter::PyDocConverter(int flags): -DoxygenTranslator(flags), m_tableLineLen(0), m_prevRowIsTH(false) { - fillStaticTables(); -} - -// Return the type as it should appear in the output documentation. -static std::string getPyDocType(Node *n, const_String_or_char_ptr lname = "") { - std::string type; - - String *s = Swig_typemap_lookup("doctype", n, lname, 0); - if (!s) { - if (String *t = Getattr(n, "type")) - s = SwigType_str(t, ""); - } - - if (!s) - return type; - - if (Language::classLookup(s)) { - // In Python C++ namespaces are flattened, so remove all but last component - // of the name. - String *const last = Swig_scopename_last(s); - - // We are not actually sure whether it's a documented class or not, but - // there doesn't seem to be any harm in making it a reference if it isn't, - // while there is a lot of benefit in having a hyperlink if it is. - type = ":py:class:`"; - type += Char(last); - type += "`"; - - Delete(last); - } else { - type = Char(s); - } - - Delete(s); - - return type; -} - -std::string PyDocConverter::getParamType(std::string param) { - std::string type; - - ParmList *plist = CopyParmList(Getattr(currentNode, "parms")); - for (Parm *p = plist; p; p = nextSibling(p)) { - String *pname = Getattr(p, "name"); - if (pname && Char(pname) == param) { - type = getPyDocType(p, pname); - break; - } - } - Delete(plist); - return type; -} - -std::string PyDocConverter::getParamValue(std::string param) { - std::string value; - - ParmList *plist = CopyParmList(Getattr(currentNode, "parms")); - for (Parm *p = plist; p; p = nextSibling(p)) { - String *pname = Getattr(p, "name"); - if (pname && Char(pname) == param) { - String *pval = Getattr(p, "value"); - if (pval) - value = Char(pval); - break; - } - } - Delete(plist); - return value; -} - -std::string PyDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) { - std::string translatedComment; - - if (doxygenEntity.isLeaf) - return translatedComment; - - std::string currentSection; - std::list<DoxygenEntity>::iterator p = doxygenEntity.entityList.begin(); - while (p != doxygenEntity.entityList.end()) { - std::map<std::string, std::string>::iterator it; - it = sectionTitles.find(p->typeOfEntity); - if (it != sectionTitles.end()) { - if (it->second != currentSection) { - currentSection = it->second; - translatedComment += currentSection; - } - } - translateEntity(*p, translatedComment); - translateSubtree(*p); - p++; - } - - return translatedComment; -} - -void PyDocConverter::translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment) { - // check if we have needed handler and call it - std::map<std::string, std::pair<tagHandler, std::string> >::iterator it; - it = tagHandlers.find(getBaseCommand(doxyEntity.typeOfEntity)); - if (it != tagHandlers.end()) - (this->*(it->second.first)) (doxyEntity, translatedComment, it->second.second); -} - -void PyDocConverter::handleParagraph(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - translatedComment += translateSubtree(tag); -} - -void PyDocConverter::handleVerbatimBlock(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - string verb = translateSubtree(tag); - - eraseLeadingNewLine(verb); - - // Remove the last newline to prevent doubling the newline already present after \endverbatim - trimWhitespace(verb); // Needed to catch trailing newline below - eraseTrailingNewLine(verb); - translatedComment += verb; -} - -void PyDocConverter::handleMath(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { - IndentGuard indent; - - // Only \f$ is translated to inline formulae, \f[ and \f{ are for the block ones. - const bool inlineFormula = tag.typeOfEntity == "f$"; - - string formulaNL; - - if (inlineFormula) { - translatedComment += ":math:`"; - } else { - indent.Init(translatedComment, m_indent); - - trimWhitespace(translatedComment); - - const string formulaIndent = indent.getFirstLineIndent(); - translatedComment += formulaIndent; - translatedComment += ".. math::\n"; - - formulaNL = '\n'; - formulaNL += formulaIndent; - formulaNL += m_indent; - translatedComment += formulaNL; - } - - std::string formula; - handleTagVerbatim(tag, formula, arg); - - // It is important to ensure that we have no spaces around the inline math - // contents, so strip them. - const size_t start = formula.find_first_not_of(" \t\n"); - const size_t end = formula.find_last_not_of(" \t\n"); - if (start != std::string::npos) { - for (size_t n = start; n <= end; n++) { - if (formula[n] == '\n') { - // New lines must be suppressed in inline maths and indented in the block ones. - if (!inlineFormula) - translatedComment += formulaNL; - } else { - // Just copy everything else. - translatedComment += formula[n]; - } - } - } - - if (inlineFormula) { - translatedComment += "`"; - } -} - -void PyDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { - IndentGuard indent(translatedComment, m_indent); - - trimWhitespace(translatedComment); - - // Check for an option given to the code command (e.g. code{.py}), - // and try to set the code-block language accordingly. - string option = getCommandOption(tag.typeOfEntity, '{', '}'); - // Set up the language option to the code-block command, which can - // be any language supported by pygments: - string codeLanguage; - if (option == ".py") - // Other possibilities here are "default" or "python3". In Sphinx - // 2.1.2, basic syntax doesn't render quite the same in these as - // with "python", which for basic keywords seems to provide - // slightly richer formatting. Another option would be to leave - // the language empty, but testing with Sphinx 1.8.5 has produced - // an error "1 argument required". - codeLanguage = "python"; - else if (option == ".java") - codeLanguage = "java"; - else if (option == ".c") - codeLanguage = "c"; - else - // If there is not a match, or if no option was given, go out on a - // limb and assume that the examples in the C or C++ sources use - // C++. - codeLanguage = "c++"; - - std::string code; - handleTagVerbatim(tag, code, arg); - - // Try and remove leading newline, which is present for block \code - // command: - eraseLeadingNewLine(code); - - // Check for python doctest blocks, and treat them specially: - bool isDocTestBlock = false; - size_t startPos; - // ">>>" would normally appear at the beginning, but doxygen comment - // style may have space in front, so skip leading whitespace - if ((startPos=code.find_first_not_of(" \t")) != string::npos && code.substr(startPos,3) == ">>>") - isDocTestBlock = true; - - string codeIndent; - if (! isDocTestBlock) { - // Use the current indent for the code-block line itself. - translatedComment += indent.getFirstLineIndent(); - translatedComment += ".. code-block:: " + codeLanguage + "\n\n"; - - // Specify the level of extra indentation that will be used for - // subsequent lines within the code block. Note that the correct - // "starting indentation" is already present in the input, so we - // only need to add the desired code block indentation. - codeIndent = m_indent; - } - - translatedComment += codeIndent; - for (size_t n = 0; n < code.length(); n++) { - if (code[n] == '\n') { - // Don't leave trailing white space, this results in PEP8 validation - // errors in Python code (which are performed by our own unit tests). - trimWhitespace(translatedComment); - translatedComment += '\n'; - - // Ensure that we indent all the lines by the code indent. - translatedComment += codeIndent; - } else { - // Just copy everything else. - translatedComment += code[n]; - } - } - - trimWhitespace(translatedComment); - - // For block commands, the translator adds the newline after - // \endcode, so try and compensate by removing the last newline from - // the code text: - eraseTrailingNewLine(translatedComment); -} - -void PyDocConverter::handlePlainString(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - translatedComment += tag.data; -} - -void PyDocConverter::handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { - translatedComment += arg; - for (DoxygenEntityListCIt it = tag.entityList.begin(); it != tag.entityList.end(); it++) { - translatedComment += it->data; - } -} - -void PyDocConverter::handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { - translatedComment += arg; - handleParagraph(tag, translatedComment); -} - -void PyDocConverter::handleTagChar(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - translatedComment += tag.typeOfEntity; -} - -void PyDocConverter::handleTagIf(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { - translatedComment += arg; - if (tag.entityList.size()) { - translatedComment += tag.entityList.begin()->data; - tag.entityList.pop_front(); - translatedComment += " {" + translateSubtree(tag) + "}"; - } -} - -void PyDocConverter::handleTagPar(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - translatedComment += "Title: "; - if (tag.entityList.size()) - translatedComment += tag.entityList.begin()->data; - tag.entityList.pop_front(); - handleParagraph(tag, translatedComment); -} - -void PyDocConverter::handleTagImage(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - if (tag.entityList.size() < 2) - return; - tag.entityList.pop_front(); - translatedComment += "Image: "; - translatedComment += tag.entityList.begin()->data; - tag.entityList.pop_front(); - if (tag.entityList.size()) - translatedComment += "(" + tag.entityList.begin()->data + ")"; -} - -void PyDocConverter::handleTagParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - if (tag.entityList.size() < 2) - return; - - IndentGuard indent(translatedComment, m_indent); - - DoxygenEntity paramNameEntity = *tag.entityList.begin(); - tag.entityList.pop_front(); - - const std::string ¶mName = paramNameEntity.data; - - const std::string paramType = getParamType(paramName); - const std::string paramValue = getParamValue(paramName); - - // Get command option, e.g. "in", "out", or "in,out" - string commandOpt = getCommandOption(tag.typeOfEntity, '[', ']'); - if (commandOpt == "in,out") commandOpt = "in/out"; - - // If provided, append the parameter direction to the type - // information via a suffix: - std::string suffix; - if (commandOpt.size() > 0) - suffix = ", " + commandOpt; - - // If the parameter has a default value, flag it as optional in the - // generated type definition. Particularly helpful when the python - // call is generated with *args, **kwargs. - if (paramValue.size() > 0) - suffix += ", optional"; - - if (!paramType.empty()) { - translatedComment += ":type " + paramName + ": " + paramType + suffix + "\n"; - translatedComment += indent.getFirstLineIndent(); - } - - translatedComment += ":param " + paramName + ":"; - - handleParagraph(tag, translatedComment); -} - - -void PyDocConverter::handleTagReturn(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - IndentGuard indent(translatedComment, m_indent); - - const std::string pytype = getPyDocType(currentNode); - if (!pytype.empty()) { - translatedComment += ":rtype: "; - translatedComment += pytype; - translatedComment += "\n"; - translatedComment += indent.getFirstLineIndent(); - } - - translatedComment += ":return: "; - handleParagraph(tag, translatedComment); -} - - -void PyDocConverter::handleTagException(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - IndentGuard indent(translatedComment, m_indent); - - translatedComment += ":raises: "; - handleParagraph(tag, translatedComment); -} - - -void PyDocConverter::handleTagRef(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - if (!tag.entityList.size()) - return; - - string anchor = tag.entityList.begin()->data; - tag.entityList.pop_front(); - string anchorText = anchor; - if (!tag.entityList.empty()) { - anchorText = tag.entityList.begin()->data; - } - translatedComment += "'" + anchorText + "'"; -} - - -void PyDocConverter::handleTagWrap(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { - if (tag.entityList.size()) { // do not include empty tags - std::string tagData = translateSubtree(tag); - // wrap the thing, ignoring whitespace - size_t wsPos = tagData.find_last_not_of("\n\t "); - if (wsPos != std::string::npos && wsPos != tagData.size() - 1) - translatedComment += arg + tagData.substr(0, wsPos + 1) + arg + tagData.substr(wsPos + 1); - else - translatedComment += arg + tagData + arg; - } -} - -void PyDocConverter::handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { - std::string htmlTagArgs = tag.data; - if (htmlTagArgs == "/") { - // end html tag, for example "</ul> - // translatedComment += "</" + arg.substr(1) + ">"; - } else { - translatedComment += arg + htmlTagArgs; - } -} - -void PyDocConverter::handleDoxyHtmlTagNoParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { - std::string htmlTagArgs = tag.data; - if (htmlTagArgs == "/") { - // end html tag, for example "</ul> - } else { - translatedComment += arg; - } -} - -void PyDocConverter::handleDoxyHtmlTag_A(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { - std::string htmlTagArgs = tag.data; - if (htmlTagArgs == "/") { - // end html tag, "</a> - translatedComment += " (" + m_url + ')'; - m_url.clear(); - } else { - m_url.clear(); - size_t pos = htmlTagArgs.find('='); - if (pos != string::npos) { - m_url = htmlTagArgs.substr(pos + 1); - } - translatedComment += arg; - } -} - -void PyDocConverter::handleDoxyHtmlTag2(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg) { - std::string htmlTagArgs = tag.data; - if (htmlTagArgs == "/") { - // end html tag, for example "</em> - translatedComment += arg; - } else { - translatedComment += arg; - } -} - -void PyDocConverter::handleDoxyHtmlTag_tr(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - std::string htmlTagArgs = tag.data; - size_t nlPos = translatedComment.rfind('\n'); - if (htmlTagArgs == "/") { - // end tag, </tr> appends vertical table line '|' - translatedComment += '|'; - if (nlPos != string::npos) { - size_t startOfTableLinePos = translatedComment.find_first_not_of(" \t", nlPos + 1); - if (startOfTableLinePos != string::npos) { - m_tableLineLen = translatedComment.size() - startOfTableLinePos; - } - } - } else { - if (m_prevRowIsTH) { - // if previous row contained <th> tag, add horizontal separator - // but first get leading spaces, because they'll be needed for the next row - size_t numLeadingSpaces = translatedComment.size() - nlPos - 1; - - translatedComment += string(m_tableLineLen, '-') + '\n'; - - if (nlPos != string::npos) { - translatedComment += string(numLeadingSpaces, ' '); - } - m_prevRowIsTH = false; - } - } -} - -void PyDocConverter::handleDoxyHtmlTag_th(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - std::string htmlTagArgs = tag.data; - if (htmlTagArgs == "/") { - // end tag, </th> is ignored - } else { - translatedComment += '|'; - m_prevRowIsTH = true; - } -} - -void PyDocConverter::handleDoxyHtmlTag_td(DoxygenEntity &tag, std::string &translatedComment, const std::string &) { - std::string htmlTagArgs = tag.data; - if (htmlTagArgs == "/") { - // end tag, </td> is ignored - } else { - translatedComment += '|'; - } -} - -void PyDocConverter::handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, const std::string &arg) { - // html entities - translatedComment += arg; -} - -void PyDocConverter::handleNewLine(DoxygenEntity &, std::string &translatedComment, const std::string &) { - trimWhitespace(translatedComment); - - translatedComment += "\n"; - if (!m_indent.empty()) - translatedComment += m_indent; -} - -String *PyDocConverter::makeDocumentation(Node *n) { - String *documentation; - std::string pyDocString; - - // store the node, we may need it later - currentNode = n; - - // for overloaded functions we must concat documentation for underlying overloads - if (Getattr(n, "sym:overloaded")) { - // rewind to the first overload - while (Getattr(n, "sym:previousSibling")) - n = Getattr(n, "sym:previousSibling"); - - std::vector<std::string> allDocumentation; - - // minimal indent of any documentation comments, not initialized yet - size_t minIndent = static_cast<size_t>(-1); - - // for each real method (not a generated overload) append the documentation - string oneDoc; - while (n) { - documentation = getDoxygenComment(n); - if (!Swig_is_generated_overload(n) && documentation) { - currentNode = n; - if (GetFlag(n, "feature:doxygen:notranslate")) { - String *comment = NewString(""); - Append(comment, documentation); - Replaceall(comment, "\n *", "\n"); - oneDoc = Char(comment); - Delete(comment); - } else { - std::list<DoxygenEntity> entityList = parser.createTree(n, documentation); - DoxygenEntity root("root", entityList); - - oneDoc = translateSubtree(root); - } - - // find the minimal indent of this documentation comment, we need to - // ensure that the entire comment is indented by it to avoid the leading - // parts of the other lines being simply discarded later - const size_t oneIndent = determineIndent(oneDoc); - if (oneIndent < minIndent) - minIndent = oneIndent; - - allDocumentation.push_back(oneDoc); - } - n = Getattr(n, "sym:nextSibling"); - } - - // construct final documentation string - if (allDocumentation.size() > 1) { - string indentStr; - if (minIndent != static_cast<size_t>(-1)) - indentStr.assign(minIndent, ' '); - - std::ostringstream concatDocString; - for (size_t realOverloadCount = 0; realOverloadCount < allDocumentation.size(); realOverloadCount++) { - if (realOverloadCount != 0) { - // separate it from the preceding one. - concatDocString << "\n" << indentStr << "|\n\n"; - } - - oneDoc = allDocumentation[realOverloadCount]; - trimWhitespace(oneDoc); - concatDocString << indentStr << "*Overload " << (realOverloadCount + 1) << ":*\n" << oneDoc; - } - pyDocString = concatDocString.str(); - } else if (allDocumentation.size() == 1) { - pyDocString = *(allDocumentation.begin()); - } - } - // for other nodes just process as normal - else { - documentation = getDoxygenComment(n); - if (documentation != NULL) { - if (GetFlag(n, "feature:doxygen:notranslate")) { - String *comment = NewString(""); - Append(comment, documentation); - Replaceall(comment, "\n *", "\n"); - pyDocString = Char(comment); - Delete(comment); - } else { - std::list<DoxygenEntity> entityList = parser.createTree(n, documentation); - DoxygenEntity root("root", entityList); - pyDocString = translateSubtree(root); - } - } - } - - // if we got something log the result - if (!pyDocString.empty()) { - - // remove the last '\n' since additional one is added during writing to file - eraseTrailingNewLine(pyDocString); - - // ensure that a blank line occurs before code or math blocks - pyDocString = padCodeAndVerbatimBlocks(pyDocString); - - if (m_flags & debug_translator) { - std::cout << "\n---RESULT IN PYDOC---" << std::endl; - std::cout << pyDocString; - std::cout << std::endl; - } - } - - return NewString(pyDocString.c_str()); -} - diff --git a/contrib/tools/swig/Source/Doxygen/pydoc.h b/contrib/tools/swig/Source/Doxygen/pydoc.h deleted file mode 100644 index 880ee3069c8..00000000000 --- a/contrib/tools/swig/Source/Doxygen/pydoc.h +++ /dev/null @@ -1,208 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * pydoc.h - * - * Module to return documentation for nodes formatted for PyDoc - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_PYDOC_H -#define SWIG_PYDOC_H - -#include <list> -#include <string> -#include "swig.h" -#include "doxyentity.h" -#include "doxytranslator.h" - -#define DOC_STRING_LENGTH 64 // characters per line allowed -#define DOC_PARAM_STRING_LENGTH 30 // characters reserved for param name / type - -class PyDocConverter : public DoxygenTranslator { -public: - PyDocConverter(int flags = 0); - String *makeDocumentation(Node *node); - -protected: - - size_t m_tableLineLen; - bool m_prevRowIsTH; - std::string m_url; - - /* - * Translate every entity in a tree, also manages sections - * display. Prints title for every group of tags that have - * a section title associated with them - */ - std::string translateSubtree(DoxygenEntity &doxygenEntity); - - /* - * Translate one entity with the appropriate handler, according - * to the tagHandlers - */ - void translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment); - - /* - * Typedef for the function that handles one tag - * arg - some string argument to easily pass it through lookup table - */ - typedef void (PyDocConverter::*tagHandler) (DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Wrap the command data with the some string - * arg - string to wrap with, like '_' or '*' - */ - void handleTagWrap(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Just prints new line - */ - void handleNewLine(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Print the name of tag to the output, used for escape-commands - */ - void handleTagChar(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Format the contents of the \exception tag or its synonyms. - */ - void handleTagException(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Print only the content and strip original tag - */ - void handleParagraph(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string()); - - /* - * Handle Doxygen verbatim tag - */ - void handleVerbatimBlock(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg = std::string()); - - /* - * Handle one of the Doxygen formula-related tags. - */ - void handleMath(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Handle a code snippet. - */ - void handleCode(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Print only data part of code - */ - void handlePlainString(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /** - * Copies verbatim args of the tag to output, used for commands like \f$, ... - */ - void handleTagVerbatim(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Print the if-elseif-else-endif section - */ - void handleTagIf(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Prints the specified message, than the contents of the tag - * arg - message - */ - void handleTagMessage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Insert 'Title: ...' - */ - void handleTagPar(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Insert 'Image: ...' - */ - void handleTagImage(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Format nice param description with type information - */ - void handleTagParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Format the contents of the \return tag or its synonyms. - */ - void handleTagReturn(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Writes text for \ref tag. - */ - void handleTagRef(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* Handles HTML tags recognized by Doxygen, like <A ...>, <ul>, <table>, ... */ - - void handleDoxyHtmlTag(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /** Does not output params of HTML tag, for example in <table border='1'> - * 'border=1' is not written to output. - */ - void handleDoxyHtmlTagNoParam(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /** Translates tag <a href = "url">text</a> to: text ("url"). */ - void handleDoxyHtmlTag_A(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* - * Handles HTML tags, which are translated to markdown-like syntax, for example - * <i>text</i> --> _text_. Appends arg for start HTML tag and end HTML tag. - */ - void handleDoxyHtmlTag2(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* Handles HTML table, tag <tr> */ - void handleDoxyHtmlTag_tr(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* Handles HTML table, tag <th> */ - void handleDoxyHtmlTag_th(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* Handles HTML table, tag <td> */ - void handleDoxyHtmlTag_td(DoxygenEntity &tag, std::string &translatedComment, const std::string &arg); - - /* Handles HTML entities recognized by Doxygen, like <, ©, ... */ - void handleHtmlEntity(DoxygenEntity &, std::string &translatedComment, const std::string &arg); - - - /* - * Simple helper function that calculates correct parameter type - * of the node stored in 'currentNode' - * If param with specified name is not found, empty string is returned - */ - std::string getParamType(std::string name); - - /* - * Simple helper function to retrieve the parameter value - */ - std::string getParamValue(std::string name); - -private: - // temporary thing, should be refactored somehow - Node *currentNode; - - // Extra indent for the current paragraph, must be output after each new line. - std::string m_indent; - - - // this contains the handler pointer and one string argument - typedef std::map<std::string, std::pair<tagHandler, std::string> >TagHandlersMap; - static TagHandlersMap tagHandlers; - - // this contains the sections titles, like 'Arguments:' or 'Notes:', that are printed only once - static std::map<std::string, std::string> sectionTitles; - - // Helper functions for fillStaticTables(): make a new tag handler object. - TagHandlersMap::mapped_type make_handler(tagHandler handler); - TagHandlersMap::mapped_type make_handler(tagHandler handler, const char *arg); - - void fillStaticTables(); -}; - -#endif diff --git a/contrib/tools/swig/Source/Include/swigconfig.h b/contrib/tools/swig/Source/Include/swigconfig.h deleted file mode 100644 index b6287a10b8a..00000000000 --- a/contrib/tools/swig/Source/Include/swigconfig.h +++ /dev/null @@ -1,105 +0,0 @@ -/* Source/Include/swigconfig.h. Generated from swigconfig.h.in by configure. */ -/* Source/Include/swigconfig.h.in. Generated from configure.ac by autoheader. */ - -/* define if the Boost library is available */ -#define HAVE_BOOST /**/ - -/* define if the compiler supports basic C++11 syntax */ -/* #undef HAVE_CXX11 */ - -/* define if the compiler supports basic C++14 syntax */ -/* #undef HAVE_CXX14 */ - -/* define if the compiler supports basic C++17 syntax */ -/* #undef HAVE_CXX17 */ - -/* define if the compiler supports basic C++20 syntax */ -#define HAVE_CXX20 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -/* #undef HAVE_INTTYPES_H */ - -/* Define to 1 if you have the `dl' library (-ldl). */ -#define HAVE_LIBDL 1 - -/* Define to 1 if you have the `dld' library (-ldld). */ -/* #undef HAVE_LIBDLD */ - -/* Define if you have PCRE2 library */ -#define HAVE_PCRE 1 - -/* Define if popen is available */ -#define HAVE_POPEN 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -/* #undef HAVE_STDINT_H */ - -/* Define to 1 if you have the <stdio.h> header file. */ -/* #undef HAVE_STDIO_H */ - -/* Define to 1 if you have the <stdlib.h> header file. */ -/* #undef HAVE_STDLIB_H */ - -/* Define to 1 if you have the <strings.h> header file. */ -/* #undef HAVE_STRINGS_H */ - -/* Define to 1 if you have the <string.h> header file. */ -/* #undef HAVE_STRING_H */ - -/* Define to 1 if you have the <sys/stat.h> header file. */ -/* #undef HAVE_SYS_STAT_H */ - -/* Define to 1 if you have the <sys/types.h> header file. */ -/* #undef HAVE_SYS_TYPES_H */ - -/* Define to 1 if you have the <unistd.h> header file. */ -/* #undef HAVE_UNISTD_H */ - -/* Name of package */ -#define PACKAGE "swig" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "https://www.swig.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "swig" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "swig 4.1.1" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "swig" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "4.1.1" - -/* Define to 1 if all of the C90 standard headers exist (not just the ones - required in a freestanding environment). This macro is provided for - backward compatibility; new code need not use it. */ -/* #undef STDC_HEADERS */ - -/* Compiler that built SWIG */ -#define SWIG_CXX "g++" - -/* Directory for SWIG system-independent libraries */ -#define SWIG_LIB "/var/empty/swig-4.1.1/share/swig/4.1.1" - -/* Directory for SWIG system-independent libraries (Unix install on native - Windows) */ -#define SWIG_LIB_WIN_UNIX "" - -/* Platform that SWIG is built for */ -#define SWIG_PLATFORM "x86_64-pc-linux-gnu" - -/* Version number of package */ -#define VERSION "4.1.1" - - -/* Deal with attempt by Microsoft to deprecate C standard runtime functions */ -#if defined(_MSC_VER) -# define _CRT_SECURE_NO_DEPRECATE -#endif - diff --git a/contrib/tools/swig/Source/Include/swigwarn.h b/contrib/tools/swig/Source/Include/swigwarn.h deleted file mode 100644 index f38607f9257..00000000000 --- a/contrib/tools/swig/Source/Include/swigwarn.h +++ /dev/null @@ -1,327 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * swigwarn.h - * - * SWIG warning message numbers - * This file serves as the main registry of warning message numbers. Some of these - * numbers are used internally in the C/C++ source code of SWIG. However, some - * of the numbers are used in SWIG configuration files (swig.swg and others). - * - * The numbers are roughly organized into a few different classes by functionality. - * - * Even though symbolic constants are used in the SWIG source, this is - * not always the case in SWIG interface files. Do not change the - * numbers in this file. - * - * This file is used as the input for generating Lib/swigwarn.swg. - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_SWIGWARN_H -#define SWIG_SWIGWARN_H - -#define WARN_NONE 0 - -/* -- Deprecated features -- */ - -#define WARN_DEPRECATED_EXTERN 101 -#define WARN_DEPRECATED_VAL 102 -#define WARN_DEPRECATED_OUT 103 -#define WARN_DEPRECATED_DISABLEDOC 104 -#define WARN_DEPRECATED_ENABLEDOC 105 -#define WARN_DEPRECATED_DOCONLY 106 -#define WARN_DEPRECATED_STYLE 107 -#define WARN_DEPRECATED_LOCALSTYLE 108 -#define WARN_DEPRECATED_TITLE 109 -#define WARN_DEPRECATED_SECTION 110 -#define WARN_DEPRECATED_SUBSECTION 111 -#define WARN_DEPRECATED_SUBSUBSECTION 112 -#define WARN_DEPRECATED_ADDMETHODS 113 -#define WARN_DEPRECATED_READONLY 114 -#define WARN_DEPRECATED_READWRITE 115 -#define WARN_DEPRECATED_EXCEPT 116 -#define WARN_DEPRECATED_NEW 117 -#define WARN_DEPRECATED_EXCEPT_TM 118 -#define WARN_DEPRECATED_IGNORE_TM 119 -#define WARN_DEPRECATED_OPTC 120 -#define WARN_DEPRECATED_NAME 121 -#define WARN_DEPRECATED_NOEXTERN 122 -#define WARN_DEPRECATED_NODEFAULT 123 -/* Unused since 4.1.0: #define WARN_DEPRECATED_TYPEMAP_LANG 124 */ -#define WARN_DEPRECATED_INPUT_FILE 125 -#define WARN_DEPRECATED_NESTED_WORKAROUND 126 - -/* -- Preprocessor -- */ - -#define WARN_PP_MISSING_FILE 201 -#define WARN_PP_EVALUATION 202 -#define WARN_PP_INCLUDEALL_IMPORTALL 203 -#define WARN_PP_CPP_WARNING 204 -#define WARN_PP_CPP_ERROR 205 -#define WARN_PP_UNEXPECTED_TOKENS 206 - -/* -- C/C++ Parser -- */ - -#define WARN_PARSE_CLASS_KEYWORD 301 -#define WARN_PARSE_REDEFINED 302 -#define WARN_PARSE_EXTEND_UNDEF 303 -#define WARN_PARSE_UNSUPPORTED_VALUE 304 -#define WARN_PARSE_BAD_VALUE 305 -#define WARN_PARSE_PRIVATE 306 -#define WARN_PARSE_BAD_DEFAULT 307 -#define WARN_PARSE_NAMESPACE_ALIAS 308 -#define WARN_PARSE_PRIVATE_INHERIT 309 -#define WARN_PARSE_TEMPLATE_REPEAT 310 -#define WARN_PARSE_TEMPLATE_PARTIAL 311 -#define WARN_PARSE_UNNAMED_NESTED_CLASS 312 -#define WARN_PARSE_UNDEFINED_EXTERN 313 -#define WARN_PARSE_KEYWORD 314 -#define WARN_PARSE_USING_UNDEF 315 -#define WARN_PARSE_MODULE_REPEAT 316 -#define WARN_PARSE_TEMPLATE_SP_UNDEF 317 -#define WARN_PARSE_TEMPLATE_AMBIG 318 -#define WARN_PARSE_NO_ACCESS 319 -#define WARN_PARSE_EXPLICIT_TEMPLATE 320 -#define WARN_PARSE_BUILTIN_NAME 321 -#define WARN_PARSE_REDUNDANT 322 -#define WARN_PARSE_REC_INHERITANCE 323 -#define WARN_PARSE_NESTED_TEMPLATE 324 -#define WARN_PARSE_NAMED_NESTED_CLASS 325 -#define WARN_PARSE_EXTEND_NAME 326 -#define WARN_PARSE_EXTERN_TEMPLATE 327 - -#define WARN_CPP11_LAMBDA 340 -#define WARN_CPP11_ALIAS_DECLARATION 341 /* redundant now */ -#define WARN_CPP11_ALIAS_TEMPLATE 342 /* redundant now */ -#define WARN_CPP11_VARIADIC_TEMPLATE 343 - -#define WARN_IGNORE_OPERATOR_NEW 350 /* new */ -#define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */ -#define WARN_IGNORE_OPERATOR_PLUS 352 /* + */ -#define WARN_IGNORE_OPERATOR_MINUS 353 /* - */ -#define WARN_IGNORE_OPERATOR_MUL 354 /* * */ -#define WARN_IGNORE_OPERATOR_DIV 355 /* / */ -#define WARN_IGNORE_OPERATOR_MOD 356 /* % */ -#define WARN_IGNORE_OPERATOR_XOR 357 /* ^ */ -#define WARN_IGNORE_OPERATOR_AND 358 /* & */ -#define WARN_IGNORE_OPERATOR_OR 359 /* | */ -#define WARN_IGNORE_OPERATOR_NOT 360 /* ~ */ -#define WARN_IGNORE_OPERATOR_LNOT 361 /* ! */ -#define WARN_IGNORE_OPERATOR_EQ 362 /* = */ -#define WARN_IGNORE_OPERATOR_LT 363 /* < */ -#define WARN_IGNORE_OPERATOR_GT 364 /* > */ -#define WARN_IGNORE_OPERATOR_PLUSEQ 365 /* += */ -#define WARN_IGNORE_OPERATOR_MINUSEQ 366 /* -= */ -#define WARN_IGNORE_OPERATOR_MULEQ 367 /* *= */ -#define WARN_IGNORE_OPERATOR_DIVEQ 368 /* /= */ -#define WARN_IGNORE_OPERATOR_MODEQ 369 /* %= */ -#define WARN_IGNORE_OPERATOR_XOREQ 370 /* ^= */ -#define WARN_IGNORE_OPERATOR_ANDEQ 371 /* &= */ -#define WARN_IGNORE_OPERATOR_OREQ 372 /* |= */ -#define WARN_IGNORE_OPERATOR_LSHIFT 373 /* << */ -#define WARN_IGNORE_OPERATOR_RSHIFT 374 /* >> */ -#define WARN_IGNORE_OPERATOR_LSHIFTEQ 375 /* <<= */ -#define WARN_IGNORE_OPERATOR_RSHIFTEQ 376 /* >>= */ -#define WARN_IGNORE_OPERATOR_EQUALTO 377 /* == */ -#define WARN_IGNORE_OPERATOR_NOTEQUAL 378 /* != */ -#define WARN_IGNORE_OPERATOR_LTEQUAL 379 /* <= */ -#define WARN_IGNORE_OPERATOR_GTEQUAL 380 /* >= */ -#define WARN_IGNORE_OPERATOR_LAND 381 /* && */ -#define WARN_IGNORE_OPERATOR_LOR 382 /* || */ -#define WARN_IGNORE_OPERATOR_PLUSPLUS 383 /* ++ */ -#define WARN_IGNORE_OPERATOR_MINUSMINUS 384 /* -- */ -#define WARN_IGNORE_OPERATOR_COMMA 385 /* , */ -#define WARN_IGNORE_OPERATOR_ARROWSTAR 386 /* ->* */ -#define WARN_IGNORE_OPERATOR_ARROW 387 /* -> */ -#define WARN_IGNORE_OPERATOR_CALL 388 /* () */ -#define WARN_IGNORE_OPERATOR_INDEX 389 /* [] */ -#define WARN_IGNORE_OPERATOR_UPLUS 390 /* + */ -#define WARN_IGNORE_OPERATOR_UMINUS 391 /* - */ -#define WARN_IGNORE_OPERATOR_UMUL 392 /* * */ -#define WARN_IGNORE_OPERATOR_UAND 393 /* & */ -#define WARN_IGNORE_OPERATOR_NEWARR 394 /* new [] */ -#define WARN_IGNORE_OPERATOR_DELARR 395 /* delete [] */ -#define WARN_IGNORE_OPERATOR_REF 396 /* operator *() */ -#define WARN_IGNORE_OPERATOR_LTEQUALGT 397 /* <=> */ - -/* please leave 350-399 free for WARN_IGNORE_OPERATOR_* */ - -/* -- Type system and typemaps -- */ - -#define WARN_TYPE_UNDEFINED_CLASS 401 -#define WARN_TYPE_INCOMPLETE 402 -#define WARN_TYPE_ABSTRACT 403 -#define WARN_TYPE_REDEFINED 404 -#define WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405 - -#define WARN_TYPEMAP_SOURCETARGET 450 /* No longer issued */ -#define WARN_TYPEMAP_CHARLEAK 451 -#define WARN_TYPEMAP_SWIGTYPE 452 /* No longer issued */ -#define WARN_TYPEMAP_APPLY_UNDEF 453 -#define WARN_TYPEMAP_SWIGTYPELEAK 454 -#define WARN_TYPEMAP_WCHARLEAK 455 - -#define WARN_TYPEMAP_IN_UNDEF 460 -#define WARN_TYPEMAP_OUT_UNDEF 461 -#define WARN_TYPEMAP_VARIN_UNDEF 462 -#define WARN_TYPEMAP_VAROUT_UNDEF 463 -#define WARN_TYPEMAP_CONST_UNDEF 464 -#define WARN_TYPEMAP_UNDEF 465 -#define WARN_TYPEMAP_VAR_UNDEF 466 -#define WARN_TYPEMAP_TYPECHECK 467 -#define WARN_TYPEMAP_THROW 468 -#define WARN_TYPEMAP_DIRECTORIN_UNDEF 469 -#define WARN_TYPEMAP_THREAD_UNSAFE 470 /* mostly used in directorout typemaps */ -#define WARN_TYPEMAP_DIRECTOROUT_UNDEF 471 -#define WARN_TYPEMAP_TYPECHECK_UNDEF 472 -#define WARN_TYPEMAP_DIRECTOROUT_PTR 473 -#define WARN_TYPEMAP_OUT_OPTIMAL_IGNORED 474 -#define WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE 475 -#define WARN_TYPEMAP_INITIALIZER_LIST 476 -#define WARN_TYPEMAP_DIRECTORTHROWS_UNDEF 477 - -/* -- Fragments -- */ -#define WARN_FRAGMENT_NOT_FOUND 490 - -/* -- General code generation -- */ - -#define WARN_LANG_OVERLOAD_DECL 501 -#define WARN_LANG_OVERLOAD_CONSTRUCT 502 -#define WARN_LANG_IDENTIFIER 503 -#define WARN_LANG_RETURN_TYPE 504 -#define WARN_LANG_VARARGS 505 -#define WARN_LANG_VARARGS_KEYWORD 506 -#define WARN_LANG_NATIVE_UNIMPL 507 -#define WARN_LANG_DEREF_SHADOW 508 -#define WARN_LANG_OVERLOAD_SHADOW 509 -#define WARN_LANG_FRIEND_IGNORE 510 -#define WARN_LANG_OVERLOAD_KEYWORD 511 -#define WARN_LANG_OVERLOAD_CONST 512 -#define WARN_LANG_CLASS_UNNAMED 513 -#define WARN_LANG_DIRECTOR_VDESTRUCT 514 -#define WARN_LANG_DISCARD_CONST 515 -#define WARN_LANG_OVERLOAD_IGNORED 516 -#define WARN_LANG_DIRECTOR_ABSTRACT 517 -#define WARN_LANG_PORTABILITY_FILENAME 518 -#define WARN_LANG_TEMPLATE_METHOD_IGNORE 519 -#define WARN_LANG_SMARTPTR_MISSING 520 -#define WARN_LANG_ILLEGAL_DESTRUCTOR 521 -#define WARN_LANG_EXTEND_CONSTRUCTOR 522 -#define WARN_LANG_EXTEND_DESTRUCTOR 523 -#define WARN_LANG_EXPERIMENTAL 524 -#define WARN_LANG_DIRECTOR_FINAL 525 -#define WARN_LANG_USING_NAME_DIFFERENT 526 - -/* -- Doxygen comments -- */ - -#define WARN_DOXYGEN_UNKNOWN_COMMAND 560 -#define WARN_DOXYGEN_UNEXPECTED_END_OF_COMMENT 561 -#define WARN_DOXYGEN_COMMAND_EXPECTED 562 -#define WARN_DOXYGEN_HTML_ERROR 563 -#define WARN_DOXYGEN_COMMAND_ERROR 564 -#define WARN_DOXYGEN_UNKNOWN_CHARACTER 565 -#define WARN_DOXYGEN_UNEXPECTED_ITERATOR_VALUE 566 - -/* -- Reserved (600-699) -- */ - -/* -- Language module specific warnings (700 - 899) -- */ - -/* Feel free to claim any number in this space that's not currently being used. Just make sure you - add an entry here */ - -#define WARN_D_TYPEMAP_CTYPE_UNDEF 700 -#define WARN_D_TYPEMAP_IMTYPE_UNDEF 701 -#define WARN_D_TYPEMAP_DTYPE_UNDEF 702 -#define WARN_D_MULTIPLE_INHERITANCE 703 -#define WARN_D_TYPEMAP_CLASSMOD_UNDEF 704 -#define WARN_D_TYPEMAP_DBODY_UNDEF 705 -#define WARN_D_TYPEMAP_DOUT_UNDEF 706 -#define WARN_D_TYPEMAP_DIN_UNDEF 707 -#define WARN_D_TYPEMAP_DDIRECTORIN_UNDEF 708 -#define WARN_D_TYPEMAP_DCONSTRUCTOR_UNDEF 709 -#define WARN_D_EXCODE_MISSING 710 -#define WARN_D_CANTHROW_MISSING 711 -#define WARN_D_NO_DIRECTORCONNECT_ATTR 712 -#define WARN_D_NAME_COLLISION 713 - -/* please leave 700-719 free for D */ - -#define WARN_SCILAB_TRUNCATED_NAME 720 - -/* please leave 720-739 free for Scilab */ - -#define WARN_PYTHON_INDENT_MISMATCH 740 - -/* please leave 740-749 free for Python */ - -#define WARN_R_MISSING_RTYPECHECK_TYPEMAP 750 - -/* please leave 750-759 free for R */ - -#define WARN_RUBY_WRONG_NAME 801 -#define WARN_RUBY_MULTIPLE_INHERITANCE 802 - -/* please leave 800-809 free for Ruby */ - -#define WARN_JAVA_TYPEMAP_JNI_UNDEF 810 -#define WARN_JAVA_TYPEMAP_JTYPE_UNDEF 811 -#define WARN_JAVA_TYPEMAP_JSTYPE_UNDEF 812 -#define WARN_JAVA_MULTIPLE_INHERITANCE 813 -#define WARN_JAVA_TYPEMAP_GETCPTR_UNDEF 814 -#define WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF 815 -#define WARN_JAVA_TYPEMAP_JAVABODY_UNDEF 816 -#define WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF 817 -#define WARN_JAVA_TYPEMAP_JAVAIN_UNDEF 818 -#define WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF 819 -#define WARN_JAVA_TYPEMAP_JAVADIRECTOROUT_UNDEF 820 -#define WARN_JAVA_TYPEMAP_INTERFACECODE_UNDEF 821 -#define WARN_JAVA_COVARIANT_RET 822 -#define WARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF 823 -#define WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC 824 -#define WARN_JAVA_NO_DIRECTORCONNECT_ATTR 825 -#define WARN_JAVA_NSPACE_WITHOUT_PACKAGE 826 -#define WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF 827 - -/* please leave 810-829 free for Java */ - -#define WARN_CSHARP_TYPEMAP_CTYPE_UNDEF 830 -#define WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF 831 -#define WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF 832 -#define WARN_CSHARP_MULTIPLE_INHERITANCE 833 -#define WARN_CSHARP_TYPEMAP_GETCPTR_UNDEF 834 -#define WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF 835 -#define WARN_CSHARP_TYPEMAP_CSBODY_UNDEF 836 -#define WARN_CSHARP_TYPEMAP_CSOUT_UNDEF 837 -#define WARN_CSHARP_TYPEMAP_CSIN_UNDEF 838 -#define WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF 839 -#define WARN_CSHARP_TYPEMAP_CSDIRECTOROUT_UNDEF 840 -#define WARN_CSHARP_TYPEMAP_INTERFACECODE_UNDEF 841 -#define WARN_CSHARP_COVARIANT_RET 842 -#define WARN_CSHARP_TYPEMAP_CSCONSTRUCT_UNDEF 843 -#define WARN_CSHARP_EXCODE 844 -#define WARN_CSHARP_CANTHROW 845 -#define WARN_CSHARP_NO_DIRECTORCONNECT_ATTR 846 -#define WARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF 847 - -/* please leave 830-849 free for C# */ - -/* 850-860 were used by Modula 3 (removed in SWIG 4.1.0) - avoid reusing for now */ - -#define WARN_PHP_MULTIPLE_INHERITANCE 870 -#define WARN_PHP_UNKNOWN_PRAGMA 871 -#define WARN_PHP_PUBLIC_BASE 872 - -/* please leave 870-889 free for PHP */ - -#define WARN_GO_NAME_CONFLICT 890 - -/* please leave 890-899 free for Go */ - -/* -- User defined warnings (900 - 999) -- */ - -#endif diff --git a/contrib/tools/swig/Source/Modules/README b/contrib/tools/swig/Source/Modules/README deleted file mode 100644 index 058779d227d..00000000000 --- a/contrib/tools/swig/Source/Modules/README +++ /dev/null @@ -1,9 +0,0 @@ -06/25/2002 - -This directory contains all of the SWIG language modules. Many of these -modules contain code that dates back to SWIG1.0. The module API has changed -a lot in the development releases so this is fairly messy. We're working on -cleaning it up, but you'll have to bear with us until it's done. - --- Dave - diff --git a/contrib/tools/swig/Source/Modules/allocate.cxx b/contrib/tools/swig/Source/Modules/allocate.cxx deleted file mode 100644 index 0e1262f8390..00000000000 --- a/contrib/tools/swig/Source/Modules/allocate.cxx +++ /dev/null @@ -1,971 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * allocate.cxx - * - * This module tries to figure out which classes and structures support - * default constructors and destructors in C++. There are several rules that - * define this behavior including pure abstract methods, private sections, - * and non-default constructors in base classes. See the ARM or - * Doc/Manual/SWIGPlus.html for details. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" - -static int virtual_elimination_mode = 0; /* set to 0 on default */ - -/* Set virtual_elimination_mode */ -void Wrapper_virtual_elimination_mode_set(int flag) { - virtual_elimination_mode = flag; -} - -/* Helper function to assist with abstract class checking. - This is a major hack. Sorry. */ - -extern "C" { - static String *search_decl = 0; /* Declarator being searched */ - static int check_implemented(Node *n) { - String *decl; - if (!n) - return 0; - while (n) { - if (Strcmp(nodeType(n), "cdecl") == 0) { - decl = Getattr(n, "decl"); - if (SwigType_isfunction(decl)) { - SwigType *decl1 = SwigType_typedef_resolve_all(decl); - SwigType *decl2 = SwigType_pop_function(decl1); - if (Strcmp(decl2, search_decl) == 0) { - if (!GetFlag(n, "abstract")) { - Delete(decl1); - Delete(decl2); - return 1; - } - } - Delete(decl1); - Delete(decl2); - } - } - n = Getattr(n, "csym:nextSibling"); - } - return 0; - } -} - -class Allocate:public Dispatcher { - Node *inclass; - int extendmode; - - /* Checks if a function, n, is the same as any in the base class, ie if the method is polymorphic. - * Also checks for methods which will be hidden (ie a base has an identical non-virtual method). - * Both methods must have public access for a match to occur. */ - int function_is_defined_in_bases(Node *n, Node *bases) { - - if (!bases) - return 0; - - String *this_decl = Getattr(n, "decl"); - if (!this_decl) - return 0; - - String *name = Getattr(n, "name"); - String *this_type = Getattr(n, "type"); - String *resolved_decl = SwigType_typedef_resolve_all(this_decl); - - // Search all base classes for methods with same signature - for (int i = 0; i < Len(bases); i++) { - Node *b = Getitem(bases, i); - Node *base = firstChild(b); - while (base) { - if (Strcmp(nodeType(base), "extend") == 0) { - // Loop through all the %extend methods - Node *extend = firstChild(base); - while (extend) { - if (function_is_defined_in_bases_seek(n, b, extend, this_decl, name, this_type, resolved_decl)) { - Delete(resolved_decl); - return 1; - } - extend = nextSibling(extend); - } - } else if (Strcmp(nodeType(base), "using") == 0) { - // Loop through all the using declaration methods - Node *usingdecl = firstChild(base); - while (usingdecl) { - if (function_is_defined_in_bases_seek(n, b, usingdecl, this_decl, name, this_type, resolved_decl)) { - Delete(resolved_decl); - return 1; - } - usingdecl = nextSibling(usingdecl); - } - } else { - // normal methods - if (function_is_defined_in_bases_seek(n, b, base, this_decl, name, this_type, resolved_decl)) { - Delete(resolved_decl); - return 1; - } - } - base = nextSibling(base); - } - } - Delete(resolved_decl); - resolved_decl = 0; - for (int j = 0; j < Len(bases); j++) { - Node *b = Getitem(bases, j); - if (function_is_defined_in_bases(n, Getattr(b, "allbases"))) - return 1; - } - return 0; - } - - /* Helper function for function_is_defined_in_bases */ - int function_is_defined_in_bases_seek(Node *n, Node *b, Node *base, String *this_decl, String *name, String *this_type, String *resolved_decl) { - - String *base_decl = Getattr(base, "decl"); - SwigType *base_type = Getattr(base, "type"); - if (base_decl && base_type) { - if (checkAttribute(base, "name", name) && !GetFlag(b, "feature:ignore") /* whole class is ignored */ ) { - if (SwigType_isfunction(resolved_decl) && SwigType_isfunction(base_decl)) { - // We have found a method that has the same name as one in a base class - bool covariant_returntype = false; - bool returntype_match = Strcmp(base_type, this_type) == 0 ? true : false; - bool decl_match = Strcmp(base_decl, this_decl) == 0 ? true : false; - if (returntype_match && decl_match) { - // Exact match - we have found a method with identical signature - // No typedef resolution was done, but skipping it speeds things up slightly - } else { - // Either we have: - // 1) matching methods but are one of them uses a different typedef (return type or parameter) to the one in base class' method - // 2) matching polymorphic methods with covariant return type - // 3) a non-matching method (ie an overloaded method of some sort) - // 4) a matching method which is not polymorphic, ie it hides the base class' method - - // Check if fully resolved return types match (including - // covariant return types) - if (!returntype_match) { - String *this_returntype = function_return_type(n); - String *base_returntype = function_return_type(base); - returntype_match = Strcmp(this_returntype, base_returntype) == 0 ? true : false; - if (!returntype_match) { - covariant_returntype = SwigType_issubtype(this_returntype, base_returntype) ? true : false; - returntype_match = covariant_returntype; - } - Delete(this_returntype); - Delete(base_returntype); - } - // The return types must match at this point, for the whole method to match - if (returntype_match && !decl_match) { - // Now need to check the parameter list - // First do an inexpensive parameter count - ParmList *this_parms = Getattr(n, "parms"); - ParmList *base_parms = Getattr(base, "parms"); - if (ParmList_len(this_parms) == ParmList_len(base_parms)) { - // Number of parameters are the same, now check that all the parameters match - SwigType *base_fn = NewString(""); - SwigType *this_fn = NewString(""); - SwigType_add_function(base_fn, base_parms); - SwigType_add_function(this_fn, this_parms); - base_fn = SwigType_typedef_resolve_all(base_fn); - this_fn = SwigType_typedef_resolve_all(this_fn); - if (Strcmp(base_fn, this_fn) == 0) { - // Finally check that the qualifiers match - int base_qualifier = SwigType_isqualifier(resolved_decl); - int this_qualifier = SwigType_isqualifier(base_decl); - if (base_qualifier == this_qualifier) { - decl_match = true; - } - } - Delete(base_fn); - Delete(this_fn); - } - } - } - //Printf(stderr,"look %s %s %d %d\n",base_decl, this_decl, returntype_match, decl_match); - - if (decl_match && returntype_match) { - // Found an identical method in the base class - bool this_wrapping_protected_members = is_member_director(n) ? true : false; // This should really check for dirprot rather than just being a director method - bool base_wrapping_protected_members = is_member_director(base) ? true : false; // This should really check for dirprot rather than just being a director method - bool both_have_public_access = is_public(n) && is_public(base); - bool both_have_protected_access = (is_protected(n) && this_wrapping_protected_members) && (is_protected(base) && base_wrapping_protected_members); - bool both_have_private_access = is_private(n) && is_private(base); - if (checkAttribute(base, "storage", "virtual")) { - // Found a polymorphic method. - // Mark the polymorphic method, in case the virtual keyword was not used. - Setattr(n, "storage", "virtual"); - if (!GetFlag(b, "feature:interface")) { // interface implementation neither hides nor overrides - if (both_have_public_access || both_have_protected_access) { - if (!is_non_public_base(inclass, b)) - Setattr(n, "override", base); // Note C# definition of override, ie access must be the same - } - else if (!both_have_private_access) { - // Different access - if (this_wrapping_protected_members || base_wrapping_protected_members) - if (!is_non_public_base(inclass, b)) - Setattr(n, "hides", base); // Note C# definition of hiding, ie hidden if access is different - } - } - // Try and find the most base's covariant return type - SwigType *most_base_covariant_type = Getattr(base, "covariant"); - if (!most_base_covariant_type && covariant_returntype) - most_base_covariant_type = function_return_type(base, false); - - if (!most_base_covariant_type) { - // Eliminate the derived virtual method. - if (virtual_elimination_mode && !is_member_director(n)) - if (both_have_public_access) - if (!is_non_public_base(inclass, b)) - if (!Swig_symbol_isoverloaded(n)) { - // Don't eliminate if an overloaded method as this hides the method - // in the scripting languages: the dispatch function will hide the base method if ignored. - SetFlag(n, "feature:ignore"); - } - } else { - // Some languages need to know about covariant return types - Setattr(n, "covariant", most_base_covariant_type); - } - - } else { - // Found an identical method in the base class, but it is not polymorphic. - if (both_have_public_access || both_have_protected_access) - if (!is_non_public_base(inclass, b)) - Setattr(n, "hides", base); - } - if (both_have_public_access || both_have_protected_access) - return 1; - } - } - } - } - return 0; - } - - /* Determines whether the base class, b, is in the list of private - * or protected base classes for class n. */ - bool is_non_public_base(Node *n, Node *b) { - bool non_public_base = false; - Node *bases = Getattr(n, "privatebases"); - if (bases) { - for (int i = 0; i < Len(bases); i++) { - Node *base = Getitem(bases, i); - if (base == b) - non_public_base = true; - } - } - bases = Getattr(n, "protectedbases"); - if (bases) { - for (int i = 0; i < Len(bases); i++) { - Node *base = Getitem(bases, i); - if (base == b) - non_public_base = true; - } - } - return non_public_base; - } - - /* Returns the return type for a function. The node n should be a function. - If resolve is true the fully returned type is fully resolved. - Caller is responsible for deleting returned string. */ - String *function_return_type(Node *n, bool resolve = true) { - String *decl = Getattr(n, "decl"); - SwigType *type = Getattr(n, "type"); - String *ty = NewString(type); - SwigType_push(ty, decl); - if (SwigType_isqualifier(ty)) - Delete(SwigType_pop(ty)); - Delete(SwigType_pop_function(ty)); - if (resolve) { - String *unresolved = ty; - ty = SwigType_typedef_resolve_all(unresolved); - Delete(unresolved); - } - return ty; - } - - /* Checks if a class member is the same as inherited from the class bases */ - int class_member_is_defined_in_bases(Node *member, Node *classnode) { - Node *bases; /* bases is the closest ancestors of classnode */ - int defined = 0; - - bases = Getattr(classnode, "allbases"); - if (!bases) - return 0; - - { - int old_mode = virtual_elimination_mode; - if (is_member_director(classnode, member)) - virtual_elimination_mode = 0; - - if (function_is_defined_in_bases(member, bases)) { - defined = 1; - } - - virtual_elimination_mode = old_mode; - } - - if (defined) - return 1; - else - return 0; - } - - /* Checks to see if a class is abstract through inheritance, - and saves the first node that seems to be abstract. - */ - int is_abstract_inherit(Node *n, Node *base = 0, int first = 0) { - if (!first && (base == n)) - return 0; - if (!base) { - /* Root node */ - Symtab *stab = Getattr(n, "symtab"); /* Get symbol table for node */ - Symtab *oldtab = Swig_symbol_setscope(stab); - int ret = is_abstract_inherit(n, n, 1); - Swig_symbol_setscope(oldtab); - return ret; - } - List *abstracts = Getattr(base, "abstracts"); - if (abstracts) { - int dabstract = 0; - int len = Len(abstracts); - for (int i = 0; i < len; i++) { - Node *nn = Getitem(abstracts, i); - String *name = Getattr(nn, "name"); - if (!name) - continue; - if (Strchr(name, '~')) - continue; /* Don't care about destructors */ - String *base_decl = Getattr(nn, "decl"); - if (base_decl) - base_decl = SwigType_typedef_resolve_all(base_decl); - if (SwigType_isfunction(base_decl)) - search_decl = SwigType_pop_function(base_decl); - Node *dn = Swig_symbol_clookup_local_check(name, 0, check_implemented); - Delete(search_decl); - Delete(base_decl); - - if (!dn) { - List *nabstracts = Getattr(n, "abstracts"); - if (!nabstracts) { - nabstracts = NewList(); - Setattr(n, "abstracts", nabstracts); - Delete(nabstracts); - } - Append(nabstracts, nn); - if (!Getattr(n, "abstracts:firstnode")) { - Setattr(n, "abstracts:firstnode", nn); - } - dabstract = base != n; - } - } - if (dabstract) - return 1; - } - List *bases = Getattr(base, "allbases"); - if (!bases) - return 0; - for (int i = 0; i < Len(bases); i++) { - if (is_abstract_inherit(n, Getitem(bases, i))) { - return 1; - } - } - return 0; - } - - - /* Grab methods used by smart pointers */ - - List *smart_pointer_methods(Node *cls, List *methods, int isconst, String *classname = 0) { - if (!methods) { - methods = NewList(); - } - - Node *c = firstChild(cls); - - while (c) { - if (Getattr(c, "error") || GetFlag(c, "feature:ignore")) { - c = nextSibling(c); - continue; - } - if (!isconst && (Strcmp(nodeType(c), "extend") == 0)) { - methods = smart_pointer_methods(c, methods, isconst, Getattr(cls, "name")); - } else if (Strcmp(nodeType(c), "cdecl") == 0) { - if (!GetFlag(c, "feature:ignore")) { - String *storage = Getattr(c, "storage"); - if (!((Cmp(storage, "typedef") == 0)) - && !((Cmp(storage, "friend") == 0))) { - String *name = Getattr(c, "name"); - String *symname = Getattr(c, "sym:name"); - Node *e = Swig_symbol_clookup_local(name, 0); - if (e && is_public(e) && !GetFlag(e, "feature:ignore") && (Cmp(symname, Getattr(e, "sym:name")) == 0)) { - Swig_warning(WARN_LANG_DEREF_SHADOW, Getfile(e), Getline(e), "Declaration of '%s' shadows declaration accessible via operator->(),\n", name); - Swig_warning(WARN_LANG_DEREF_SHADOW, Getfile(c), Getline(c), "previous declaration of '%s'.\n", name); - } else { - /* Make sure node with same name doesn't already exist */ - int k; - int match = 0; - for (k = 0; k < Len(methods); k++) { - e = Getitem(methods, k); - if (Cmp(symname, Getattr(e, "sym:name")) == 0) { - match = 1; - break; - } - if (!Getattr(e, "sym:name") && (Cmp(name, Getattr(e, "name")) == 0)) { - match = 1; - break; - } - } - if (!match) { - Node *cc = c; - while (cc) { - Node *cp = cc; - if (classname) { - Setattr(cp, "extendsmartclassname", classname); - } - Setattr(cp, "allocate:smartpointeraccess", "1"); - /* If constant, we have to be careful */ - if (isconst) { - SwigType *decl = Getattr(cp, "decl"); - if (decl) { - if (SwigType_isfunction(decl)) { /* If method, we only add if it's a const method */ - if (SwigType_isconst(decl)) { - Append(methods, cp); - } - } else { - Append(methods, cp); - } - } else { - Append(methods, cp); - } - } else { - Append(methods, cp); - } - cc = Getattr(cc, "sym:nextSibling"); - } - } - } - } - } - } - - c = nextSibling(c); - } - /* Look for methods in base classes */ - { - Node *bases = Getattr(cls, "bases"); - int k; - for (k = 0; k < Len(bases); k++) { - smart_pointer_methods(Getitem(bases, k), methods, isconst); - } - } - /* Remove protected/private members */ - { - for (int i = 0; i < Len(methods);) { - Node *n = Getitem(methods, i); - if (!is_public(n)) { - Delitem(methods, i); - continue; - } - i++; - } - } - return methods; - } - - void mark_exception_classes(ParmList *p) { - while (p) { - SwigType *ty = Getattr(p, "type"); - SwigType *t = SwigType_typedef_resolve_all(ty); - if (SwigType_isreference(t) || SwigType_ispointer(t) || SwigType_isarray(t)) { - Delete(SwigType_pop(t)); - } - Node *c = Swig_symbol_clookup(t, 0); - if (c) { - if (!GetFlag(c, "feature:exceptionclass")) { - SetFlag(c, "feature:exceptionclass"); - } - } - p = nextSibling(p); - Delete(t); - } - } - - - void process_exceptions(Node *n) { - ParmList *catchlist = 0; - /* - the "catchlist" attribute is used to emit the block - - try {$action;} - catch <list of catches>; - - in emit.cxx - - and is either constructed from the "feature:catches" feature - or copied from the node "throws" list. - */ - String *scatchlist = Getattr(n, "feature:catches"); - if (scatchlist) { - catchlist = Swig_cparse_parms(scatchlist, n); - if (catchlist) { - Setattr(n, "catchlist", catchlist); - mark_exception_classes(catchlist); - Delete(catchlist); - } - } - ParmList *throws = Getattr(n, "throws"); - if (throws) { - /* if there is no explicit catchlist, we catch everything in the throws list */ - if (!catchlist) { - Setattr(n, "catchlist", throws); - } - mark_exception_classes(throws); - } - } - -public: -Allocate(): - inclass(NULL), extendmode(0) { - } - - virtual int top(Node *n) { - cplus_mode = PUBLIC; - inclass = 0; - extendmode = 0; - emit_children(n); - return SWIG_OK; - } - - virtual int importDirective(Node *n) { - return emit_children(n); - } - virtual int includeDirective(Node *n) { - return emit_children(n); - } - virtual int externDeclaration(Node *n) { - return emit_children(n); - } - virtual int namespaceDeclaration(Node *n) { - return emit_children(n); - } - virtual int extendDirective(Node *n) { - extendmode = 1; - emit_children(n); - extendmode = 0; - return SWIG_OK; - } - - virtual int classDeclaration(Node *n) { - Symtab *symtab = Swig_symbol_current(); - Swig_symbol_setscope(Getattr(n, "symtab")); - save_value<Node*> oldInclass(inclass); - save_value<AccessMode> oldAcessMode(cplus_mode); - save_value<int> oldExtendMode(extendmode); - if (Getattr(n, "template")) - extendmode = 0; - if (!CPlusPlus) { - /* Always have default constructors/destructors in C */ - Setattr(n, "allocate:default_constructor", "1"); - Setattr(n, "allocate:default_destructor", "1"); - } - - if (Getattr(n, "allocate:visit")) - return SWIG_OK; - Setattr(n, "allocate:visit", "1"); - - /* Always visit base classes first */ - { - List *bases = Getattr(n, "bases"); - if (bases) { - for (int i = 0; i < Len(bases); i++) { - Node *b = Getitem(bases, i); - classDeclaration(b); - } - } - } - inclass = n; - String *kind = Getattr(n, "kind"); - if (Strcmp(kind, "class") == 0) { - cplus_mode = PRIVATE; - } else { - cplus_mode = PUBLIC; - } - - emit_children(n); - - /* Check if the class is abstract via inheritance. This might occur if a class didn't have - any pure virtual methods of its own, but it didn't implement all of the pure methods in - a base class */ - if (!Getattr(n, "abstracts") && is_abstract_inherit(n)) { - if (((Getattr(n, "allocate:public_constructor") || (!GetFlag(n, "feature:nodefault") && !Getattr(n, "allocate:has_constructor"))))) { - if (!GetFlag(n, "feature:notabstract")) { - Node *na = Getattr(n, "abstracts:firstnode"); - if (na) { - Swig_warning(WARN_TYPE_ABSTRACT, Getfile(n), Getline(n), - "Class '%s' might be abstract, " "no constructors generated,\n", SwigType_namestr(Getattr(n, "name"))); - Swig_warning(WARN_TYPE_ABSTRACT, Getfile(na), Getline(na), "Method %s might not be implemented.\n", Swig_name_decl(na)); - if (!Getattr(n, "abstracts")) { - List *abstracts = NewList(); - Append(abstracts, na); - Setattr(n, "abstracts", abstracts); - Delete(abstracts); - } - } - } - } - } - - if (!Getattr(n, "allocate:has_constructor")) { - /* No constructor is defined. We need to check a few things */ - /* If class is abstract. No default constructor. Sorry */ - if (Getattr(n, "abstracts")) { - Delattr(n, "allocate:default_constructor"); - } - if (!Getattr(n, "allocate:default_constructor")) { - /* Check base classes */ - List *bases = Getattr(n, "allbases"); - int allows_default = 1; - - for (int i = 0; i < Len(bases); i++) { - Node *n = Getitem(bases, i); - /* If base class does not allow default constructor, we don't allow it either */ - if (!Getattr(n, "allocate:default_constructor") && (!Getattr(n, "allocate:default_base_constructor"))) { - allows_default = 0; - } - } - if (allows_default) { - Setattr(n, "allocate:default_constructor", "1"); - } - } - } - if (!Getattr(n, "allocate:has_copy_constructor")) { - if (Getattr(n, "abstracts")) { - Delattr(n, "allocate:copy_constructor"); - } - if (!Getattr(n, "allocate:copy_constructor")) { - /* Check base classes */ - List *bases = Getattr(n, "allbases"); - int allows_copy = 1; - - for (int i = 0; i < Len(bases); i++) { - Node *n = Getitem(bases, i); - /* If base class does not allow copy constructor, we don't allow it either */ - if (!Getattr(n, "allocate:copy_constructor") && (!Getattr(n, "allocate:copy_base_constructor"))) { - allows_copy = 0; - } - } - if (allows_copy) { - Setattr(n, "allocate:copy_constructor", "1"); - } - } - } - - if (!Getattr(n, "allocate:has_destructor")) { - /* No destructor was defined */ - List *bases = Getattr(n, "allbases"); - int allows_destruct = 1; - - for (int i = 0; i < Len(bases); i++) { - Node *n = Getitem(bases, i); - /* If base class does not allow default destructor, we don't allow it either */ - if (!Getattr(n, "allocate:default_destructor") && (!Getattr(n, "allocate:default_base_destructor"))) { - allows_destruct = 0; - } - } - if (allows_destruct) { - Setattr(n, "allocate:default_destructor", "1"); - } - } - - if (!Getattr(n, "allocate:has_assign")) { - /* No assignment operator was defined */ - List *bases = Getattr(n, "allbases"); - int allows_assign = 1; - - for (int i = 0; i < Len(bases); i++) { - Node *n = Getitem(bases, i); - /* If base class does not allow assignment, we don't allow it either */ - if (Getattr(n, "allocate:has_assign")) { - allows_assign = !Getattr(n, "allocate:noassign"); - } - } - if (!allows_assign) { - Setattr(n, "allocate:noassign", "1"); - } - } - - if (!Getattr(n, "allocate:has_new")) { - /* No new operator was defined */ - List *bases = Getattr(n, "allbases"); - int allows_new = 1; - - for (int i = 0; i < Len(bases); i++) { - Node *n = Getitem(bases, i); - /* If base class does not allow new operator, we don't allow it either */ - if (Getattr(n, "allocate:has_new")) { - allows_new = !Getattr(n, "allocate:nonew"); - } - } - if (!allows_new) { - Setattr(n, "allocate:nonew", "1"); - } - } - - /* Check if base classes allow smart pointers, but might be hidden */ - if (!Getattr(n, "allocate:smartpointer")) { - Node *sp = Swig_symbol_clookup("operator ->", 0); - if (sp) { - /* Look for parent */ - Node *p = parentNode(sp); - if (Strcmp(nodeType(p), "extend") == 0) { - p = parentNode(p); - } - if (Strcmp(nodeType(p), "class") == 0) { - if (GetFlag(p, "feature:ignore")) { - Setattr(n, "allocate:smartpointer", Getattr(p, "allocate:smartpointer")); - } - } - } - } - - Swig_interface_propagate_methods(n); - - /* Only care about default behavior. Remove temporary values */ - Setattr(n, "allocate:visit", "1"); - Swig_symbol_setscope(symtab); - return SWIG_OK; - } - - virtual int accessDeclaration(Node *n) { - String *kind = Getattr(n, "kind"); - if (Cmp(kind, "public") == 0) { - cplus_mode = PUBLIC; - } else if (Cmp(kind, "private") == 0) { - cplus_mode = PRIVATE; - } else if (Cmp(kind, "protected") == 0) { - cplus_mode = PROTECTED; - } - return SWIG_OK; - } - - virtual int usingDeclaration(Node *n) { - - Node *c = 0; - for (c = firstChild(n); c; c = nextSibling(c)) { - if (Strcmp(nodeType(c), "cdecl") == 0) { - process_exceptions(c); - - if (inclass) - class_member_is_defined_in_bases(c, inclass); - } - } - - return SWIG_OK; - } - - virtual int cDeclaration(Node *n) { - - process_exceptions(n); - - if (inclass) { - /* check whether the member node n is defined in class node in class's bases */ - class_member_is_defined_in_bases(n, inclass); - - /* Check to see if this is a static member or not. If so, we add an attribute - cplus:staticbase that saves the current class */ - - if (Swig_storage_isstatic(n)) { - Setattr(n, "cplus:staticbase", inclass); - } else if (Cmp(Getattr(n, "kind"), "variable") == 0) { - /* Check member variable to determine whether assignment is valid */ - if (SwigType_isreference(Getattr(n, "type"))) { - /* Can't assign a class with reference member data */ - Setattr(inclass, "allocate:noassign", "1"); - } - } - - String *name = Getattr(n, "name"); - if (cplus_mode != PUBLIC) { - if (Strcmp(name, "operator =") == 0) { - /* Look for a private assignment operator */ - if (!GetFlag(n, "deleted")) - Setattr(inclass, "allocate:has_assign", "1"); - Setattr(inclass, "allocate:noassign", "1"); - } else if (Strcmp(name, "operator new") == 0) { - /* Look for a private new operator */ - if (!GetFlag(n, "deleted")) - Setattr(inclass, "allocate:has_new", "1"); - Setattr(inclass, "allocate:nonew", "1"); - } - } else { - if (Strcmp(name, "operator =") == 0) { - if (!GetFlag(n, "deleted")) - Setattr(inclass, "allocate:has_assign", "1"); - else - Setattr(inclass, "allocate:noassign", "1"); - } else if (Strcmp(name, "operator new") == 0) { - if (!GetFlag(n, "deleted")) - Setattr(inclass, "allocate:has_new", "1"); - else - Setattr(inclass, "allocate:nonew", "1"); - } - /* Look for smart pointer operator */ - if ((Strcmp(name, "operator ->") == 0) && (!GetFlag(n, "feature:ignore"))) { - /* Look for version with no parameters */ - Node *sn = n; - while (sn) { - if (!Getattr(sn, "parms")) { - SwigType *type = SwigType_typedef_resolve_all(Getattr(sn, "type")); - SwigType_push(type, Getattr(sn, "decl")); - Delete(SwigType_pop_function(type)); - SwigType *base = SwigType_base(type); - Node *sc = Swig_symbol_clookup(base, 0); - if ((sc) && (Strcmp(nodeType(sc), "class") == 0)) { - if (SwigType_check_decl(type, "p.")) { - /* Need to check if type is a const pointer */ - int isconst = 0; - Delete(SwigType_pop(type)); - if (SwigType_isconst(type)) { - isconst = !Getattr(inclass, "allocate:smartpointermutable"); - Setattr(inclass, "allocate:smartpointerconst", "1"); - } - else { - Setattr(inclass, "allocate:smartpointermutable", "1"); - } - List *methods = smart_pointer_methods(sc, 0, isconst); - Setattr(inclass, "allocate:smartpointer", methods); - Setattr(inclass, "allocate:smartpointerpointeeclassname", Getattr(sc, "name")); - } else { - /* Hmmm. The return value is not a pointer. If the type is a value - or reference. We're going to chase it to see if another operator->() - can be found */ - if ((SwigType_check_decl(type, "")) || (SwigType_check_decl(type, "r."))) { - Node *nn = Swig_symbol_clookup("operator ->", Getattr(sc, "symtab")); - if (nn) { - Delete(base); - Delete(type); - sn = nn; - continue; - } - } - } - } - Delete(base); - Delete(type); - break; - } - } - } - } - } - return SWIG_OK; - } - - virtual int constructorDeclaration(Node *n) { - if (!inclass) - return SWIG_OK; - Parm *parms = Getattr(n, "parms"); - - process_exceptions(n); - if (!extendmode) { - if (!ParmList_numrequired(parms)) { - /* Class does define a default constructor */ - /* However, we had better see where it is defined */ - if (cplus_mode == PUBLIC) { - Setattr(inclass, "allocate:default_constructor", "1"); - } else if (cplus_mode == PROTECTED) { - Setattr(inclass, "allocate:default_base_constructor", "1"); - } - } - /* Class defines some kind of constructor. May or may not be public */ - Setattr(inclass, "allocate:has_constructor", "1"); - if (cplus_mode == PUBLIC) { - Setattr(inclass, "allocate:public_constructor", "1"); - } - } else { - Setattr(inclass, "allocate:has_constructor", "1"); - Setattr(inclass, "allocate:public_constructor", "1"); - } - - - /* See if this is a copy constructor */ - if (parms && (ParmList_numrequired(parms) == 1)) { - /* Look for a few cases. X(const X &), X(X &), X(X *) */ - int copy_constructor = 0; - SwigType *type = Getattr(inclass, "name"); - String *tn = NewStringf("r.q(const).%s", type); - String *cc = SwigType_typedef_resolve_all(tn); - SwigType *rt = SwigType_typedef_resolve_all(Getattr(parms, "type")); - if (SwigType_istemplate(type)) { - String *tmp = Swig_symbol_template_deftype(cc, 0); - Delete(cc); - cc = tmp; - tmp = Swig_symbol_template_deftype(rt, 0); - Delete(rt); - rt = tmp; - } - if (Strcmp(cc, rt) == 0) { - copy_constructor = 1; - } else { - Delete(cc); - cc = NewStringf("r.%s", Getattr(inclass, "name")); - if (Strcmp(cc, Getattr(parms, "type")) == 0) { - copy_constructor = 1; - } else { - Delete(cc); - cc = NewStringf("p.%s", Getattr(inclass, "name")); - String *ty = SwigType_strip_qualifiers(Getattr(parms, "type")); - if (Strcmp(cc, ty) == 0) { - copy_constructor = 1; - } - Delete(ty); - } - } - Delete(cc); - Delete(rt); - Delete(tn); - - if (copy_constructor) { - Setattr(n, "copy_constructor", "1"); - Setattr(inclass, "allocate:has_copy_constructor", "1"); - if (cplus_mode == PUBLIC) { - Setattr(inclass, "allocate:copy_constructor", "1"); - } else if (cplus_mode == PROTECTED) { - Setattr(inclass, "allocate:copy_base_constructor", "1"); - } - } - } - return SWIG_OK; - } - - virtual int destructorDeclaration(Node *n) { - (void) n; - if (!inclass) - return SWIG_OK; - if (!extendmode) { - Setattr(inclass, "allocate:has_destructor", "1"); - if (cplus_mode == PUBLIC) { - Setattr(inclass, "allocate:default_destructor", "1"); - } else if (cplus_mode == PROTECTED) { - Setattr(inclass, "allocate:default_base_destructor", "1"); - } else if (cplus_mode == PRIVATE) { - Setattr(inclass, "allocate:private_destructor", "1"); - } - } else { - Setattr(inclass, "allocate:has_destructor", "1"); - Setattr(inclass, "allocate:default_destructor", "1"); - } - return SWIG_OK; - } -}; - -void Swig_default_allocators(Node *n) { - if (!n) - return; - Allocate *a = new Allocate; - a->top(n); - delete a; -} diff --git a/contrib/tools/swig/Source/Modules/contract.cxx b/contrib/tools/swig/Source/Modules/contract.cxx deleted file mode 100644 index dfc85ebe761..00000000000 --- a/contrib/tools/swig/Source/Modules/contract.cxx +++ /dev/null @@ -1,358 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * contract.cxx - * - * Support for Wrap by Contract in SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" - -/* Contract structure. This holds rules about the different kinds of contract sections - and their combination rules */ - -struct contract { - const char *section; - const char *combiner; -}; -/* Contract rules. This table defines what contract sections are recognized as well as - how contracts are to combined via inheritance */ - -static contract Rules[] = { - {"require:", "&&"}, - {"ensure:", "||"}, - {NULL, NULL} -}; - -/* ---------------------------------------------------------------------------- - * class Contracts: - * - * This class defines the functions that need to be used in - * "wrap by contract" module. - * ------------------------------------------------------------------------- */ - -class Contracts:public Dispatcher { - String *make_expression(String *s, Node *n); - void substitute_parms(String *s, ParmList *p, int method); -public: - Hash *ContractSplit(Node *n); - int emit_contract(Node *n, int method); - int cDeclaration(Node *n); - int constructorDeclaration(Node *n); - int externDeclaration(Node *n); - int extendDirective(Node *n); - int importDirective(Node *n); - int includeDirective(Node *n); - int namespaceDeclaration(Node *n); - int classDeclaration(Node *n); - virtual int top(Node *n); -}; - -static int Contract_Mode = 0; /* contract option */ -static int InClass = 0; /* Parsing C++ or not */ -static int InConstructor = 0; -static Node *CurrentClass = 0; - -/* Set the contract mode, default is 0 (not open) */ -/* Normally set in main.cxx, when get the "-contracts" option */ -void Swig_contract_mode_set(int flag) { - Contract_Mode = flag; -} - -/* Get the contract mode */ -int Swig_contract_mode_get() { - return Contract_Mode; -} - -/* Apply contracts */ -void Swig_contracts(Node *n) { - - Contracts *a = new Contracts; - a->top(n); - delete a; -} - -/* Split the whole contract into preassertion, postassertion and others */ -Hash *Contracts::ContractSplit(Node *n) { - - String *contract = Getattr(n, "feature:contract"); - Hash *result; - if (!contract) - return NULL; - - result = NewHash(); - String *current_section = NewString(""); - const char *current_section_name = Rules[0].section; - List *l = SplitLines(contract); - - Iterator i; - for (i = First(l); i.item; i = Next(i)) { - int found = 0; - if (Strchr(i.item, '{')) - continue; - if (Strchr(i.item, '}')) - continue; - for (int j = 0; Rules[j].section; j++) { - if (Strstr(i.item, Rules[j].section)) { - if (Len(current_section)) { - Setattr(result, current_section_name, current_section); - current_section = Getattr(result, Rules[j].section); - if (!current_section) - current_section = NewString(""); - } - current_section_name = Rules[j].section; - found = 1; - break; - } - } - if (!found) - Append(current_section, i.item); - } - if (Len(current_section)) - Setattr(result, current_section_name, current_section); - return result; -} - -/* This function looks in base classes and collects contracts found */ -void inherit_contracts(Node *c, Node *n, Hash *contracts, Hash *messages) { - - Node *b, *temp; - String *name, *type, *local_decl, *base_decl; - List *bases; - int found = 0; - - bases = Getattr(c, "bases"); - if (!bases) - return; - - name = Getattr(n, "name"); - type = Getattr(n, "type"); - local_decl = Getattr(n, "decl"); - if (local_decl) { - local_decl = SwigType_typedef_resolve_all(local_decl); - } else { - return; - } - /* Width first search */ - for (int i = 0; i < Len(bases); i++) { - b = Getitem(bases, i); - temp = firstChild(b); - while (temp) { - base_decl = Getattr(temp, "decl"); - if (base_decl) { - base_decl = SwigType_typedef_resolve_all(base_decl); - if ((checkAttribute(temp, "storage", "virtual")) && - (checkAttribute(temp, "name", name)) && (checkAttribute(temp, "type", type)) && (!Strcmp(local_decl, base_decl))) { - /* Yes, match found. */ - Hash *icontracts = Getattr(temp, "contract:rules"); - Hash *imessages = Getattr(temp, "contract:messages"); - found = 1; - if (icontracts && imessages) { - /* Add inherited contracts and messages to the contract rules above */ - int j = 0; - for (j = 0; Rules[j].section; j++) { - String *t = Getattr(contracts, Rules[j].section); - String *s = Getattr(icontracts, Rules[j].section); - if (s) { - if (t) { - Insert(t, 0, "("); - Printf(t, ") %s (%s)", Rules[j].combiner, s); - String *m = Getattr(messages, Rules[j].section); - Printf(m, " %s [%s from %s]", Rules[j].combiner, Getattr(imessages, Rules[j].section), Getattr(b, "name")); - } else { - Setattr(contracts, Rules[j].section, NewString(s)); - Setattr(messages, Rules[j].section, NewStringf("[%s from %s]", Getattr(imessages, Rules[j].section), Getattr(b, "name"))); - } - } - } - } - } - Delete(base_decl); - } - temp = nextSibling(temp); - } - } - Delete(local_decl); - if (!found) { - for (int j = 0; j < Len(bases); j++) { - b = Getitem(bases, j); - inherit_contracts(b, n, contracts, messages); - } - } -} - -/* This function cleans up the assertion string by removing some extraneous characters. - Splitting the assertion into pieces */ - -String *Contracts::make_expression(String *s, Node *n) { - String *str_assert, *expr = 0; - List *list_assert; - - str_assert = NewString(s); - /* Omit all useless characters and split by ; */ - Replaceall(str_assert, "\n", ""); - Replaceall(str_assert, "{", ""); - Replaceall(str_assert, "}", ""); - Replace(str_assert, " ", "", DOH_REPLACE_ANY | DOH_REPLACE_NOQUOTE); - Replace(str_assert, "\t", "", DOH_REPLACE_ANY | DOH_REPLACE_NOQUOTE); - - list_assert = Split(str_assert, ';', -1); - Delete(str_assert); - - /* build up new assertion */ - str_assert = NewString(""); - Iterator ei; - - for (ei = First(list_assert); ei.item; ei = Next(ei)) { - expr = ei.item; - if (Len(expr)) { - Replaceid(expr, Getattr(n, "name"), Swig_cresult_name()); - if (Len(str_assert)) - Append(str_assert, "&&"); - Printf(str_assert, "(%s)", expr); - } - } - Delete(list_assert); - return str_assert; -} - -/* This function substitutes parameter names for argument names in the - contract specification. Note: it is assumed that the wrapper code - uses arg1 for self and arg2..argn for arguments. */ - -void Contracts::substitute_parms(String *s, ParmList *p, int method) { - int argnum = 1; - char argname[32]; - - if (method) { - Replaceid(s, "$self", "arg1"); - argnum++; - } - while (p) { - sprintf(argname, "arg%d", argnum); - String *name = Getattr(p, "name"); - if (name) { - Replaceid(s, name, argname); - } - argnum++; - p = nextSibling(p); - } -} - -int Contracts::emit_contract(Node *n, int method) { - Hash *contracts; - Hash *messages; - String *c; - - ParmList *cparms; - - if (!Getattr(n, "feature:contract")) - return SWIG_ERROR; - - /* Get contract parameters */ - cparms = Getmeta(Getattr(n, "feature:contract"), "parms"); - - /* Split contract into preassert & postassert */ - contracts = ContractSplit(n); - if (!contracts) - return SWIG_ERROR; - - /* This messages hash is used to hold the error messages that will be displayed on - failed contract. */ - - messages = NewHash(); - - /* Take the different contract expressions and clean them up a bit */ - Iterator i; - for (i = First(contracts); i.item; i = Next(i)) { - String *e = make_expression(i.item, n); - substitute_parms(e, cparms, method); - Setattr(contracts, i.key, e); - - /* Make a string containing error messages */ - Setattr(messages, i.key, NewString(e)); - } - - /* If we're in a class. We need to inherit other assertions. */ - if (InClass) { - inherit_contracts(CurrentClass, n, contracts, messages); - } - - /* Save information */ - Setattr(n, "contract:rules", contracts); - Setattr(n, "contract:messages", messages); - - /* Okay. Generate the contract runtime code. */ - - if ((c = Getattr(contracts, "require:"))) { - Setattr(n, "contract:preassert", NewStringf("SWIG_contract_assert(%s, \"Contract violation: require: %s\");\n", c, Getattr(messages, "require:"))); - } - if ((c = Getattr(contracts, "ensure:"))) { - Setattr(n, "contract:postassert", NewStringf("SWIG_contract_assert(%s, \"Contract violation: ensure: %s\");\n", c, Getattr(messages, "ensure:"))); - } - return SWIG_OK; -} - -int Contracts::cDeclaration(Node *n) { - int ret = SWIG_OK; - String *decl = Getattr(n, "decl"); - - /* Not a function. Don't even bother with it (for now) */ - if (!SwigType_isfunction(decl)) - return SWIG_OK; - - if (Getattr(n, "feature:contract")) - ret = emit_contract(n, InClass && !Swig_storage_isstatic(n)); - return ret; -} - -int Contracts::constructorDeclaration(Node *n) { - int ret = SWIG_OK; - InConstructor = 1; - if (Getattr(n, "feature:contract")) - ret = emit_contract(n, 0); - InConstructor = 0; - return ret; -} - -int Contracts::externDeclaration(Node *n) { - return emit_children(n); -} - -int Contracts::extendDirective(Node *n) { - return emit_children(n); -} - -int Contracts::importDirective(Node *n) { - return emit_children(n); -} - -int Contracts::includeDirective(Node *n) { - return emit_children(n); -} - -int Contracts::namespaceDeclaration(Node *n) { - return emit_children(n); -} - -int Contracts::classDeclaration(Node *n) { - int ret = SWIG_OK; - int oldInClass = InClass; - Node *oldClass = CurrentClass; - InClass = 1; - CurrentClass = n; - emit_children(n); - InClass = oldInClass; - CurrentClass = oldClass; - return ret; -} - -int Contracts::top(Node *n) { - emit_children(n); - return SWIG_OK; -} diff --git a/contrib/tools/swig/Source/Modules/csharp.cxx b/contrib/tools/swig/Source/Modules/csharp.cxx deleted file mode 100644 index 240a002b40e..00000000000 --- a/contrib/tools/swig/Source/Modules/csharp.cxx +++ /dev/null @@ -1,4616 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * csharp.cxx - * - * C# language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" -#include <limits.h> // for INT_MAX -#include <ctype.h> - -/* Hash type used for upcalls from C/C++ */ -typedef DOH UpcallData; - -class CSHARP:public Language { - static const char *usage; - const String *empty_string; - const String *public_string; - const String *protected_string; - - Hash *swig_types_hash; - File *f_begin; - File *f_runtime; - File *f_runtime_h; - File *f_header; - File *f_wrappers; - File *f_init; - File *f_directors; - File *f_directors_h; - File *f_single_out; - List *filenames_list; - - bool proxy_flag; // Flag for generating proxy classes - bool native_function_flag; // Flag for when wrapping a native function - bool enum_constant_flag; // Flag for when wrapping an enum or constant - bool static_flag; // Flag for when wrapping a static functions or member variables - bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable - bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const - bool global_variable_flag; // Flag for when wrapping a global variable - bool old_variable_names; // Flag for old style variable names in the intermediary class - bool generate_property_declaration_flag; // Flag for generating properties - - String *imclass_name; // intermediary class name - String *module_class_name; // module class name - String *imclass_class_code; // intermediary class code - String *proxy_class_def; - String *proxy_class_code; - String *interface_class_code; // if %feature("interface") was declared for a class, here goes the interface declaration - String *module_class_code; - String *proxy_class_name; // proxy class name - String *full_imclass_name; // fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name - String *variable_name; //Name of a variable being wrapped - String *proxy_class_constants_code; - String *module_class_constants_code; - String *enum_code; - String *dllimport; // DllImport attribute name - String *namespce; // Optional namespace name - String *imclass_imports; //intermediary class imports from %pragma - String *module_imports; //module imports from %pragma - String *imclass_baseclass; //inheritance for intermediary class class from %pragma - String *module_baseclass; //inheritance for module class from %pragma - String *imclass_interfaces; //interfaces for intermediary class class from %pragma - String *module_interfaces; //interfaces for module class from %pragma - String *imclass_class_modifiers; //class modifiers for intermediary class overridden by %pragma - String *module_class_modifiers; //class modifiers for module class overridden by %pragma - String *upcasts_code; //C++ casts for inheritance hierarchies C++ code - String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code - String *director_callback_typedefs; // Director function pointer typedefs for callbacks - String *director_callbacks; // Director callback function pointer member variables - String *director_delegate_callback; // Director callback method that delegates are set to call - String *director_delegate_definitions; // Director delegates definitions in proxy class - String *director_delegate_instances; // Director delegates member variables in proxy class - String *director_method_types; // Director method types - String *director_connect_parms; // Director delegates parameter list for director connect call - String *destructor_call; //C++ destructor call if any - String *output_file; // File name for single file mode. If set all generated code will be written to this file - - // Director method stuff: - List *dmethods_seq; - Hash *dmethods_table; - int n_dmethods; - int n_directors; - int first_class_dmethod; - int curr_class_dmethod; - int nesting_depth; - - enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum }; - -public: - - /* ----------------------------------------------------------------------------- - * CSHARP() - * ----------------------------------------------------------------------------- */ - - CSHARP():empty_string(NewString("")), - public_string(NewString("public")), - protected_string(NewString("protected")), - swig_types_hash(NULL), - f_begin(NULL), - f_runtime(NULL), - f_runtime_h(NULL), - f_header(NULL), - f_wrappers(NULL), - f_init(NULL), - f_directors(NULL), - f_directors_h(NULL), - f_single_out(NULL), - filenames_list(NULL), - proxy_flag(true), - native_function_flag(false), - enum_constant_flag(false), - static_flag(false), - variable_wrapper_flag(false), - wrapping_member_flag(false), - global_variable_flag(false), - old_variable_names(false), - generate_property_declaration_flag(false), - imclass_name(NULL), - module_class_name(NULL), - imclass_class_code(NULL), - proxy_class_def(NULL), - proxy_class_code(NULL), - interface_class_code(NULL), - module_class_code(NULL), - proxy_class_name(NULL), - full_imclass_name(NULL), - variable_name(NULL), - proxy_class_constants_code(NULL), - module_class_constants_code(NULL), - enum_code(NULL), - dllimport(NULL), - namespce(NULL), - imclass_imports(NULL), - module_imports(NULL), - imclass_baseclass(NULL), - module_baseclass(NULL), - imclass_interfaces(NULL), - module_interfaces(NULL), - imclass_class_modifiers(NULL), - module_class_modifiers(NULL), - upcasts_code(NULL), - imclass_cppcasts_code(NULL), - director_callback_typedefs(NULL), - director_callbacks(NULL), - director_delegate_callback(NULL), - director_delegate_definitions(NULL), - director_delegate_instances(NULL), - director_method_types(NULL), - director_connect_parms(NULL), - destructor_call(NULL), - output_file(NULL), - dmethods_seq(NULL), - dmethods_table(NULL), - n_dmethods(0), - n_directors(0), - first_class_dmethod(0), - curr_class_dmethod(0), - nesting_depth(0){ - /* for now, multiple inheritance in directors is disabled, this - should be easy to implement though */ - director_multiple_inheritance = 0; - director_language = 1; - } - - /* ----------------------------------------------------------------------------- - * getProxyName() - * - * Test to see if a type corresponds to something wrapped with a proxy class. - * Return NULL if not otherwise the proxy class name, fully qualified with - * a namespace if the nspace feature is used. - * ----------------------------------------------------------------------------- */ - - String *getProxyName(SwigType *t) { - String *proxyname = NULL; - if (proxy_flag) { - Node *n = classLookup(t); - if (n) { - proxyname = Getattr(n, "proxyname"); - if (!proxyname) { - String *nspace = Getattr(n, "sym:nspace"); - String *symname = Copy(Getattr(n, "sym:name")); - if (symname && !GetFlag(n, "feature:flatnested")) { - for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) { - if (String* name = Getattr(outer_class, "sym:name")) { - Push(symname, "."); - Push(symname, name); - } - else - return NULL; - } - } - if (nspace) { - if (namespce) - proxyname = NewStringf("%s.%s.%s", namespce, nspace, symname); - else - proxyname = NewStringf("%s.%s", nspace, symname); - } else { - proxyname = Copy(symname); - } - Setattr(n, "proxyname", proxyname); - Delete(proxyname); - Delete(symname); - } - } - } - return proxyname; - } - - /* ------------------------------------------------------------ - * main() - * ------------------------------------------------------------ */ - - virtual void main(int argc, char *argv[]) { - - SWIG_library_directory("csharp"); - - // Look for certain command line options - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-dllimport") == 0) { - if (argv[i + 1]) { - dllimport = NewString(""); - Printf(dllimport, argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-namespace") == 0) { - if (argv[i + 1]) { - namespce = NewString(""); - Printf(namespce, argv[i + 1]); - if (Len(namespce) == 0) { - Delete(namespce); - namespce = 0; - } - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if ((strcmp(argv[i], "-noproxy") == 0)) { - Swig_mark_arg(i); - proxy_flag = false; - } else if (strcmp(argv[i], "-oldvarnames") == 0) { - Swig_mark_arg(i); - old_variable_names = true; - } else if (strcmp(argv[i], "-outfile") == 0) { - if (argv[i + 1]) { - output_file = NewString(""); - Printf(output_file, argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-help") == 0) { - Printf(stdout, "%s\n", usage); - } - } - } - - // Add a symbol to the parser for conditional compilation - Preprocessor_define("SWIGCSHARP 1", 0); - - // Add typemap definitions - SWIG_typemap_lang("csharp"); - SWIG_config_file("csharp.swg"); - - allow_overloading(); - Swig_interface_feature_enable(); - } - - /* --------------------------------------------------------------------- - * top() - * --------------------------------------------------------------------- */ - - virtual int top(Node *n) { - - // Get any options set in the module directive - Node *optionsnode = Getattr(Getattr(n, "module"), "options"); - - if (optionsnode) { - if (Getattr(optionsnode, "imclassname")) - imclass_name = Copy(Getattr(optionsnode, "imclassname")); - /* check if directors are enabled for this module. note: this - * is a "master" switch, without which no director code will be - * emitted. %feature("director") statements are also required - * to enable directors for individual classes or methods. - * - * use %module(directors="1") modulename at the start of the - * interface file to enable director generation. - */ - if (Getattr(optionsnode, "directors")) { - allow_directors(); - } - if (Getattr(optionsnode, "dirprot")) { - allow_dirprot(); - } - allow_allprotected(GetFlag(optionsnode, "allprotected")); - } - - /* Initialize all of the output files */ - String *outfile = Getattr(n, "outfile"); - String *outfile_h = Getattr(n, "outfile_h"); - - if (!outfile) { - Printf(stderr, "Unable to determine outfile\n"); - Exit(EXIT_FAILURE); - } - - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - - if (directorsEnabled()) { - if (!outfile_h) { - Printf(stderr, "Unable to determine outfile_h\n"); - Exit(EXIT_FAILURE); - } - f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); - if (!f_runtime_h) { - FileErrorDisplay(outfile_h); - Exit(EXIT_FAILURE); - } - } - - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - f_wrappers = NewString(""); - f_directors_h = NewString(""); - f_directors = NewString(""); - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", f_init); - Swig_register_filebyname("director", f_directors); - Swig_register_filebyname("director_h", f_directors_h); - - swig_types_hash = NewHash(); - filenames_list = NewList(); - - // Make the intermediary class and module class names. The intermediary class name can be set in the module directive. - if (!imclass_name) { - imclass_name = NewStringf("%sPINVOKE", Getattr(n, "name")); - module_class_name = Copy(Getattr(n, "name")); - } else { - // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution - if (Cmp(imclass_name, Getattr(n, "name")) == 0) - module_class_name = NewStringf("%sModule", Getattr(n, "name")); - else - module_class_name = Copy(Getattr(n, "name")); - } - - // module class and intermediary classes are always created - if (!addSymbol(imclass_name, n)) - return SWIG_ERROR; - if (!addSymbol(module_class_name, n)) - return SWIG_ERROR; - - imclass_class_code = NewString(""); - proxy_class_def = NewString(""); - proxy_class_code = NewString(""); - module_class_constants_code = NewString(""); - imclass_baseclass = NewString(""); - imclass_interfaces = NewString(""); - imclass_class_modifiers = NewString(""); - module_class_code = NewString(""); - module_baseclass = NewString(""); - module_interfaces = NewString(""); - module_imports = NewString(""); - module_class_modifiers = NewString(""); - imclass_imports = NewString(""); - imclass_cppcasts_code = NewString(""); - director_connect_parms = NewString(""); - upcasts_code = NewString(""); - dmethods_seq = NewList(); - dmethods_table = NewHash(); - n_dmethods = 0; - n_directors = 0; - if (!dllimport) - dllimport = Copy(module_class_name); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "CSHARP"); - - if (directorsEnabled()) { - Printf(f_runtime, "#define SWIG_DIRECTORS\n"); - - /* Emit initial director header and director code: */ - Swig_banner(f_directors_h); - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_class_name); - Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_class_name); - - Printf(f_directors, "\n\n"); - Printf(f_directors, "/* ---------------------------------------------------\n"); - Printf(f_directors, " * C++ director class methods\n"); - Printf(f_directors, " * --------------------------------------------------- */\n\n"); - if (outfile_h) { - String *filename = Swig_file_filename(outfile_h); - Printf(f_directors, "#include \"%s\"\n\n", filename); - Delete(filename); - } - } - - Printf(f_runtime, "\n"); - if (namespce) { - String *wrapper_name = NewStringf(""); - Printf(wrapper_name, "CSharp_%s_%%f", namespce); - Swig_name_register("wrapper", wrapper_name); - Delete(wrapper_name); - } - else { - Swig_name_register("wrapper", "CSharp_%f"); - } - - if (old_variable_names) { - Swig_name_register("set", "set_%n%v"); - Swig_name_register("get", "get_%n%v"); - } - - Printf(f_wrappers, "\n#ifdef __cplusplus\n"); - Printf(f_wrappers, "extern \"C\" {\n"); - Printf(f_wrappers, "#endif\n\n"); - - /* Emit code */ - Language::top(n); - - if (directorsEnabled()) { - // Insert director runtime into the f_runtime file (make it occur before %header section) - Swig_insert_file("director_common.swg", f_runtime); - Swig_insert_file("director.swg", f_runtime); - } - // Generate the intermediary class - { - File *f_im = getOutputFile(SWIG_output_directory(), imclass_name); - - addOpenNamespace(0, f_im); - - if (imclass_imports) - Printf(f_im, "%s\n", imclass_imports); - - if (Len(imclass_class_modifiers) > 0) - Printf(f_im, "%s ", imclass_class_modifiers); - Printf(f_im, "%s ", imclass_name); - - if (imclass_baseclass && *Char(imclass_baseclass)) - Printf(f_im, ": %s ", imclass_baseclass); - if (Len(imclass_interfaces) > 0) - Printv(f_im, "implements ", imclass_interfaces, " ", NIL); - Printf(f_im, "{\n"); - - // Add the intermediary class methods - Replaceall(imclass_class_code, "$module", module_class_name); - Replaceall(imclass_class_code, "$imclassname", imclass_name); - Replaceall(imclass_class_code, "$dllimport", dllimport); - Printv(f_im, imclass_class_code, NIL); - Printv(f_im, imclass_cppcasts_code, NIL); - - // Finish off the class - Printf(f_im, "}\n"); - addCloseNamespace(0, f_im); - - if (f_im != f_single_out) - Delete(f_im); - f_im = NULL; - } - - // Generate the C# module class - { - File *f_module = getOutputFile(SWIG_output_directory(), module_class_name); - - addOpenNamespace(0, f_module); - - if (module_imports) - Printf(f_module, "%s\n", module_imports); - - if (Len(module_class_modifiers) > 0) - Printf(f_module, "%s ", module_class_modifiers); - Printf(f_module, "%s ", module_class_name); - - if (module_baseclass && *Char(module_baseclass)) - Printf(f_module, ": %s ", module_baseclass); - if (Len(module_interfaces) > 0) - Printv(f_module, "implements ", module_interfaces, " ", NIL); - Printf(f_module, "{\n"); - - Replaceall(module_class_code, "$module", module_class_name); - Replaceall(module_class_constants_code, "$module", module_class_name); - - Replaceall(module_class_code, "$imclassname", imclass_name); - Replaceall(module_class_constants_code, "$imclassname", imclass_name); - - Replaceall(module_class_code, "$dllimport", dllimport); - Replaceall(module_class_constants_code, "$dllimport", dllimport); - - // Add the wrapper methods - Printv(f_module, module_class_code, NIL); - - // Write out all the global constants - Printv(f_module, module_class_constants_code, NIL); - - // Finish off the class - Printf(f_module, "}\n"); - addCloseNamespace(0, f_module); - - if (f_module != f_single_out) - Delete(f_module); - f_module = NULL; - } - - if (upcasts_code) - Printv(f_wrappers, upcasts_code, NIL); - - Printf(f_wrappers, "#ifdef __cplusplus\n"); - Printf(f_wrappers, "}\n"); - Printf(f_wrappers, "#endif\n"); - - // Output a C# type wrapper class for each SWIG type - for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) { - emitTypeWrapperClass(swig_type.key, swig_type.item); - } - - // Check for overwriting file problems on filesystems that are case insensitive - Iterator it1; - Iterator it2; - for (it1 = First(filenames_list); it1.item; it1 = Next(it1)) { - String *item1_lower = Swig_string_lower(it1.item); - for (it2 = Next(it1); it2.item; it2 = Next(it2)) { - String *item2_lower = Swig_string_lower(it2.item); - if (it1.item && it2.item) { - if (Strcmp(item1_lower, item2_lower) == 0) { - Swig_warning(WARN_LANG_PORTABILITY_FILENAME, input_file, line_number, - "Portability warning: File %s will be overwritten by %s on case insensitive filesystems such as " - "Windows' FAT32 and NTFS unless the class/module name is renamed\n", it1.item, it2.item); - } - } - Delete(item2_lower); - } - Delete(item1_lower); - } - - Delete(swig_types_hash); - swig_types_hash = NULL; - Delete(filenames_list); - filenames_list = NULL; - Delete(imclass_name); - imclass_name = NULL; - Delete(imclass_class_code); - imclass_class_code = NULL; - Delete(proxy_class_def); - proxy_class_def = NULL; - Delete(proxy_class_code); - proxy_class_code = NULL; - Delete(module_class_constants_code); - module_class_constants_code = NULL; - Delete(imclass_baseclass); - imclass_baseclass = NULL; - Delete(imclass_interfaces); - imclass_interfaces = NULL; - Delete(imclass_class_modifiers); - imclass_class_modifiers = NULL; - Delete(module_class_name); - module_class_name = NULL; - Delete(module_class_code); - module_class_code = NULL; - Delete(module_baseclass); - module_baseclass = NULL; - Delete(module_interfaces); - module_interfaces = NULL; - Delete(module_imports); - module_imports = NULL; - Delete(module_class_modifiers); - module_class_modifiers = NULL; - Delete(imclass_imports); - imclass_imports = NULL; - Delete(imclass_cppcasts_code); - imclass_cppcasts_code = NULL; - Delete(upcasts_code); - upcasts_code = NULL; - Delete(dmethods_seq); - dmethods_seq = NULL; - Delete(dmethods_table); - dmethods_table = NULL; - Delete(namespce); - namespce = NULL; - n_dmethods = 0; - - /* Close all of the files */ - Dump(f_runtime, f_begin); - Dump(f_header, f_begin); - - if (directorsEnabled()) { - Dump(f_directors, f_begin); - Dump(f_directors_h, f_runtime_h); - - Printf(f_runtime_h, "\n"); - Printf(f_runtime_h, "#endif\n"); - - Delete(f_runtime_h); - f_runtime_h = NULL; - Delete(f_directors); - f_directors = NULL; - Delete(f_directors_h); - f_directors_h = NULL; - } - - if (f_single_out) { - Dump(f_single_out, f_begin); - Delete(f_single_out); - f_single_out = NULL; - } - - Dump(f_wrappers, f_begin); - Wrapper_pretty_print(f_init, f_begin); - Delete(f_header); - Delete(f_wrappers); - Delete(f_init); - Delete(f_runtime); - Delete(f_begin); - return SWIG_OK; - } - - /* ----------------------------------------------------------------------------- - * emitBanner() - * ----------------------------------------------------------------------------- */ - - void emitBanner(File *f) { - Printf(f, "//------------------------------------------------------------------------------\n"); - Printf(f, "// <auto-generated />\n"); - Printf(f, "//\n"); - Swig_banner_target_lang(f, "//"); - Printf(f, "//------------------------------------------------------------------------------\n\n"); - } - - /* ----------------------------------------------------------------------------- - * getOutputFile() - * - * Prepares a File object by creating the file in the file system and - * writing the banner for auto-generated files to it (emitBanner). - * If '-outfile' is provided (single file mode) the supplied parameters will - * be ignored and the returned file will always be: - * <outdir>/<outfile> - * Otherwise the file will be: - * <dir>/<name>.cs - * ----------------------------------------------------------------------------- */ - - File *getOutputFile(const String *dir, const String *name) { - if (output_file) { - if (!f_single_out) { - String *filen = NewStringf("%s%s", SWIG_output_directory(), output_file); - f_single_out = NewFile(filen, "w", SWIG_output_files()); - if (!f_single_out) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - emitBanner(f_single_out); - } - return f_single_out; - } else { - String *filen = NewStringf("%s%s.cs", dir, name); - File *f = NewFile(filen, "w", SWIG_output_files()); - if (!f) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - emitBanner(f); - return f; - } - } - - /*----------------------------------------------------------------------- - * Add new director upcall signature - *----------------------------------------------------------------------*/ - - UpcallData *addUpcallMethod(String *imclass_method, String *class_method, String *decl, String *overloaded_name) { - String *key = NewStringf("%s|%s", imclass_method, decl); - - ++curr_class_dmethod; - - String *class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod); - n_dmethods++; - - Hash *new_udata = NewHash(); - Append(dmethods_seq, new_udata); - Setattr(dmethods_table, key, new_udata); - - Setattr(new_udata, "method", Copy(class_method)); - Setattr(new_udata, "class_methodidx", class_methodidx); - Setattr(new_udata, "decl", Copy(decl)); - Setattr(new_udata, "overname", Copy(overloaded_name)); - - Delete(key); - return new_udata; - } - - /*----------------------------------------------------------------------- - * Get director upcall signature - *----------------------------------------------------------------------*/ - - /* - UpcallData * getUpcallMethodData(String *director_class, String *decl) { - String *key = NewStringf("%s|%s", director_class, decl); - UpcallData *udata = Getattr(dmethods_table, key); - - Delete(key); - return udata; - } - */ - - /* ---------------------------------------------------------------------- - * nativeWrapper() - * ---------------------------------------------------------------------- */ - - virtual int nativeWrapper(Node *n) { - String *wrapname = Getattr(n, "wrap:name"); - - if (!addSymbol(wrapname, n, imclass_name)) - return SWIG_ERROR; - - if (Getattr(n, "type")) { - Swig_save("nativeWrapper", n, "name", NIL); - Setattr(n, "name", wrapname); - native_function_flag = true; - functionWrapper(n); - Swig_restore(n); - native_function_flag = false; - } else { - Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name")); - } - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * functionWrapper() - * ---------------------------------------------------------------------- */ - - virtual int functionWrapper(Node *n) { - String *symname = Getattr(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - String *tm; - Parm *p; - int i; - String *c_return_type = NewString(""); - String *im_return_type = NewString(""); - String *cleanup = NewString(""); - String *outarg = NewString(""); - String *body = NewString(""); - String *im_outattributes = 0; - int num_arguments = 0; - bool is_void_return; - String *overloaded_name = getOverloadedName(n); - - if (!Getattr(n, "sym:overloaded")) { - if (!addSymbol(symname, n, imclass_name)) - return SWIG_ERROR; - } - - /* - The rest of this function deals with generating the intermediary class wrapper function (that wraps - a c/c++ function) and generating the PInvoke c code. Each C# wrapper function has a - matching PInvoke c function call. - */ - - // A new wrapper function object - Wrapper *f = NewWrapper(); - - // Make a wrapper name for this function - String *wname = Swig_name_wrapper(overloaded_name); - - /* Attach the non-standard typemaps to the parameter list. */ - Swig_typemap_attach_parms("ctype", l, f); - Swig_typemap_attach_parms("imtype", l, f); - - /* Get return types */ - if ((tm = Swig_typemap_lookup("ctype", n, "", 0))) { - String *ctypeout = Getattr(n, "tmap:ctype:out"); // the type in the ctype typemap's out attribute overrides the type in the typemap - if (ctypeout) - tm = ctypeout; - Printf(c_return_type, "%s", tm); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(t, 0)); - } - - if ((tm = Swig_typemap_lookup("imtype", n, "", 0))) { - String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap - if (imtypeout) - tm = imtypeout; - Printf(im_return_type, "%s", tm); - im_outattributes = Getattr(n, "tmap:imtype:outattributes"); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(t, 0)); - } - - is_void_return = (Cmp(c_return_type, "void") == 0); - if (!is_void_return) - Wrapper_add_localv(f, "jresult", c_return_type, "jresult", NIL); - - Printv(f->def, " SWIGEXPORT ", c_return_type, " SWIGSTDCALL ", wname, "(", NIL); - - // Emit all of the local variables for holding arguments. - emit_parameter_variables(l, f); - - /* Attach the standard typemaps */ - emit_attach_parmmaps(l, f); - - // Parameter overloading - Setattr(n, "wrap:parms", l); - Setattr(n, "wrap:name", wname); - - // Wrappers not wanted for some methods where the parameters cannot be overloaded in C# - if (Getattr(n, "sym:overloaded")) { - // Emit warnings for the few cases that can't be overloaded in C# and give up on generating wrapper - Swig_overload_check(n); - if (Getattr(n, "overload:ignore")) { - DelWrapper(f); - return SWIG_OK; - } - } - - Printv(imclass_class_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL); - - if (im_outattributes) - Printf(imclass_class_code, " %s\n", im_outattributes); - - Printf(imclass_class_code, " public static extern %s %s(", im_return_type, overloaded_name); - - - /* Get number of required and total arguments */ - num_arguments = emit_num_arguments(l); - int gencomma = 0; - - // Now walk the function parameter list and generate code to get arguments - for (i = 0, p = l; i < num_arguments; i++) { - - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *ln = Getattr(p, "lname"); - String *im_param_type = NewString(""); - String *c_param_type = NewString(""); - String *arg = NewString(""); - - Printf(arg, "j%s", ln); - - /* Get the ctype types of the parameter */ - if ((tm = Getattr(p, "tmap:ctype"))) { - Printv(c_param_type, tm, NIL); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Get the intermediary class parameter types of the parameter */ - if ((tm = Getattr(p, "tmap:imtype"))) { - const String *inattributes = Getattr(p, "tmap:imtype:inattributes"); - Printf(im_param_type, "%s%s", inattributes ? inattributes : empty_string, tm); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Add parameter to intermediary class method */ - if (gencomma) - Printf(imclass_class_code, ", "); - Printf(imclass_class_code, "%s %s", im_param_type, arg); - - // Add parameter to C function - Printv(f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL); - - gencomma = 1; - - // Get typemap for this argument - if ((tm = Getattr(p, "tmap:in"))) { - canThrow(n, "in", p); - Replaceall(tm, "$arg", arg); /* deprecated? */ - Replaceall(tm, "$input", arg); - Setattr(p, "emit:input", arg); - Printf(f->code, "%s\n", tm); - p = Getattr(p, "tmap:in:next"); - } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); - p = nextSibling(p); - } - Delete(im_param_type); - Delete(c_param_type); - Delete(arg); - } - - /* Insert constraint checking code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - canThrow(n, "check", p); - Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */ - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert cleanup code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:freearg"))) { - canThrow(n, "freearg", p); - Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */ - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(cleanup, tm, "\n", NIL); - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert argument output code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - canThrow(n, "argout", p); - Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */ - Replaceall(tm, "$result", "jresult"); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - // Look for usage of throws typemap and the canthrow flag - ParmList *throw_parm_list = NULL; - if ((throw_parm_list = Getattr(n, "catchlist"))) { - Swig_typemap_attach_parms("throws", throw_parm_list, f); - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - canThrow(n, "throws", p); - } - } - } - - String *null_attribute = 0; - // Now write code to make the function call - if (!native_function_flag) { - - Swig_director_emit_dynamic_cast(n, f); - String *actioncode = emit_action(n); - - /* Return value if necessary */ - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { - canThrow(n, "out", n); - Replaceall(tm, "$result", "jresult"); - - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "1"); - else - Replaceall(tm, "$owner", "0"); - - Printf(f->code, "%s", tm); - null_attribute = Getattr(n, "tmap:out:null"); - if (Len(tm)) - Printf(f->code, "\n"); - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name")); - } - emit_return_variable(n, t, f); - } - - /* Output argument output code */ - Printv(f->code, outarg, NIL); - - /* Output cleanup code */ - Printv(f->code, cleanup, NIL); - - /* Look to see if there is any newfree cleanup code */ - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - canThrow(n, "newfree", n); - Printf(f->code, "%s\n", tm); - } - } - - /* See if there is any return cleanup code */ - if (!native_function_flag) { - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - canThrow(n, "ret", n); - Printf(f->code, "%s\n", tm); - } - } - - /* Finish C function and intermediary class function definitions */ - Printf(imclass_class_code, ")"); - Printf(imclass_class_code, ";\n"); - - Printf(f->def, ") {"); - - if (!is_void_return) - Printv(f->code, " return jresult;\n", NIL); - Printf(f->code, "}\n"); - - /* Substitute the cleanup code */ - Replaceall(f->code, "$cleanup", cleanup); - - /* Substitute the function name */ - Replaceall(f->code, "$symname", symname); - - /* Contract macro modification */ - if (Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ") > 0) { - Setattr(n, "csharp:canthrow", "1"); - } - - if (!null_attribute) - Replaceall(f->code, "$null", "0"); - else - Replaceall(f->code, "$null", null_attribute); - - /* Dump the function out */ - if (!native_function_flag) { - Wrapper_print(f, f_wrappers); - - // Handle %csexception which sets the canthrow attribute - if (Getattr(n, "feature:except:canthrow")) - Setattr(n, "csharp:canthrow", "1"); - - // A very simple check (it is not foolproof) to help typemap/feature writers for - // throwing C# exceptions from unmanaged code. It checks for the common methods which - // set a pending C# exception... the 'canthrow' typemap/feature attribute must be set - // so that code which checks for pending exceptions is added in the C# proxy method. - if (!Getattr(n, "csharp:canthrow")) { - if (Strstr(f->code, "SWIG_exception")) { - Swig_warning(WARN_CSHARP_CANTHROW, input_file, line_number, - "Unmanaged code contains a call to SWIG_exception and C# code does not handle pending exceptions via the canthrow attribute.\n"); - } else if (Strstr(f->code, "SWIG_CSharpSetPendingException")) { - Swig_warning(WARN_CSHARP_CANTHROW, input_file, line_number, - "Unmanaged code contains a call to a SWIG_CSharpSetPendingException method and C# code does not handle pending exceptions via the canthrow attribute.\n"); - } - } - } - - if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) { - moduleClassFunctionHandler(n); - } - - /* - * Generate the proxy class properties for public member variables. - * Not for enums and constants. - */ - if (proxy_flag && wrapping_member_flag && !enum_constant_flag) { - // Capitalize the first letter in the variable in the getter/setter function name - bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) != 0; - - String *getter_setter_name = NewString(""); - if (!getter_flag) - Printf(getter_setter_name, "set"); - else - Printf(getter_setter_name, "get"); - Putc(toupper((int) *Char(variable_name)), getter_setter_name); - Printf(getter_setter_name, "%s", Char(variable_name) + 1); - - Setattr(n, "proxyfuncname", getter_setter_name); - Setattr(n, "imfuncname", symname); - - proxyClassFunctionHandler(n); - Delete(getter_setter_name); - } - - Delete(c_return_type); - Delete(im_return_type); - Delete(cleanup); - Delete(outarg); - Delete(body); - Delete(overloaded_name); - DelWrapper(f); - return SWIG_OK; - } - - /* ----------------------------------------------------------------------- - * variableWrapper() - * ----------------------------------------------------------------------- */ - - virtual int variableWrapper(Node *n) { - Language::variableWrapper(n); - return SWIG_OK; - } - - /* ----------------------------------------------------------------------- - * globalvariableHandler() - * ------------------------------------------------------------------------ */ - - virtual int globalvariableHandler(Node *n) { - - generate_property_declaration_flag = true; - variable_name = Getattr(n, "sym:name"); - global_variable_flag = true; - int ret = Language::globalvariableHandler(n); - global_variable_flag = false; - generate_property_declaration_flag = false; - - if (proxy_flag) { - Printf(module_class_code, "\n }\n\n"); - } - - return ret; - } - - String *getCurrentScopeName(String *nspace) { - String *scope = 0; - if (nspace || getCurrentClass()) { - scope = NewString(""); - if (nspace) - Printf(scope, "%s", nspace); - if (Node *cls = getCurrentClass()) { - if (Node *outer = Getattr(cls, "nested:outer")) { - String *outerClassesPrefix = Copy(Getattr(outer, "sym:name")); - for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) { - Push(outerClassesPrefix, "."); - Push(outerClassesPrefix, Getattr(outer, "sym:name")); - } - Printv(scope, nspace ? "." : "", outerClassesPrefix, ".", proxy_class_name, NIL); - Delete(outerClassesPrefix); - } else - Printv(scope, nspace ? "." : "", proxy_class_name, NIL); - } - } - return scope; - } - - /* ---------------------------------------------------------------------- - * enumDeclaration() - * - * C/C++ enums can be mapped in one of 4 ways, depending on the cs:enum feature specified: - * 1) Simple enums - simple constant within the proxy class or module class - * 2) Typeunsafe enums - simple constant in a C# class (class named after the c++ enum name) - * 3) Typesafe enum - typesafe enum pattern (class named after the c++ enum name) - * 4) Proper enums - proper C# enum - * Anonymous enums always default to 1) - * ---------------------------------------------------------------------- */ - - virtual int enumDeclaration(Node *n) { - - if (!ImportMode) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call - if (proxy_flag && !is_wrapping_class()) { - // Global enums / enums in a namespace - assert(!full_imclass_name); - - if (!nspace) { - full_imclass_name = NewStringf("%s", imclass_name); - } else { - if (namespce) { - full_imclass_name = NewStringf("%s.%s", namespce, imclass_name); - } else { - full_imclass_name = NewStringf("%s", imclass_name); - } - } - } - - enum_code = NewString(""); - String *symname = Getattr(n, "sym:name"); - String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code; - EnumFeature enum_feature = decodeEnumFeature(n); - String *typemap_lookup_type = Getattr(n, "name"); - - if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) { - // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum - - String *scope = getCurrentScopeName(nspace); - if (!addSymbol(symname, n, scope)) - return SWIG_ERROR; - - // Pure C# baseclass and interfaces - const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE); - const String *pure_interfaces = typemapLookup(n, "csinterfaces", typemap_lookup_type, WARN_NONE); - - // Class attributes - const String *csattributes = typemapLookup(n, "csattributes", typemap_lookup_type, WARN_NONE); - if (csattributes && *Char(csattributes)) - Printf(enum_code, "%s\n", csattributes); - - // Emit the enum - Printv(enum_code, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers (enum modifiers really) - " ", symname, (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass, ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces - ", " : "", pure_interfaces, " {\n", NIL); - Delete(scope); - } else { - // Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort - if (symname && !Getattr(n, "unnamedinstance")) - Printf(constants_code, " // %s \n", symname); - } - - // Emit each enum item - Language::enumDeclaration(n); - - if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) { - // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum - // Finish the enum declaration - // Typemaps are used to generate the enum definition in a similar manner to proxy classes. - Printv(enum_code, (enum_feature == ProperEnum) ? "\n" : typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class - typemapLookup(n, "cscode", typemap_lookup_type, WARN_NONE), // extra C# code - "}", NIL); - - Replaceall(enum_code, "$csclassname", symname); - - // Substitute $enumvalues - intended usage is for typesafe enums - if (Getattr(n, "enumvalues")) - Replaceall(enum_code, "$enumvalues", Getattr(n, "enumvalues")); - else - Replaceall(enum_code, "$enumvalues", ""); - - if (proxy_flag && is_wrapping_class()) { - // Enums defined within the C++ class are defined within the proxy class - - // Add extra indentation - Replaceall(enum_code, "\n", "\n "); - Replaceall(enum_code, " \n", "\n"); - - Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL); - } else { - // Global enums are defined in their own file - String *output_directory = outputDirectory(nspace); - File *f_enum = getOutputFile(output_directory, symname); - - addOpenNamespace(nspace, f_enum); - - Printv(f_enum, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements - "\n", enum_code, "\n", NIL); - - addCloseNamespace(nspace, f_enum); - if (f_enum != f_single_out) - Delete(f_enum); - f_enum = NULL; - Delete(output_directory); - } - } else { - // Wrap C++ enum with simple constant - Printf(enum_code, "\n"); - if (proxy_flag && is_wrapping_class()) - Printv(proxy_class_constants_code, enum_code, NIL); - else - Printv(module_class_constants_code, enum_code, NIL); - } - - Delete(enum_code); - enum_code = NULL; - - if (proxy_flag && !is_wrapping_class()) { - Delete(full_imclass_name); - full_imclass_name = 0; - } - } - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * enumvalueDeclaration() - * ---------------------------------------------------------------------- */ - - virtual int enumvalueDeclaration(Node *n) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL); - String *symname = Getattr(n, "sym:name"); - String *value = Getattr(n, "value"); - String *name = Getattr(n, "name"); - Node *parent = parentNode(n); - int unnamedinstance = GetFlag(parent, "unnamedinstance"); - String *parent_name = Getattr(parent, "name"); - String *nspace = getNSpace(); - String *newsymname = 0; - String *tmpValue; - - // Strange hack from parent method - if (value) - tmpValue = NewString(value); - else - tmpValue = NewString(name); - // Note that this is used in enumValue() amongst other places - Setattr(n, "value", tmpValue); - - // Deal with enum values that are not int - int swigtype = SwigType_type(Getattr(n, "type")); - if (swigtype == T_BOOL) { - const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0"; - Setattr(n, "enumvalue", val); - } else if (swigtype == T_CHAR) { - String *val = NewStringf("'%(hexescape)s'", Getattr(n, "enumvalue")); - Setattr(n, "enumvalue", val); - Delete(val); - } - - { - EnumFeature enum_feature = decodeEnumFeature(parent); - - if ((enum_feature == SimpleEnum) && GetFlag(parent, "scopedenum")) { - newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname); - symname = newsymname; - } - - // Add to language symbol table - String *scope = 0; - if (unnamedinstance || !parent_name || enum_feature == SimpleEnum) { - String *enumClassPrefix = getEnumClassPrefix(); - if (enumClassPrefix) { - scope = NewString(""); - if (nspace) - Printf(scope, "%s.", nspace); - Printf(scope, "%s", enumClassPrefix); - } else { - scope = Copy(module_class_name); - } - } else { - scope = getCurrentScopeName(nspace); - if (!scope) - scope = Copy(Getattr(parent, "sym:name")); - else - Printf(scope, ".%s", Getattr(parent, "sym:name")); - } - if (!addSymbol(symname, n, scope)) - return SWIG_ERROR; - - const String *csattributes = Getattr(n, "feature:cs:attributes"); - - if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) { - // Wrap (non-anonymous) C/C++ enum with a proper C# enum - // Emit the enum item. - if (!GetFlag(n, "firstenumitem")) - Printf(enum_code, ",\n"); - - if (csattributes) - Printf(enum_code, " %s\n", csattributes); - - Printf(enum_code, " %s", symname); - - // Check for the %csconstvalue feature - String *value = Getattr(n, "feature:cs:constvalue"); - - // Note that the enum value must be a true constant and cannot be set from a PINVOKE call, thus no support for %csconst(0) - value = value ? value : Getattr(n, "enumvalue"); - if (value) { - Printf(enum_code, " = %s", value); - } - } else { - // Wrap C/C++ enums with constant integers or use the typesafe enum pattern - SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum "); - Setattr(n, "type", typemap_lookup_type); - const String *tm = typemapLookup(n, "cstype", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF); - - String *return_type = Copy(tm); - substituteClassname(typemap_lookup_type, return_type); - const String *methodmods = Getattr(n, "feature:cs:methodmodifiers"); - methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - - if (csattributes) - Printf(enum_code, " %s\n", csattributes); - - if ((enum_feature == TypesafeEnum) && parent_name && !unnamedinstance) { - // Wrap (non-anonymous) enum using the typesafe enum pattern - if (Getattr(n, "enumvalue")) { - String *value = enumValue(n); - Printf(enum_code, " %s static readonly %s %s = new %s(\"%s\", %s);\n", methodmods, return_type, symname, return_type, symname, value); - Delete(value); - } else { - Printf(enum_code, " %s static readonly %s %s = new %s(\"%s\");\n", methodmods, return_type, symname, return_type, symname); - } - } else { - // Simple integer constants - // Note these are always generated for anonymous enums, no matter what enum_feature is specified - // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later - - // The %csconst feature determines how the constant value is obtained - int const_feature_flag = GetFlag(n, "feature:cs:const"); - - const char *const_readonly = const_feature_flag ? "const" : "static readonly"; - String *value = enumValue(n); - Printf(enum_code, " %s %s %s %s = %s;\n", methodmods, const_readonly, return_type, symname, value); - Delete(value); - } - Delete(return_type); - } - - // Add the enum value to the comma separated list being constructed in the enum declaration. - String *enumvalues = Getattr(parent, "enumvalues"); - if (!enumvalues) - Setattr(parent, "enumvalues", Copy(symname)); - else - Printv(enumvalues, ", ", symname, NIL); - Delete(scope); - } - - Delete(newsymname); - Delete(tmpValue); - Swig_restore(n); - return SWIG_OK; - } - - /* ----------------------------------------------------------------------- - * constantWrapper() - * Used for wrapping constants - #define or %constant. - * Also for inline initialised const static primitive type member variables (short, int, double, enums etc). - * C# static const variables are generated for these. - * If the %csconst(1) feature is used then the C constant value is used to initialise the C# const variable. - * If not, a PINVOKE method is generated to get the C constant value for initialisation of the C# const variable. - * However, if the %csconstvalue feature is used, it overrides all other ways to generate the initialisation. - * Also note that this method might be called for wrapping enum items (when the enum is using %csconst(0)). - * ------------------------------------------------------------------------ */ - - virtual int constantWrapper(Node *n) { - String *symname = Getattr(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - SwigType *valuetype = Getattr(n, "valuetype"); - ParmList *l = Getattr(n, "parms"); - String *tm; - String *return_type = NewString(""); - String *constants_code = NewString(""); - Swig_save("constantWrapper", n, "value", NIL); - Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:cstype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:cstype:outattributes", NIL); - - bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0); - - const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname; - if (!is_enum_item) { - String *scope = 0; - if (proxy_class_name) { - String *nspace = getNSpace(); - scope = NewString(""); - if (nspace) - Printf(scope, "%s.", nspace); - Printf(scope, "%s", proxy_class_name); - } else { - scope = Copy(module_class_name); - } - if (!addSymbol(itemname, n, scope)) - return SWIG_ERROR; - Delete(scope); - } - - // The %csconst feature determines how the constant value is obtained - int const_feature_flag = GetFlag(n, "feature:cs:const"); - - /* Adjust the enum type for the Swig_typemap_lookup. - * We want the same jstype typemap for all the enum items so we use the enum type (parent node). */ - if (is_enum_item) { - t = Getattr(parentNode(n), "enumtype"); - Setattr(n, "type", t); - } - - /* Attach the non-standard typemaps to the parameter list. */ - Swig_typemap_attach_parms("cstype", l, NULL); - - /* Get C# return types */ - bool classname_substituted_flag = false; - - if ((tm = Swig_typemap_lookup("cstype", n, "", 0))) { - String *cstypeout = Getattr(n, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap - if (cstypeout) - tm = cstypeout; - classname_substituted_flag = substituteClassname(t, tm); - Printf(return_type, "%s", tm); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0)); - } - - // Default (octal) escaping is no good - change to hex escaped value - String *hexescaped_value = Getattr(n, "rawvalue") ? NewStringf("%(hexescape)s", Getattr(n, "rawvalue")) : 0; - // Add the stripped quotes back in - String *new_value = NewString(""); - if (SwigType_type(t) == T_STRING) { - Printf(new_value, "\"%s\"", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value"))); - Setattr(n, "value", new_value); - } else if (SwigType_type(t) == T_CHAR) { - Printf(new_value, "\'%s\'", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value"))); - Setattr(n, "value", new_value); - } - - const String *outattributes = Getattr(n, "tmap:cstype:outattributes"); - if (outattributes) - Printf(constants_code, " %s\n", outattributes); - - const String *methodmods = Getattr(n, "feature:cs:methodmodifiers"); - methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - - Printf(constants_code, " %s %s %s %s = ", methodmods, (const_feature_flag ? "const" : "static readonly"), return_type, itemname); - - // Check for the %csconstvalue feature - String *value = Getattr(n, "feature:cs:constvalue"); - - if (value) { - Printf(constants_code, "%s;\n", value); - } else if (!const_feature_flag) { - // Default enum and constant handling will work with any type of C constant and initialises the C# variable from C through a PINVOKE call. - - if (classname_substituted_flag) { - if (SwigType_isenum(t)) { - // This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on) - Printf(constants_code, "(%s)%s.%s();\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname)); - } else { - // This handles function pointers using the %constant directive - Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname)); - } - } else { - Printf(constants_code, "%s.%s();\n", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname)); - } - - // Each constant and enum value is wrapped with a separate PInvoke function call - SetFlag(n, "feature:immutable"); - enum_constant_flag = true; - variableWrapper(n); - enum_constant_flag = false; - } else { - // Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code - if (Getattr(n, "wrappedasconstant")) { - if (SwigType_type(t) == T_CHAR) { - if (SwigType_type(valuetype) == T_CHAR) - Printf(constants_code, "\'%(hexescape)s\';\n", Getattr(n, "staticmembervariableHandler:value")); - else - Printf(constants_code, "(char)%s;\n", Getattr(n, "staticmembervariableHandler:value")); - } else { - Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value")); - } - } else { - Printf(constants_code, "%s;\n", Getattr(n, "value")); - } - } - - // Emit the generated code to appropriate place - // Enums only emit the intermediate and PINVOKE methods, so no proxy or module class wrapper methods needed - if (!is_enum_item) { - if (proxy_flag && wrapping_member_flag) - Printv(proxy_class_constants_code, constants_code, NIL); - else - Printv(module_class_constants_code, constants_code, NIL); - } - // Cleanup - Swig_restore(n); - Delete(new_value); - Delete(return_type); - Delete(constants_code); - return SWIG_OK; - } - - /* ----------------------------------------------------------------------------- - * insertDirective() - * ----------------------------------------------------------------------------- */ - - virtual int insertDirective(Node *n) { - int ret = SWIG_OK; - String *code = Getattr(n, "code"); - String *section = Getattr(n, "section"); - Replaceall(code, "$module", module_class_name); - Replaceall(code, "$imclassname", imclass_name); - Replaceall(code, "$dllimport", dllimport); - - if (!ImportMode && (Cmp(section, "proxycode") == 0)) { - if (proxy_class_code) { - Swig_typemap_replace_embedded_typemap(code, n); - int offset = Len(code) > 0 && *Char(code) == '\n' ? 1 : 0; - Printv(proxy_class_code, Char(code) + offset, "\n", NIL); - } - } else { - ret = Language::insertDirective(n); - } - return ret; - } - - /* ----------------------------------------------------------------------------- - * pragmaDirective() - * - * Valid Pragmas: - * imclassbase - base (extends) for the intermediary class - * imclassclassmodifiers - class modifiers for the intermediary class - * imclasscode - text (C# code) is copied verbatim to the intermediary class - * imclassimports - import statements for the intermediary class - * imclassinterfaces - interface (implements) for the intermediary class - * - * modulebase - base (extends) for the module class - * moduleclassmodifiers - class modifiers for the module class - * modulecode - text (C# code) is copied verbatim to the module class - * moduleimports - import statements for the module class - * moduleinterfaces - interface (implements) for the module class - * - * ----------------------------------------------------------------------------- */ - - virtual int pragmaDirective(Node *n) { - if (!ImportMode) { - String *lang = Getattr(n, "lang"); - String *code = Getattr(n, "name"); - String *value = Getattr(n, "value"); - - if (Strcmp(lang, "csharp") == 0) { - - String *strvalue = NewString(value); - Replaceall(strvalue, "\\\"", "\""); - - if (Strcmp(code, "imclassbase") == 0) { - Delete(imclass_baseclass); - imclass_baseclass = Copy(strvalue); - } else if (Strcmp(code, "imclassclassmodifiers") == 0) { - Delete(imclass_class_modifiers); - imclass_class_modifiers = Copy(strvalue); - } else if (Strcmp(code, "imclasscode") == 0) { - Printf(imclass_class_code, "%s\n", strvalue); - } else if (Strcmp(code, "imclassimports") == 0) { - Delete(imclass_imports); - imclass_imports = Copy(strvalue); - } else if (Strcmp(code, "imclassinterfaces") == 0) { - Delete(imclass_interfaces); - imclass_interfaces = Copy(strvalue); - } else if (Strcmp(code, "modulebase") == 0) { - Delete(module_baseclass); - module_baseclass = Copy(strvalue); - } else if (Strcmp(code, "moduleclassmodifiers") == 0) { - Delete(module_class_modifiers); - module_class_modifiers = Copy(strvalue); - } else if (Strcmp(code, "modulecode") == 0) { - Printf(module_class_code, "%s\n", strvalue); - } else if (Strcmp(code, "moduleimports") == 0) { - Delete(module_imports); - module_imports = Copy(strvalue); - } else if (Strcmp(code, "moduleinterfaces") == 0) { - Delete(module_interfaces); - module_interfaces = Copy(strvalue); - } else { - Swig_error(input_file, line_number, "Unrecognized pragma.\n"); - } - Delete(strvalue); - } - } - return Language::pragmaDirective(n); - } - - /* ----------------------------------------------------------------------------- - * getQualifiedInterfaceName() - * ----------------------------------------------------------------------------- */ - - String *getQualifiedInterfaceName(Node *n) { - String *ret = Getattr(n, "interface:qname"); - if (!ret) { - String *nspace = Getattr(n, "sym:nspace"); - String *interface_name = Getattr(n, "interface:name"); - if (nspace) { - if (namespce) - ret = NewStringf("%s.%s.%s", namespce, nspace, interface_name); - else - ret = NewStringf("%s.%s", nspace, interface_name); - } else { - ret = Copy(interface_name); - } - Setattr(n, "interface:qname", ret); - } - return ret; - } - - /* ----------------------------------------------------------------------------- - * getInterfaceName() - * ----------------------------------------------------------------------------- */ - - String *getInterfaceName(SwigType *t, bool qualified) { - String *interface_name = NULL; - if (proxy_flag) { - Node *n = classLookup(t); - if (n && Getattr(n, "interface:name")) - interface_name = qualified ? getQualifiedInterfaceName(n) : Getattr(n, "interface:name"); - } - return interface_name; - } - - /* ----------------------------------------------------------------------------- - * addInterfaceNameAndUpcasts() - * ----------------------------------------------------------------------------- */ - - void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, List *base_list, SwigType *c_classname) { - for (Iterator it = First(base_list); it.item; it = Next(it)) { - Node *base = it.item; - SwigType *c_baseclassname = Getattr(base, "name"); - String *interface_name = Getattr(base, "interface:name"); - if (Len(interface_list)) - Append(interface_list, ", "); - Append(interface_list, interface_name); - - Node *attributes = NewHash(); - String *interface_code = Copy(typemapLookup(base, "csinterfacecode", Getattr(base, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACECODE_UNDEF, attributes)); - String *cptr_method_name = 0; - if (interface_code) { - Replaceall(interface_code, "$interfacename", interface_name); - Printv(interface_upcasts, interface_code, NIL); - cptr_method_name = Copy(Getattr(attributes, "tmap:csinterfacecode:cptrmethod")); - } - if (!cptr_method_name) - cptr_method_name = NewStringf("%s_GetInterfaceCPtr", interface_name); - Replaceall(cptr_method_name, ".", "_"); - Replaceall(cptr_method_name, "$interfacename", interface_name); - - String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); - - Delete(upcast_method_name); - Delete(cptr_method_name); - Delete(interface_code); - } - } - - /* ----------------------------------------------------------------------------- - * upcastsCode() - * - * Add code for C++ casting to base class - * ----------------------------------------------------------------------------- */ - - void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) { - String *wname = Swig_name_wrapper(upcast_method_name); - - Printv(imclass_cppcasts_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL); - Printf(imclass_cppcasts_code, " public static extern global::System.IntPtr %s(global::System.IntPtr jarg1);\n", upcast_method_name); - - Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name); - - String *classname = SwigType_namestr(c_classname); - String *baseclassname = SwigType_namestr(c_baseclassname); - if (smart) { - String *smartnamestr = SwigType_namestr(smart); - String *bsmartnamestr = SwigType_namestr(smart); - - // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates - SwigType *rclassname = SwigType_typedef_resolve_all(classname); - SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname); - Replaceall(bsmartnamestr, rclassname, rbaseclassname); - - Printv(upcasts_code, - "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n", - " return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n" - "}\n", "\n", NIL); - - Delete(rbaseclassname); - Delete(rclassname); - Delete(bsmartnamestr); - Delete(smartnamestr); - } else { - Printv(upcasts_code, - "SWIGEXPORT ", baseclassname, " * SWIGSTDCALL ", wname, "(", classname, " *jarg1) {\n", - " return (", baseclassname, " *)jarg1;\n" - "}\n", "\n", NIL); - } - - Delete(baseclassname); - Delete(classname); - Delete(wname); - } - - /* ----------------------------------------------------------------------------- - * emitProxyClassDefAndCPPCasts() - * ----------------------------------------------------------------------------- */ - - void emitProxyClassDefAndCPPCasts(Node *n) { - SwigType *c_classname = Getattr(n, "name"); - SwigType *c_baseclassname = NULL; - String *baseclass = NULL; - String *interface_list = NewStringEmpty(); - String *interface_upcasts = NewStringEmpty(); - SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); - bool feature_director = Swig_directorclass(n) ? true : false; - bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested"); - SwigType *smart = Swig_cparse_smartptr(n); - - // Inheritance from pure C# classes - Node *attributes = NewHash(); - const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE, attributes); - bool purebase_replace = GetFlag(attributes, "tmap:csbase:replace") ? true : false; - bool purebase_notderived = GetFlag(attributes, "tmap:csbase:notderived") ? true : false; - Delete(attributes); - - // C++ inheritance - if (!purebase_replace) { - List *baselist = Getattr(n, "bases"); - if (baselist) { - Iterator base = First(baselist); - while (base.item) { - if (!(GetFlag(base.item, "feature:ignore") || GetFlag(base.item, "feature:interface"))) { - SwigType *baseclassname = Getattr(base.item, "name"); - if (!c_baseclassname) { - String *name = getProxyName(baseclassname); - if (name) { - c_baseclassname = baseclassname; - baseclass = name; - } - } else { - /* Warn about multiple inheritance for additional base class(es) */ - String *proxyclassname = Getattr(n, "classtypeobj"); - Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s, base %s ignored. Multiple inheritance is not supported in C#.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname)); - } - } - base = Next(base); - } - } - } - List *interface_bases = Getattr(n, "interface:bases"); - if (interface_bases) - addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname); - - bool derived = baseclass != 0; - if (derived && purebase_notderived) - pure_baseclass = empty_string; - const String *wanted_base = baseclass ? baseclass : pure_baseclass; - - if (purebase_replace) { - wanted_base = pure_baseclass; - derived = false; - baseclass = NULL; - if (purebase_notderived) - Swig_error(Getfile(n), Getline(n), "The csbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type); - } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) { - Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s, base %s ignored. Multiple inheritance is not supported in C#. " - "Perhaps you need one of the 'replace' or 'notderived' attributes in the csbase typemap?\n", typemap_lookup_type, pure_baseclass); - } - - // Pure C# interfaces - const String *pure_interfaces = typemapLookup(n, derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE); - if (*Char(interface_list) && *Char(pure_interfaces)) - Append(interface_list, ", "); - Append(interface_list, pure_interfaces); - // Start writing the proxy class - if (!has_outerclass) - Printv(proxy_class_def, typemapLookup(n, "csimports", typemap_lookup_type, WARN_NONE), // Import statements - "\n", NIL); - - // Class attributes - const String *csattributes = typemapLookup(n, "csattributes", typemap_lookup_type, WARN_NONE); - if (csattributes && *Char(csattributes)) - Printf(proxy_class_def, "%s\n", csattributes); - - Printv(proxy_class_def, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers - " $csclassname", // Class name and base class - (*Char(wanted_base) || *Char(interface_list)) ? " : " : "", wanted_base, (*Char(wanted_base) && *Char(interface_list)) ? // Interfaces - ", " : "", interface_list, " {", derived ? typemapLookup(n, "csbody_derived", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF) : // main body of class - typemapLookup(n, "csbody", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class - NIL); - - // C++ destructor is wrapped by the Finalize and Dispose methods - - const char *tmap_method = derived ? "csdestruct_derived" : "csdestruct"; - const String *tm = typemapExists(n, tmap_method, typemap_lookup_type); - if (tm) { - Swig_error(Getfile(tm), Getline(tm), - "A deprecated %s typemap was found for %s, please remove it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps.\n", - tmap_method, proxy_class_name); - } - tmap_method = "csfinalize"; - tm = typemapExists(n, tmap_method, typemap_lookup_type); - if (tm) { - Swig_error(Getfile(tm), Getline(tm), - "A deprecated %s typemap was found for %s, please remove it and replace all csdestruct, csdestruct_derived and csfinalize typemaps by the csdispose, csdispose_derived, csdisposing and csdisposing_derived typemaps.\n", - tmap_method, proxy_class_name); - } - - tmap_method = derived ? "csdisposing_derived" : "csdisposing"; - String *destruct = NewString(""); - attributes = NewHash(); - const String *destruct_methodname = NULL; - const String *destruct_methodmodifiers = NULL; - const String *destruct_parameters = NULL; - if (derived) { - tm = typemapLookup(n, "csdisposing_derived", typemap_lookup_type, WARN_NONE, attributes); - destruct_methodname = Getattr(attributes, "tmap:csdisposing_derived:methodname"); - destruct_methodmodifiers = Getattr(attributes, "tmap:csdisposing_derived:methodmodifiers"); - destruct_parameters = Getattr(attributes, "tmap:csdisposing_derived:parameters"); - } else { - tm = typemapLookup(n, "csdisposing", typemap_lookup_type, WARN_NONE, attributes); - destruct_methodname = Getattr(attributes, "tmap:csdisposing:methodname"); - destruct_methodmodifiers = Getattr(attributes, "tmap:csdisposing:methodmodifiers"); - destruct_parameters = Getattr(attributes, "tmap:csdisposing:parameters"); - } - if (tm && *Char(tm)) { - if (!destruct_methodname) { - Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in %s typemap for %s\n", tmap_method, proxy_class_name); - } - if (!destruct_methodmodifiers) { - Swig_error(Getfile(n), Getline(n), - "No methodmodifiers attribute defined in %s typemap for %s.\n", tmap_method, proxy_class_name); - } - if (!destruct_parameters) - destruct_parameters = empty_string; - } - // Emit the Finalize and Dispose methods - if (tm) { - // Finalize and Dispose methods - Printv(proxy_class_def, typemapLookup(n, derived ? "csdispose_derived" : "csdispose", typemap_lookup_type, WARN_NONE), NIL); - // Dispose(bool disposing) method - Printv(destruct, tm, NIL); - if (*Char(destructor_call)) - Replaceall(destruct, "$imcall", destructor_call); - else - Replaceall(destruct, "$imcall", "throw new global::System.MethodAccessException(\"C++ destructor does not have public access\")"); - if (*Char(destruct)) { - Printv(proxy_class_def, "\n ", NIL); - const String *methodmods = Getattr(n, "destructmethodmodifiers"); - if (methodmods) - Printv(proxy_class_def, methodmods, NIL); - else - Printv(proxy_class_def, destruct_methodmodifiers, " ", derived ? "override" : "virtual", NIL); - Printv(proxy_class_def, " void ", destruct_methodname, "(", destruct_parameters, ") ", destruct, "\n", NIL); - } - } - if (*Char(interface_upcasts)) - Printv(proxy_class_def, interface_upcasts, NIL); - - if (feature_director) { - // Generate director connect method - // put this in classDirectorEnd ??? - Printf(proxy_class_code, " private void SwigDirectorConnect() {\n"); - - int i; - for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { - UpcallData *udata = Getitem(dmethods_seq, i); - String *method = Getattr(udata, "method"); - String *methid = Getattr(udata, "class_methodidx"); - String *overname = Getattr(udata, "overname"); - Printf(proxy_class_code, " if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s))\n", method, methid); - Printf(proxy_class_code, " swigDelegate%s = new SwigDelegate%s_%s(SwigDirectorMethod%s);\n", methid, proxy_class_name, methid, overname); - } - String *director_connect_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect"); - Printf(proxy_class_code, " %s.%s(swigCPtr", imclass_name, director_connect_method_name); - for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { - UpcallData *udata = Getitem(dmethods_seq, i); - String *methid = Getattr(udata, "class_methodidx"); - Printf(proxy_class_code, ", swigDelegate%s", methid); - } - Printf(proxy_class_code, ");\n"); - Printf(proxy_class_code, " }\n"); - - if (first_class_dmethod < curr_class_dmethod) { - // Only emit if there is at least one director method - Printf(proxy_class_code, "\n"); - Printf(proxy_class_code, " private bool SwigDerivedClassHasMethod(string methodName, global::System.Type[] methodTypes) {\n"); - Printf(proxy_class_code, " global::System.Reflection.MethodInfo[] methodInfos = this.GetType().GetMethods(\n"); - Printf(proxy_class_code, " global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance);\n"); - Printf(proxy_class_code, " foreach (global::System.Reflection.MethodInfo methodInfo in methodInfos) {\n"); - Printf(proxy_class_code, " if (methodInfo.DeclaringType == null)\n"); - Printf(proxy_class_code, " continue;\n\n"); - Printf(proxy_class_code, " if (methodInfo.Name != methodName)\n"); - Printf(proxy_class_code, " continue;\n\n"); - Printf(proxy_class_code, " var parameters = methodInfo.GetParameters();\n"); - Printf(proxy_class_code, " if (parameters.Length != methodTypes.Length)\n"); - Printf(proxy_class_code, " continue;\n\n"); - Printf(proxy_class_code, " bool parametersMatch = true;\n"); - Printf(proxy_class_code, " for (var i = 0; i < parameters.Length; i++) {\n"); - Printf(proxy_class_code, " if (parameters[i].ParameterType != methodTypes[i]) {\n"); - Printf(proxy_class_code, " parametersMatch = false;\n"); - Printf(proxy_class_code, " break;\n"); - Printf(proxy_class_code, " }\n"); - Printf(proxy_class_code, " }\n\n"); - Printf(proxy_class_code, " if (!parametersMatch)\n"); - Printf(proxy_class_code, " continue;\n\n"); - Printf(proxy_class_code, " if (methodInfo.IsVirtual && (methodInfo.DeclaringType.IsSubclassOf(typeof(%s))) &&\n", proxy_class_name); - Printf(proxy_class_code, " methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType) {\n"); - Printf(proxy_class_code, " return true;\n"); - Printf(proxy_class_code, " }\n"); - Printf(proxy_class_code, " }\n\n"); - Printf(proxy_class_code, " return false;\n"); - - /* Could add this code to cover corner case where the GetMethod() returns a method which allows type - * promotion, eg it will return foo(double), if looking for foo(int). - if (hasDerivedMethod) { - hasDerivedMethod = false; - if (methodInfo != null) - { - hasDerivedMethod = true; - ParameterInfo[] parameterArray1 = methodInfo.GetParameters(); - for (int i=0; i<methodTypes.Length; i++) - { - if (parameterArray1[0].ParameterType != methodTypes[0]) - { - hasDerivedMethod = false; - break; - } - } - } - } - */ - //Printf(proxy_class_code, " return hasDerivedMethod;\n"); - Printf(proxy_class_code, " }\n"); - } - - if (Len(director_delegate_callback) > 0) - Printv(proxy_class_code, director_delegate_callback, NIL); - if (Len(director_delegate_definitions) > 0) - Printv(proxy_class_code, "\n", director_delegate_definitions, NIL); - if (Len(director_delegate_instances) > 0) - Printv(proxy_class_code, "\n", director_delegate_instances, NIL); - if (Len(director_method_types) > 0) - Printv(proxy_class_code, "\n", director_method_types, NIL); - - Delete(director_callback_typedefs); - director_callback_typedefs = NULL; - Delete(director_callbacks); - director_callbacks = NULL; - Delete(director_delegate_callback); - director_delegate_callback = NULL; - Delete(director_delegate_definitions); - director_delegate_definitions = NULL; - Delete(director_delegate_instances); - director_delegate_instances = NULL; - Delete(director_method_types); - director_method_types = NULL; - Delete(director_connect_parms); - director_connect_parms = NULL; - Delete(director_connect_method_name); - } - - Delete(interface_upcasts); - Delete(interface_list); - Delete(attributes); - Delete(destruct); - - // Emit extra user code - Printv(proxy_class_def, typemapLookup(n, "cscode", typemap_lookup_type, WARN_NONE), // extra C# code - "\n", NIL); - - if (derived) { - String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); - Delete(upcast_method_name); - } - - Delete(smart); - } - - /* ---------------------------------------------------------------------- - * emitInterfaceDeclaration() - * ---------------------------------------------------------------------- */ - - void emitInterfaceDeclaration(Node *n, String *interface_name, File *f_interface) { - Printv(f_interface, typemapLookup(n, "csimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL); - Printv(f_interface, typemapLookup(n, "csinterfacemodifiers", Getattr(n, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF), NIL); - Printf(f_interface, " %s", interface_name); - if (List *baselist = Getattr(n, "bases")) { - String *bases = 0; - for (Iterator base = First(baselist); base.item; base = Next(base)) { - if (GetFlag(base.item, "feature:ignore") || !GetFlag(base.item, "feature:interface")) - continue; // TODO: warn about skipped non-interface bases - String *base_iname = Getattr(base.item, "interface:name"); - if (!bases) - bases = NewStringf(" : %s", base_iname); - else { - Append(bases, ", "); - Append(bases, base_iname); - } - } - if (bases) { - Printv(f_interface, bases, NIL); - Delete(bases); - } - } - Printf(f_interface, " {\n"); - - Node *attributes = NewHash(); - String *interface_code = Copy(typemapLookup(n, "csinterfacecode", Getattr(n, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACECODE_UNDEF, attributes)); - if (interface_code) { - String *interface_declaration = Copy(Getattr(attributes, "tmap:csinterfacecode:declaration")); - if (interface_declaration) { - Replaceall(interface_declaration, "$interfacename", interface_name); - Printv(f_interface, interface_declaration, NIL); - Delete(interface_declaration); - } - Delete(interface_code); - } - } - - /* ---------------------------------------------------------------------- - * classHandler() - * ---------------------------------------------------------------------- */ - - virtual int classHandler(Node *n) { - String *nspace = getNSpace(); - File *f_proxy = NULL; - File *f_interface = NULL; - // save class local variables - String *old_proxy_class_name = proxy_class_name; - String *old_full_imclass_name = full_imclass_name; - String *old_destructor_call = destructor_call; - String *old_proxy_class_constants_code = proxy_class_constants_code; - String *old_proxy_class_def = proxy_class_def; - String *old_proxy_class_code = proxy_class_code; - bool has_outerclass = Getattr(n, "nested:outer") && !GetFlag(n, "feature:flatnested"); - String *old_interface_class_code = interface_class_code; - interface_class_code = 0; - - if (proxy_flag) { - proxy_class_name = NewString(Getattr(n, "sym:name")); - String *interface_name = GetFlag(n, "feature:interface") ? Getattr(n, "interface:name") : 0; - if (Node *outer = Getattr(n, "nested:outer")) { - String *outerClassesPrefix = Copy(Getattr(outer, "sym:name")); - for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) { - Push(outerClassesPrefix, "."); - Push(outerClassesPrefix, Getattr(outer, "sym:name")); - } - String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix; - if (!addSymbol(proxy_class_name, n, fnspace)) - return SWIG_ERROR; - if (interface_name && !addInterfaceSymbol(interface_name, n, fnspace)) - return SWIG_ERROR; - if (nspace) - Delete(fnspace); - Delete(outerClassesPrefix); - } else { - if (!addSymbol(proxy_class_name, n, nspace)) - return SWIG_ERROR; - if (interface_name && !addInterfaceSymbol(interface_name, n, nspace)) - return SWIG_ERROR; - } - - if (!nspace) { - full_imclass_name = NewStringf("%s", imclass_name); - if (Cmp(proxy_class_name, imclass_name) == 0) { - Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name); - Exit(EXIT_FAILURE); - } - - if (Cmp(proxy_class_name, module_class_name) == 0) { - Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name); - Exit(EXIT_FAILURE); - } - } else { - if (namespce) { - full_imclass_name = NewStringf("%s.%s", namespce, imclass_name); - } else { - full_imclass_name = NewStringf("%s", imclass_name); - } - } - - if (!has_outerclass) { - String *output_directory = outputDirectory(nspace); - f_proxy = getOutputFile(output_directory, proxy_class_name); - - addOpenNamespace(nspace, f_proxy); - Delete(output_directory); - } - else - ++nesting_depth; - - proxy_class_def = NewString(""); - proxy_class_code = NewString(""); - destructor_call = NewString(""); - proxy_class_constants_code = NewString(""); - - if (GetFlag(n, "feature:interface")) { - interface_class_code = NewString(""); - String *output_directory = outputDirectory(nspace); - f_interface = getOutputFile(output_directory, interface_name); - addOpenNamespace(nspace, f_interface); - emitInterfaceDeclaration(n, interface_name, interface_class_code); - Delete(output_directory); - } - } - - Language::classHandler(n); - - if (proxy_flag) { - - emitProxyClassDefAndCPPCasts(n); - - String *csclazzname = Swig_name_member(getNSpace(), getClassPrefix(), ""); // mangled full proxy class name - - Replaceall(proxy_class_def, "$csclassname", proxy_class_name); - Replaceall(proxy_class_code, "$csclassname", proxy_class_name); - Replaceall(proxy_class_constants_code, "$csclassname", proxy_class_name); - Replaceall(interface_class_code, "$csclassname", proxy_class_name); - - Replaceall(proxy_class_def, "$csclazzname", csclazzname); - Replaceall(proxy_class_code, "$csclazzname", csclazzname); - Replaceall(proxy_class_constants_code, "$csclazzname", csclazzname); - Replaceall(interface_class_code, "$csclazzname", csclazzname); - - Replaceall(proxy_class_def, "$module", module_class_name); - Replaceall(proxy_class_code, "$module", module_class_name); - Replaceall(proxy_class_constants_code, "$module", module_class_name); - Replaceall(interface_class_code, "$module", module_class_name); - - Replaceall(proxy_class_def, "$imclassname", full_imclass_name); - Replaceall(proxy_class_code, "$imclassname", full_imclass_name); - Replaceall(proxy_class_constants_code, "$imclassname", full_imclass_name); - Replaceall(interface_class_code, "$imclassname", full_imclass_name); - - Replaceall(proxy_class_def, "$dllimport", dllimport); - Replaceall(proxy_class_code, "$dllimport", dllimport); - Replaceall(proxy_class_constants_code, "$dllimport", dllimport); - Replaceall(interface_class_code, "$dllimport", dllimport); - - if (!has_outerclass) - Printv(f_proxy, proxy_class_def, proxy_class_code, NIL); - else { - Swig_offset_string(proxy_class_def, nesting_depth); - Append(old_proxy_class_code, proxy_class_def); - Swig_offset_string(proxy_class_code, nesting_depth); - Append(old_proxy_class_code, proxy_class_code); - } - - // Write out all the constants - if (Len(proxy_class_constants_code) != 0) { - if (!has_outerclass) - Printv(f_proxy, proxy_class_constants_code, NIL); - else { - Swig_offset_string(proxy_class_constants_code, nesting_depth); - Append(old_proxy_class_code, proxy_class_constants_code); - } - } - if (!has_outerclass) { - Printf(f_proxy, "}\n"); - addCloseNamespace(nspace, f_proxy); - if (f_proxy != f_single_out) - Delete(f_proxy); - f_proxy = NULL; - } else { - for (int i = 0; i < nesting_depth; ++i) - Append(old_proxy_class_code, " "); - Append(old_proxy_class_code, "}\n\n"); - --nesting_depth; - } - - if (f_interface) { - Printv(f_interface, interface_class_code, "}\n", NIL); - addCloseNamespace(nspace, f_interface); - if (f_interface != f_single_out) - Delete(f_interface); - f_interface = 0; - } - - emitDirectorExtraMethods(n); - - Delete(interface_class_code); - interface_class_code = old_interface_class_code; - Delete(csclazzname); - Delete(proxy_class_name); - proxy_class_name = old_proxy_class_name; - Delete(full_imclass_name); - full_imclass_name = old_full_imclass_name; - Delete(destructor_call); - destructor_call = old_destructor_call; - Delete(proxy_class_constants_code); - proxy_class_constants_code = old_proxy_class_constants_code; - Delete(proxy_class_def); - proxy_class_def = old_proxy_class_def; - Delete(proxy_class_code); - proxy_class_code = old_proxy_class_code; - } - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * memberfunctionHandler() - * ---------------------------------------------------------------------- */ - - virtual int memberfunctionHandler(Node *n) { - Language::memberfunctionHandler(n); - - if (proxy_flag) { - String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name); - Setattr(n, "proxyfuncname", Getattr(n, "sym:name")); - Setattr(n, "imfuncname", intermediary_function_name); - proxyClassFunctionHandler(n); - Delete(overloaded_name); - } - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * staticmemberfunctionHandler() - * ---------------------------------------------------------------------- */ - - virtual int staticmemberfunctionHandler(Node *n) { - - static_flag = true; - Language::staticmemberfunctionHandler(n); - - if (proxy_flag) { - String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name); - Setattr(n, "proxyfuncname", Getattr(n, "sym:name")); - Setattr(n, "imfuncname", intermediary_function_name); - proxyClassFunctionHandler(n); - Delete(overloaded_name); - } - static_flag = false; - - return SWIG_OK; - } - - - /* ----------------------------------------------------------------------------- - * proxyClassFunctionHandler() - * - * Function called for creating a C# wrapper function around a c++ function in the - * proxy class. Used for both static and non-static C++ class functions. - * C++ class static functions map to C# static functions. - * Two extra attributes in the Node must be available. These are "proxyfuncname" - - * the name of the C# class proxy function, which in turn will call "imfuncname" - - * the intermediary (PInvoke) function name in the intermediary class. - * ----------------------------------------------------------------------------- */ - - void proxyClassFunctionHandler(Node *n) { - SwigType *t = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - String *intermediary_function_name = Getattr(n, "imfuncname"); - String *proxy_function_name = Getattr(n, "proxyfuncname"); - String *tm; - Parm *p; - Parm *last_parm = 0; - int i; - String *imcall = NewString(""); - String *return_type = NewString(""); - String *function_code = NewString(""); - bool setter_flag = false; - String *pre_code = NewString(""); - String *post_code = NewString(""); - String *terminator_code = NewString(""); - bool is_interface = GetFlag(parentNode(n), "feature:interface") && !checkAttribute(n, "kind", "variable") - && !static_flag && Getattr(n, "interface:owner") == 0; - - if (!proxy_flag) - return; - - // Wrappers not wanted for some methods where the parameters cannot be overloaded in C# - if (Getattr(n, "overload:ignore")) - return; - - // Don't generate proxy method for additional explicitcall method used in directors - if (GetFlag(n, "explicitcall")) - return; - - if (l) { - if (SwigType_type(Getattr(l, "type")) == T_VOID) { - l = nextSibling(l); - } - } - - /* Attach the non-standard typemaps to the parameter list */ - Swig_typemap_attach_parms("in", l, NULL); - Swig_typemap_attach_parms("cstype", l, NULL); - Swig_typemap_attach_parms("csin", l, NULL); - - /* Get return types */ - if ((tm = Swig_typemap_lookup("cstype", n, "", 0))) { - // Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type - SwigType *covariant = Getattr(n, "covariant"); - String *cstypeout = Getattr(n, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap - if (cstypeout) - tm = cstypeout; - substituteClassname(covariant ? covariant : t, tm); - Printf(return_type, "%s", tm); - if (covariant) - Swig_warning(WARN_CSHARP_COVARIANT_RET, input_file, line_number, - "Covariant return types not supported in C#. Proxy method will return %s.\n", SwigType_str(covariant, 0)); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0)); - } - - if (wrapping_member_flag && !enum_constant_flag) { - // Properties - setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) == 0); - if (setter_flag) - Swig_typemap_attach_parms("csvarin", l, NULL); - } - - /* Start generating the proxy function */ - const String *outattributes = Getattr(n, "tmap:cstype:outattributes"); - if (outattributes) - Printf(function_code, " %s\n", outattributes); - const String *csattributes = Getattr(n, "feature:cs:attributes"); - if (csattributes) - Printf(function_code, " %s\n", csattributes); - const String *methodmods = Getattr(n, "feature:cs:methodmodifiers"); - if (methodmods) { - if (is_smart_pointer()) { - // Smart pointer classes do not mirror the inheritance hierarchy of the underlying pointer type, so no virtual/override/new required. - String *mmods = Copy(methodmods); - Replaceall(mmods, "override", ""); - Replaceall(mmods, "virtual", ""); - Replaceall(mmods, "new", ""); - Chop(mmods); // remove trailing whitespace - Printf(function_code, " %s ", mmods); - Delete(mmods); - } else { - Printf(function_code, " %s ", methodmods); - } - } else { - methodmods = (is_public(n) ? public_string : protected_string); - Printf(function_code, " %s ", methodmods); - if (!is_smart_pointer()) { - // Smart pointer classes do not mirror the inheritance hierarchy of the underlying pointer type, so no virtual/override/new required. - if (Getattr(n, "override")) - Printf(function_code, "override "); - else if (checkAttribute(n, "storage", "virtual")) - Printf(function_code, "virtual "); - if (Getattr(n, "hides")) - Printf(function_code, "new "); - } - } - if (static_flag) - Printf(function_code, "static "); - Printf(function_code, "%s %s(", return_type, proxy_function_name); - if (is_interface) - Printf(interface_class_code, " %s %s(", return_type, proxy_function_name); - - - Printv(imcall, full_imclass_name, ".$imfuncname(", NIL); - if (!static_flag) - Printf(imcall, "swigCPtr"); - - emit_mark_varargs(l); - - int gencomma = !static_flag; - - /* Output each parameter */ - for (i = 0, p = l; p; i++) { - - /* Ignored varargs */ - if (checkAttribute(p, "varargs:ignore", "1")) { - p = nextSibling(p); - continue; - } - - /* Ignored parameters */ - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - continue; - } - - /* Ignore the 'this' argument for variable wrappers */ - if (!(variable_wrapper_flag && i == 0)) { - SwigType *pt = Getattr(p, "type"); - String *param_type = NewString(""); - if (setter_flag) - last_parm = p; - - /* Get the C# parameter type */ - if ((tm = Getattr(p, "tmap:cstype"))) { - substituteClassname(pt, tm); - const String *inattributes = Getattr(p, "tmap:cstype:inattributes"); - Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - if (gencomma) - Printf(imcall, ", "); - - String *arg = makeParameterName(n, p, i, setter_flag); - - // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class) - if ((tm = Getattr(p, "tmap:csin"))) { - substituteClassname(pt, tm); - Replaceall(tm, "$csinput", arg); - String *pre = Getattr(p, "tmap:csin:pre"); - if (pre) { - substituteClassname(pt, pre); - Replaceall(pre, "$csinput", arg); - if (Len(pre_code) > 0) - Printf(pre_code, "\n"); - Printv(pre_code, pre, NIL); - } - String *post = Getattr(p, "tmap:csin:post"); - if (post) { - substituteClassname(pt, post); - Replaceall(post, "$csinput", arg); - if (Len(post_code) > 0) - Printf(post_code, "\n"); - Printv(post_code, post, NIL); - } - String *terminator = Getattr(p, "tmap:csin:terminator"); - if (terminator) { - substituteClassname(pt, terminator); - Replaceall(terminator, "$csinput", arg); - if (Len(terminator_code) > 0) - Insert(terminator_code, 0, "\n"); - Insert(terminator_code, 0, terminator); - } - Printv(imcall, tm, NIL); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Add parameter to proxy function */ - if (gencomma >= 2) { - Printf(function_code, ", "); - if (is_interface) - Printf(interface_class_code, ", "); - } - gencomma = 2; - Printf(function_code, "%s %s", param_type, arg); - if (is_interface) - Printf(interface_class_code, "%s %s", param_type, arg); - - Delete(arg); - Delete(param_type); - } - p = Getattr(p, "tmap:in:next"); - } - - Printf(imcall, ")"); - Printf(function_code, ")"); - if (is_interface) - Printf(interface_class_code, ");\n"); - - // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class) - if ((tm = Swig_typemap_lookup("csout", n, "", 0))) { - excodeSubstitute(n, tm, "csout", n); - bool is_pre_code = Len(pre_code) > 0; - bool is_post_code = Len(post_code) > 0; - bool is_terminator_code = Len(terminator_code) > 0; - if (is_pre_code || is_post_code || is_terminator_code) { - Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap - if (is_post_code) { - Insert(tm, 0, "\n try "); - Printv(tm, " finally {\n", post_code, "\n }", NIL); - } else { - Insert(tm, 0, "\n "); - } - if (is_pre_code) { - Insert(tm, 0, pre_code); - Insert(tm, 0, "\n"); - } - if (is_terminator_code) { - Printv(tm, "\n", terminator_code, NIL); - } - Insert(tm, 0, "{"); - Printf(tm, "\n }"); - } - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "true"); - else - Replaceall(tm, "$owner", "false"); - substituteClassname(t, tm); - - // For director methods: generate code to selectively make a normal polymorphic call or - // an explicit method call - needed to prevent infinite recursion calls in director methods. - Node *explicit_n = Getattr(n, "explicitcallnode"); - if (explicit_n) { - String *ex_overloaded_name = getOverloadedName(explicit_n); - String *ex_intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), ex_overloaded_name); - - String *ex_imcall = Copy(imcall); - Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name); - Replaceall(imcall, "$imfuncname", intermediary_function_name); - String *excode = NewString(""); - Node *directorNode = Getattr(n, "directorNode"); - UpcallData *udata = directorNode ? Getattr(directorNode, "upcalldata") : 0; - if (udata) { - String *methid = Getattr(udata, "class_methodidx"); - - if (!Cmp(return_type, "void")) - Printf(excode, "if (SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s)) %s; else %s", proxy_function_name, methid, ex_imcall, imcall); - else - Printf(excode, "(SwigDerivedClassHasMethod(\"%s\", swigMethodTypes%s) ? %s : %s)", proxy_function_name, methid, ex_imcall, imcall); - - Clear(imcall); - Printv(imcall, excode, NIL); - } else { - // probably an ignored method or nodirector - } - Delete(excode); - Delete(ex_overloaded_name); - } else { - Replaceall(imcall, "$imfuncname", intermediary_function_name); - } - Replaceall(tm, "$imfuncname", intermediary_function_name); - Replaceall(tm, "$imcall", imcall); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0)); - } - - if (wrapping_member_flag && !enum_constant_flag) { - // Properties - if (generate_property_declaration_flag) { // Ensure the declaration is generated just once should the property contain both a set and get - // Get the C# variable type - obtained differently depending on whether a setter is required. - String *variable_type = return_type; - if (setter_flag) { - assert(last_parm); // (last parameter is the only parameter for properties) - /* Get variable type - ensure the variable name is fully resolved during typemap lookup via the symbol table set in NewParmNode */ - SwigType *cvariable_type = Getattr(last_parm, "type"); - Parm *variable_parm = NewParmNode(cvariable_type, n); - if ((tm = Swig_typemap_lookup("cstype", variable_parm, "", 0))) { - String *cstypeout = Getattr(variable_parm, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap - if (cstypeout) - tm = cstypeout; - substituteClassname(cvariable_type, tm); - variable_type = tm; - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(cvariable_type, 0)); - } - } - const String *csattributes = Getattr(n, "feature:cs:attributes"); - if (csattributes) - Printf(proxy_class_code, " %s\n", csattributes); - const String *methodmods = Getattr(n, "feature:cs:methodmodifiers"); - if (!methodmods) - methodmods = (is_public(n) ? public_string : protected_string); - Printf(proxy_class_code, " %s %s%s %s {", methodmods, static_flag ? "static " : "", variable_type, variable_name); - } - generate_property_declaration_flag = false; - - if (setter_flag) { - // Setter method - assert(last_parm); // (last parameter is the only parameter for properties) - SwigType *cvariable_type = Getattr(last_parm, "type"); - Parm *variable_parm = NewParmNode(cvariable_type, n); - if ((tm = Swig_typemap_lookup("csvarin", variable_parm, "", 0))) { - substituteClassname(cvariable_type, tm); - Replaceall(tm, "$csinput", "value"); - Replaceall(tm, "$imfuncname", intermediary_function_name); - Replaceall(tm, "$imcall", imcall); - excodeSubstitute(n, tm, "csvarin", variable_parm); - Printf(proxy_class_code, "%s", tm); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(cvariable_type, 0)); - } - } else { - // Getter method - if ((tm = Swig_typemap_lookup("csvarout", n, "", 0))) { - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "true"); - else - Replaceall(tm, "$owner", "false"); - substituteClassname(t, tm); - Replaceall(tm, "$imfuncname", intermediary_function_name); - Replaceall(tm, "$imcall", imcall); - excodeSubstitute(n, tm, "csvarout", n); - Printf(proxy_class_code, "%s", tm); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarout typemap defined for %s\n", SwigType_str(t, 0)); - } - } - } else { - // Normal function call - Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string); - Printv(proxy_class_code, function_code, NIL); - } - - Delete(pre_code); - Delete(post_code); - Delete(terminator_code); - Delete(function_code); - Delete(return_type); - Delete(imcall); - } - - /* ---------------------------------------------------------------------- - * constructorHandler() - * ---------------------------------------------------------------------- */ - - virtual int constructorHandler(Node *n) { - - ParmList *l = Getattr(n, "parms"); - String *tm; - Parm *p; - int i; - String *function_code = NewString(""); - String *helper_code = NewString(""); // Holds code for the constructor helper method generated only when the csin typemap has code in the pre or post attributes - String *helper_args = NewString(""); - String *pre_code = NewString(""); - String *post_code = NewString(""); - String *terminator_code = NewString(""); - String *im_return_type = NewString(""); - bool feature_director = (parentNode(n) && Swig_directorclass(n)); - - Language::constructorHandler(n); - - // Wrappers not wanted for some methods where the parameters cannot be overloaded in C# - if (Getattr(n, "overload:ignore")) - return SWIG_OK; - - if (proxy_flag) { - String *overloaded_name = getOverloadedName(n); - String *mangled_overname = Swig_name_construct(getNSpace(), overloaded_name); - String *imcall = NewString(""); - - const String *csattributes = Getattr(n, "feature:cs:attributes"); - if (csattributes) { - Printf(function_code, " %s\n", csattributes); - Printf(helper_code, " %s\n", csattributes); - } - const String *methodmods = Getattr(n, "feature:cs:methodmodifiers"); - methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - - tm = Getattr(n, "tmap:imtype"); // typemaps were attached earlier to the node - String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap - if (imtypeout) - tm = imtypeout; - Printf(im_return_type, "%s", tm); - - Printf(function_code, " %s %s(", methodmods, proxy_class_name); - Printf(helper_code, " static private %s SwigConstruct%s(", im_return_type, proxy_class_name); - - Printv(imcall, full_imclass_name, ".", mangled_overname, "(", NIL); - - /* Attach the non-standard typemaps to the parameter list */ - Swig_typemap_attach_parms("in", l, NULL); - Swig_typemap_attach_parms("cstype", l, NULL); - Swig_typemap_attach_parms("csin", l, NULL); - - emit_mark_varargs(l); - - int gencomma = 0; - - /* Output each parameter */ - for (i = 0, p = l; p; i++) { - - /* Ignored varargs */ - if (checkAttribute(p, "varargs:ignore", "1")) { - p = nextSibling(p); - continue; - } - - /* Ignored parameters */ - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - continue; - } - - SwigType *pt = Getattr(p, "type"); - String *param_type = NewString(""); - - /* Get the C# parameter type */ - if ((tm = Getattr(p, "tmap:cstype"))) { - substituteClassname(pt, tm); - const String *inattributes = Getattr(p, "tmap:cstype:inattributes"); - Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - if (gencomma) - Printf(imcall, ", "); - - String *arg = makeParameterName(n, p, i, false); - String *cshin = 0; - - // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class) - if ((tm = Getattr(p, "tmap:csin"))) { - substituteClassname(pt, tm); - Replaceall(tm, "$csinput", arg); - String *pre = Getattr(p, "tmap:csin:pre"); - if (pre) { - substituteClassname(pt, pre); - Replaceall(pre, "$csinput", arg); - if (Len(pre_code) > 0) - Printf(pre_code, "\n"); - Printv(pre_code, pre, NIL); - } - String *post = Getattr(p, "tmap:csin:post"); - if (post) { - substituteClassname(pt, post); - Replaceall(post, "$csinput", arg); - if (Len(post_code) > 0) - Printf(post_code, "\n"); - Printv(post_code, post, NIL); - } - String *terminator = Getattr(p, "tmap:csin:terminator"); - if (terminator) { - substituteClassname(pt, terminator); - Replaceall(terminator, "$csinput", arg); - if (Len(terminator_code) > 0) - Insert(terminator_code, 0, "\n"); - Insert(terminator_code, 0, terminator); - } - cshin = Getattr(p, "tmap:csin:cshin"); - if (cshin) - Replaceall(cshin, "$csinput", arg); - Printv(imcall, tm, NIL); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Add parameter to proxy function */ - if (gencomma) { - Printf(function_code, ", "); - Printf(helper_code, ", "); - Printf(helper_args, ", "); - } - Printf(function_code, "%s %s", param_type, arg); - Printf(helper_code, "%s %s", param_type, arg); - Printf(helper_args, "%s", cshin ? cshin : arg); - ++gencomma; - - Delete(cshin); - Delete(arg); - Delete(param_type); - p = Getattr(p, "tmap:in:next"); - } - - Printf(imcall, ")"); - - Printf(function_code, ")"); - Printf(helper_code, ")"); - - /* Insert the csconstruct typemap, doing the replacement for $directorconnect, as needed */ - Hash *attributes = NewHash(); - String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj"); - String *construct_tm = Copy(typemapLookup(n, "csconstruct", typemap_lookup_type, - WARN_CSHARP_TYPEMAP_CSCONSTRUCT_UNDEF, attributes)); - if (construct_tm) { - if (!feature_director) { - Replaceall(construct_tm, "$directorconnect", ""); - } else { - String *connect_attr = Getattr(attributes, "tmap:csconstruct:directorconnect"); - - if (connect_attr) { - Replaceall(construct_tm, "$directorconnect", connect_attr); - } else { - Swig_warning(WARN_CSHARP_NO_DIRECTORCONNECT_ATTR, input_file, line_number, "\"directorconnect\" attribute missing in %s \"csconstruct\" typemap.\n", - Getattr(n, "name")); - Replaceall(construct_tm, "$directorconnect", ""); - } - } - - Printv(function_code, " ", construct_tm, NIL); - } - - excodeSubstitute(n, function_code, "csconstruct", attributes); - - bool is_pre_code = Len(pre_code) > 0; - bool is_post_code = Len(post_code) > 0; - bool is_terminator_code = Len(terminator_code) > 0; - if (is_pre_code || is_post_code || is_terminator_code) { - Printf(helper_code, " {\n"); - if (is_pre_code) { - Printv(helper_code, pre_code, "\n", NIL); - } - if (is_post_code) { - Printf(helper_code, " try {\n"); - Printv(helper_code, " return ", imcall, ";\n", NIL); - Printv(helper_code, " } finally {\n", post_code, "\n }", NIL); - } else { - Printv(helper_code, " return ", imcall, ";", NIL); - } - if (is_terminator_code) { - Printv(helper_code, "\n", terminator_code, NIL); - } - Printf(helper_code, "\n }\n"); - String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", proxy_class_name, proxy_class_name, helper_args); - String *im_outattributes = Getattr(n, "tmap:imtype:outattributes"); - if (im_outattributes) - Printf(proxy_class_code, " %s\n", im_outattributes); - Printv(proxy_class_code, helper_code, "\n", NIL); - Replaceall(function_code, "$imcall", helper_name); - Delete(helper_name); - } else { - Replaceall(function_code, "$imcall", imcall); - } - - Printv(proxy_class_code, function_code, "\n", NIL); - - Delete(helper_args); - Delete(im_return_type); - Delete(pre_code); - Delete(post_code); - Delete(terminator_code); - Delete(construct_tm); - Delete(attributes); - Delete(overloaded_name); - Delete(imcall); - } - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * destructorHandler() - * ---------------------------------------------------------------------- */ - - virtual int destructorHandler(Node *n) { - Language::destructorHandler(n); - String *symname = Getattr(n, "sym:name"); - - if (proxy_flag) { - Printv(destructor_call, full_imclass_name, ".", Swig_name_destroy(getNSpace(), symname), "(swigCPtr)", NIL); - const String *methodmods = Getattr(n, "feature:cs:methodmodifiers"); - if (methodmods) - Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods); - } - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * membervariableHandler() - * ---------------------------------------------------------------------- */ - - virtual int membervariableHandler(Node *n) { - - generate_property_declaration_flag = true; - variable_name = Getattr(n, "sym:name"); - wrapping_member_flag = true; - variable_wrapper_flag = true; - Language::membervariableHandler(n); - wrapping_member_flag = false; - variable_wrapper_flag = false; - generate_property_declaration_flag = false; - - Printf(proxy_class_code, "\n }\n\n"); - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * staticmembervariableHandler() - * ---------------------------------------------------------------------- */ - - virtual int staticmembervariableHandler(Node *n) { - - bool static_const_member_flag = (Getattr(n, "value") == 0); - - generate_property_declaration_flag = true; - variable_name = Getattr(n, "sym:name"); - wrapping_member_flag = true; - static_flag = true; - Language::staticmembervariableHandler(n); - wrapping_member_flag = false; - static_flag = false; - generate_property_declaration_flag = false; - - if (static_const_member_flag) - Printf(proxy_class_code, "\n }\n\n"); - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * memberconstantHandler() - * ---------------------------------------------------------------------- */ - - virtual int memberconstantHandler(Node *n) { - variable_name = Getattr(n, "sym:name"); - wrapping_member_flag = true; - Language::memberconstantHandler(n); - wrapping_member_flag = false; - return SWIG_OK; - } - - /* ----------------------------------------------------------------------------- - * getOverloadedName() - * ----------------------------------------------------------------------------- */ - - String *getOverloadedName(Node *n) { - - /* A C# HandleRef is used for all classes in the SWIG intermediary class. - * The intermediary class methods are thus mangled when overloaded to give - * a unique name. */ - String *overloaded_name = NewStringf("%s", Getattr(n, "sym:name")); - - if (Getattr(n, "sym:overloaded")) { - Printv(overloaded_name, Getattr(n, "sym:overname"), NIL); - } - - return overloaded_name; - } - - /* ----------------------------------------------------------------------------- - * moduleClassFunctionHandler() - * ----------------------------------------------------------------------------- */ - - void moduleClassFunctionHandler(Node *n) { - SwigType *t = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - String *tm; - Parm *p; - Parm *last_parm = 0; - int i; - String *imcall = NewString(""); - String *return_type = NewString(""); - String *function_code = NewString(""); - int num_arguments = 0; - String *overloaded_name = getOverloadedName(n); - String *func_name = NULL; - bool setter_flag = false; - String *pre_code = NewString(""); - String *post_code = NewString(""); - String *terminator_code = NewString(""); - - if (l) { - if (SwigType_type(Getattr(l, "type")) == T_VOID) { - l = nextSibling(l); - } - } - - /* Attach the non-standard typemaps to the parameter list */ - Swig_typemap_attach_parms("cstype", l, NULL); - Swig_typemap_attach_parms("csin", l, NULL); - - /* Get return types */ - if ((tm = Swig_typemap_lookup("cstype", n, "", 0))) { - String *cstypeout = Getattr(n, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap - if (cstypeout) - tm = cstypeout; - substituteClassname(t, tm); - Printf(return_type, "%s", tm); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0)); - } - - /* Change function name for global variables */ - if (proxy_flag && global_variable_flag) { - // Capitalize the first letter in the variable to create the getter/setter function name - func_name = NewString(""); - setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), variable_name)) == 0); - if (setter_flag) - Printf(func_name, "set"); - else - Printf(func_name, "get"); - Putc(toupper((int) *Char(variable_name)), func_name); - Printf(func_name, "%s", Char(variable_name) + 1); - if (setter_flag) - Swig_typemap_attach_parms("csvarin", l, NULL); - } else { - func_name = Copy(Getattr(n, "sym:name")); - } - - /* Start generating the function */ - const String *outattributes = Getattr(n, "tmap:cstype:outattributes"); - if (outattributes) - Printf(function_code, " %s\n", outattributes); - const String *csattributes = Getattr(n, "feature:cs:attributes"); - if (csattributes) - Printf(function_code, " %s\n", csattributes); - const String *methodmods = Getattr(n, "feature:cs:methodmodifiers"); - methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - Printf(function_code, " %s static %s %s(", methodmods, return_type, func_name); - Printv(imcall, imclass_name, ".", overloaded_name, "(", NIL); - - /* Get number of required and total arguments */ - num_arguments = emit_num_arguments(l); - - bool global_or_member_variable = global_variable_flag || (wrapping_member_flag && !enum_constant_flag); - int gencomma = 0; - - /* Output each parameter */ - for (i = 0, p = l; i < num_arguments; i++) { - - /* Ignored parameters */ - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *param_type = NewString(""); - last_parm = p; - - /* Get the C# parameter type */ - if ((tm = Getattr(p, "tmap:cstype"))) { - substituteClassname(pt, tm); - const String *inattributes = Getattr(p, "tmap:cstype:inattributes"); - Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - if (gencomma) - Printf(imcall, ", "); - - String *arg = makeParameterName(n, p, i, global_or_member_variable); - - // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class) - if ((tm = Getattr(p, "tmap:csin"))) { - substituteClassname(pt, tm); - Replaceall(tm, "$csinput", arg); - String *pre = Getattr(p, "tmap:csin:pre"); - if (pre) { - substituteClassname(pt, pre); - Replaceall(pre, "$csinput", arg); - if (Len(pre_code) > 0) - Printf(pre_code, "\n"); - Printv(pre_code, pre, NIL); - } - String *post = Getattr(p, "tmap:csin:post"); - if (post) { - substituteClassname(pt, post); - Replaceall(post, "$csinput", arg); - if (Len(post_code) > 0) - Printf(post_code, "\n"); - Printv(post_code, post, NIL); - } - String *terminator = Getattr(p, "tmap:csin:terminator"); - if (terminator) { - substituteClassname(pt, terminator); - Replaceall(terminator, "$csinput", arg); - if (Len(terminator_code) > 0) - Insert(terminator_code, 0, "\n"); - Insert(terminator_code, 0, terminator); - } - Printv(imcall, tm, NIL); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Add parameter to module class function */ - if (gencomma >= 2) - Printf(function_code, ", "); - gencomma = 2; - Printf(function_code, "%s %s", param_type, arg); - - p = Getattr(p, "tmap:in:next"); - Delete(arg); - Delete(param_type); - } - - Printf(imcall, ")"); - Printf(function_code, ")"); - - // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in module class) - if ((tm = Swig_typemap_lookup("csout", n, "", 0))) { - excodeSubstitute(n, tm, "csout", n); - bool is_pre_code = Len(pre_code) > 0; - bool is_post_code = Len(post_code) > 0; - bool is_terminator_code = Len(terminator_code) > 0; - if (is_pre_code || is_post_code || is_terminator_code) { - Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap - if (is_post_code) { - Insert(tm, 0, "\n try "); - Printv(tm, " finally {\n", post_code, "\n }", NIL); - } else { - Insert(tm, 0, "\n "); - } - if (is_pre_code) { - Insert(tm, 0, pre_code); - Insert(tm, 0, "\n"); - } - if (is_terminator_code) { - Printv(tm, "\n", terminator_code, NIL); - } - Insert(tm, 0, "{"); - Printf(tm, "\n }"); - } - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "true"); - else - Replaceall(tm, "$owner", "false"); - substituteClassname(t, tm); - Replaceall(tm, "$imfuncname", overloaded_name); - Replaceall(tm, "$imcall", imcall); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0)); - } - - if (proxy_flag && global_variable_flag) { - // Properties - if (generate_property_declaration_flag) { // Ensure the declaration is generated just once should the property contain both a set and get - // Get the C# variable type - obtained differently depending on whether a setter is required. - String *variable_type = return_type; - if (setter_flag) { - p = last_parm; // (last parameter is the only parameter for properties) - SwigType *pt = Getattr(p, "type"); - if ((tm = Getattr(p, "tmap:cstype"))) { - substituteClassname(pt, tm); - String *cstypeout = Getattr(p, "tmap:cstype:out"); // the type in the cstype typemap's out attribute overrides the type in the typemap - variable_type = cstypeout ? cstypeout : tm; - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(pt, 0)); - } - } - const String *csattributes = Getattr(n, "feature:cs:attributes"); - if (csattributes) - Printf(module_class_code, " %s\n", csattributes); - const String *methodmods = Getattr(n, "feature:cs:methodmodifiers"); - if (!methodmods) - methodmods = (is_public(n) ? public_string : protected_string); - Printf(module_class_code, " %s static %s %s {", methodmods, variable_type, variable_name); - } - generate_property_declaration_flag = false; - - if (setter_flag) { - // Setter method - p = last_parm; // (last parameter is the only parameter for properties) - SwigType *pt = Getattr(p, "type"); - if ((tm = Getattr(p, "tmap:csvarin"))) { - substituteClassname(pt, tm); - Replaceall(tm, "$csinput", "value"); - Replaceall(tm, "$imfuncname", overloaded_name); - Replaceall(tm, "$imcall", imcall); - excodeSubstitute(n, tm, "csvarin", p); - Printf(module_class_code, "%s", tm); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(pt, 0)); - } - } else { - // Getter method - if ((tm = Swig_typemap_lookup("csvarout", n, "", 0))) { - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "true"); - else - Replaceall(tm, "$owner", "false"); - substituteClassname(t, tm); - Replaceall(tm, "$imfuncname", overloaded_name); - Replaceall(tm, "$imcall", imcall); - excodeSubstitute(n, tm, "csvarout", n); - Printf(module_class_code, "%s", tm); - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarout typemap defined for %s\n", SwigType_str(t, 0)); - } - } - } else { - // Normal function call - Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string); - Printv(module_class_code, function_code, NIL); - } - - Delete(pre_code); - Delete(post_code); - Delete(terminator_code); - Delete(function_code); - Delete(return_type); - Delete(imcall); - Delete(func_name); - } - - /*---------------------------------------------------------------------- - * replaceSpecialVariables() - *--------------------------------------------------------------------*/ - - virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) { - (void)method; - SwigType *type = Getattr(parm, "type"); - substituteClassname(type, tm); - } - - /*---------------------------------------------------------------------- - * decodeEnumFeature() - * Decode the possible enum features, which are one of: - * %csenum(simple) - * %csenum(typeunsafe) - default - * %csenum(typesafe) - * %csenum(proper) - *--------------------------------------------------------------------*/ - - EnumFeature decodeEnumFeature(Node *n) { - EnumFeature enum_feature = TypeunsafeEnum; - String *feature = Getattr(n, "feature:cs:enum"); - if (feature) { - if (Cmp(feature, "simple") == 0) - enum_feature = SimpleEnum; - else if (Cmp(feature, "typesafe") == 0) - enum_feature = TypesafeEnum; - else if (Cmp(feature, "proper") == 0) - enum_feature = ProperEnum; - } - return enum_feature; - } - - /* ----------------------------------------------------------------------- - * enumValue() - * This method will return a string with an enum value to use in C# generated - * code. If the %csconst feature is not used, the string will contain the intermediary - * class call to obtain the enum value. The intermediary class and PINVOKE methods to obtain - * the enum value will be generated. Otherwise the C/C++ enum value will be used if there - * is one and hopefully it will compile as C# code - e.g. 20 as in: enum E{e=20}; - * The %csconstvalue feature overrides all other ways to generate the constant value. - * The caller must delete memory allocated for the returned string. - * ------------------------------------------------------------------------ */ - - String *enumValue(Node *n) { - String *symname = Getattr(n, "sym:name"); - - // Check for the %csconstvalue feature - String *value = Getattr(n, "feature:cs:constvalue"); - - if (!value) { - // The %csconst feature determines how the constant value is obtained - int const_feature_flag = GetFlag(n, "feature:cs:const"); - - if (const_feature_flag) { - // Use the C syntax to make a true C# constant and hope that it compiles as C# code - value = Getattr(n, "enumvalue") ? Copy(Getattr(n, "enumvalue")) : Copy(Getattr(n, "enumvalueex")); - } else { - String *newsymname = 0; - if (!getCurrentClass() || !proxy_flag) { - String *enumClassPrefix = getEnumClassPrefix(); - if (enumClassPrefix) { - // A global scoped enum - newsymname = Swig_name_member(0, enumClassPrefix, symname); - symname = newsymname; - } - } - - // Get the enumvalue from a PINVOKE call - if (!getCurrentClass() || !cparse_cplusplus || !proxy_flag) { - // Strange hack to change the name - Setattr(n, "name", Getattr(n, "value")); /* for wrapping of enums in a namespace when emit_action is used */ - constantWrapper(n); - value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname)); - } else { - memberconstantHandler(n); - value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), Swig_name_member(0, getEnumClassPrefix(), symname))); - } - } - } - return value; - } - - /* ----------------------------------------------------------------------------- - * getEnumName() - * ----------------------------------------------------------------------------- */ - - String *getEnumName(SwigType *t) { - Node *enumname = NULL; - Node *n = enumLookup(t); - if (n) { - enumname = Getattr(n, "enumname"); - if (!enumname) { - String *symname = Getattr(n, "sym:name"); - if (symname) { - // Add in class scope when referencing enum if not a global enum - String *scopename_prefix = Swig_scopename_prefix(Getattr(n, "name")); - String *proxyname = 0; - if (scopename_prefix) { - proxyname = getProxyName(scopename_prefix); - } - if (proxyname) { - enumname = NewStringf("%s.%s", proxyname, symname); - } else { - // global enum or enum in a namespace - String *nspace = Getattr(n, "sym:nspace"); - if (nspace) { - if (namespce) - enumname = NewStringf("%s.%s.%s", namespce, nspace, symname); - else - enumname = NewStringf("%s.%s", nspace, symname); - } else { - enumname = Copy(symname); - } - } - Setattr(n, "enumname", enumname); - Delete(enumname); - Delete(scopename_prefix); - } - } - } - - return enumname; - } - - /* ----------------------------------------------------------------------------- - * substituteClassname() - * - * Substitute the special variable $csclassname with the proxy class name for classes/structs/unions - * that SWIG knows about. Also substitutes enums with enum name. - * Otherwise use the $descriptor name for the C# class name. Note that the $&csclassname substitution - * is the same as a $&descriptor substitution, ie one pointer added to descriptor name. - * Inputs: - * pt - parameter type - * tm - typemap contents that might contain the special variable to be replaced - * Outputs: - * tm - typemap contents complete with the special variable substitution - * Return: - * substitution_performed - flag indicating if a substitution was performed - * ----------------------------------------------------------------------------- */ - - bool substituteClassname(SwigType *pt, String *tm) { - bool substitution_performed = false; - SwigType *type = Copy(SwigType_typedef_resolve_all(pt)); - SwigType *strippedtype = SwigType_strip_qualifiers(type); - - if (Strstr(tm, "$csclassname")) { - SwigType *classnametype = Copy(strippedtype); - substituteClassnameSpecialVariable(classnametype, tm, "$csclassname"); - substitution_performed = true; - Delete(classnametype); - } - if (Strstr(tm, "$*csclassname")) { - SwigType *classnametype = Copy(strippedtype); - Delete(SwigType_pop(classnametype)); - if (Len(classnametype) > 0) { - substituteClassnameSpecialVariable(classnametype, tm, "$*csclassname"); - substitution_performed = true; - } - Delete(classnametype); - } - if (Strstr(tm, "$&csclassname")) { - SwigType *classnametype = Copy(strippedtype); - SwigType_add_pointer(classnametype); - substituteClassnameSpecialVariable(classnametype, tm, "$&csclassname"); - substitution_performed = true; - Delete(classnametype); - } - if (Strstr(tm, "$csinterfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$csinterfacename", true); - substitution_performed = true; - Delete(interfacenametype); - } - if (Strstr(tm, "$*csinterfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - Delete(SwigType_pop(interfacenametype)); - if (Len(interfacenametype) > 0) { - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*csinterfacename", true); - substitution_performed = true; - } - Delete(interfacenametype); - } - if (Strstr(tm, "$&csinterfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - SwigType_add_pointer(interfacenametype); - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&csinterfacename", true); - substitution_performed = true; - Delete(interfacenametype); - } - if (Strstr(tm, "$interfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$interfacename", false); - substitution_performed = true; - Delete(interfacenametype); - } - if (Strstr(tm, "$*interfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - Delete(SwigType_pop(interfacenametype)); - if (Len(interfacenametype) > 0) { - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*interfacename", false); - substitution_performed = true; - } - Delete(interfacenametype); - } - if (Strstr(tm, "$&interfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - SwigType_add_pointer(interfacenametype); - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&interfacename", false); - substitution_performed = true; - Delete(interfacenametype); - } - - Delete(strippedtype); - Delete(type); - - return substitution_performed; - } - - /* ----------------------------------------------------------------------------- - * substituteClassnameSpecialVariable() - * ----------------------------------------------------------------------------- */ - - void substituteClassnameSpecialVariable(SwigType *classnametype, String *tm, const char *classnamespecialvariable) { - String *replacementname; - if (SwigType_isenum(classnametype)) { - String *enumname = getEnumName(classnametype); - if (enumname) { - replacementname = Copy(enumname); - } else { - bool anonymous_enum = (Cmp(classnametype, "enum ") == 0); - if (anonymous_enum) { - replacementname = NewString("int"); - } else { - // An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition) or an ignored enum - replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype)); - Replace(replacementname, "enum ", "", DOH_REPLACE_ANY); - Setattr(swig_types_hash, replacementname, classnametype); - } - } - } else { - String *classname = getProxyName(classnametype); // getProxyName() works for pointers to classes too - if (classname) { - replacementname = Copy(classname); - } else { - // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved. - replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype)); - - // Add to hash table so that the type wrapper classes can be created later - Setattr(swig_types_hash, replacementname, classnametype); - } - } - Replaceall(tm, classnamespecialvariable, replacementname); - - Delete(replacementname); - } - - /* ----------------------------------------------------------------------------- - * substituteInterfacenameSpecialVariable() - * ----------------------------------------------------------------------------- */ - - void substituteInterfacenameSpecialVariable(SwigType *interfacenametype, String *tm, const char *interfacenamespecialvariable, bool qualified) { - - String *interfacename = getInterfaceName(interfacenametype, qualified); - if (interfacename) { - String *replacementname = Copy(interfacename); - Replaceall(tm, interfacenamespecialvariable, replacementname); - Delete(replacementname); - } - } - - /* ----------------------------------------------------------------------------- - * emitTypeWrapperClass() - * ----------------------------------------------------------------------------- */ - - void emitTypeWrapperClass(String *classname, SwigType *type) { - Node *n = NewHash(); - Setfile(n, input_file); - Setline(n, line_number); - - String *swigtype = NewString(""); - File *f_swigtype = getOutputFile(SWIG_output_directory(), classname); - - addOpenNamespace(0, f_swigtype); - - // Pure C# baseclass and interfaces - const String *pure_baseclass = typemapLookup(n, "csbase", type, WARN_NONE); - const String *pure_interfaces = typemapLookup(n, "csinterfaces", type, WARN_NONE); - - // Emit the class - Printv(swigtype, typemapLookup(n, "csimports", type, WARN_NONE), // Import statements - "\n", NIL); - - // Class attributes - const String *csattributes = typemapLookup(n, "csattributes", type, WARN_NONE); - if (csattributes && *Char(csattributes)) - Printf(swigtype, "%s\n", csattributes); - - Printv(swigtype, typemapLookup(n, "csclassmodifiers", type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers - " $csclassname", // Class name and base class - (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass, ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces - ", " : "", pure_interfaces, " {", typemapLookup(n, "csbody", type, WARN_CSHARP_TYPEMAP_CSBODY_UNDEF), // main body of class - typemapLookup(n, "cscode", type, WARN_NONE), // extra C# code - "}\n", NIL); - - Replaceall(swigtype, "$csclassname", classname); - Replaceall(swigtype, "$module", module_class_name); - Replaceall(swigtype, "$imclassname", imclass_name); - Replaceall(swigtype, "$dllimport", dllimport); - - // For unknown enums - Replaceall(swigtype, "$enumvalues", ""); - - Printv(f_swigtype, swigtype, NIL); - - addCloseNamespace(0, f_swigtype); - if (f_swigtype != f_single_out) - Delete(f_swigtype); - f_swigtype = NULL; - Delete(swigtype); - Delete(n); - } - - /* ----------------------------------------------------------------------------- - * typemapLookup() - * n - for input only and must contain info for Getfile(n) and Getline(n) to work - * tmap_method - typemap method name - * type - typemap type to lookup - * warning - warning number to issue if no typemaps found - * typemap_attributes - the typemap attributes are attached to this node and will - * also be used for temporary storage if non null - * return is never NULL, unlike Swig_typemap_lookup() - * ----------------------------------------------------------------------------- */ - - const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0) { - Node *node = !typemap_attributes ? NewHash() : typemap_attributes; - Setattr(node, "type", type); - Setfile(node, Getfile(n)); - Setline(node, Getline(n)); - const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0); - if (!tm) { - tm = empty_string; - if (warning != WARN_NONE) - Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0)); - } - if (!typemap_attributes) - Delete(node); - return tm; - } - - /* ----------------------------------------------------------------------------- - * typemapExists() - * n - for input only and must contain info for Getfile(n) and Getline(n) to work - * tmap_method - typemap method name - * type - typemap type to lookup - * returns found typemap or NULL if not found - * ----------------------------------------------------------------------------- */ - - const String *typemapExists(Node *n, const_String_or_char_ptr tmap_method, SwigType *type) { - Node *node = NewHash(); - Setattr(node, "type", type); - Setfile(node, Getfile(n)); - Setline(node, Getline(n)); - const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0); - Delete(node); - return tm; - } - - /* ----------------------------------------------------------------------------- - * canThrow() - * Determine whether the code in the typemap can throw a C# exception. - * If so, note it for later when excodeSubstitute() is called. - * ----------------------------------------------------------------------------- */ - - void canThrow(Node *n, const String *typemap, Node *parameter) { - String *canthrow_attribute = NewStringf("tmap:%s:canthrow", typemap); - String *canthrow = Getattr(parameter, canthrow_attribute); - if (canthrow) - Setattr(n, "csharp:canthrow", "1"); - Delete(canthrow_attribute); - } - - /* ----------------------------------------------------------------------------- - * excodeSubstitute() - * If a method can throw a C# exception, additional exception code is added to - * check for the pending exception so that it can then throw the exception. The - * $excode special variable is replaced by the exception code in the excode - * typemap attribute. - * ----------------------------------------------------------------------------- */ - - void excodeSubstitute(Node *n, String *code, const String *typemap, Node *parameter) { - String *excode_attribute = NewStringf("tmap:%s:excode", typemap); - String *excode = Getattr(parameter, excode_attribute); - if (Getattr(n, "csharp:canthrow")) { - int count = Replaceall(code, "$excode", excode); - if (count < 1 || !excode) { - Swig_warning(WARN_CSHARP_EXCODE, input_file, line_number, - "C# exception may not be thrown - no $excode or excode attribute in '%s' typemap.\n", typemap); - } - } else { - Replaceall(code, "$excode", empty_string); - } - Delete(excode_attribute); - } - - /* ----------------------------------------------------------------------------- - * addOpenNamespace() - * ----------------------------------------------------------------------------- */ - - void addOpenNamespace(const String *nspace, File *file) { - if (namespce || nspace) { - Printf(file, "namespace "); - if (namespce) - Printv(file, namespce, nspace ? "." : "", NIL); - if (nspace) - Printv(file, nspace, NIL); - Printf(file, " {\n"); - } - } - - /* ----------------------------------------------------------------------------- - * addCloseNamespace() - * ----------------------------------------------------------------------------- */ - - void addCloseNamespace(const String *nspace, File *file) { - if (namespce || nspace) - Printf(file, "\n}\n"); - } - - /* ----------------------------------------------------------------------------- - * outputDirectory() - * - * Return the directory to use for generating C# classes/enums and create the - * subdirectory (does not create if language specific outdir does not exist). - * ----------------------------------------------------------------------------- */ - - String *outputDirectory(String *nspace) { - String *output_directory = Copy(SWIG_output_directory()); - if (nspace) { - String *nspace_subdirectory = Copy(nspace); - Replaceall(nspace_subdirectory, ".", SWIG_FILE_DELIMITER); - String *newdir_error = Swig_new_subdirectory(output_directory, nspace_subdirectory); - if (newdir_error) { - Printf(stderr, "%s\n", newdir_error); - Delete(newdir_error); - Exit(EXIT_FAILURE); - } - Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0); - Delete(nspace_subdirectory); - } - return output_directory; - } - - /*---------------------------------------------------------------------- - * Start of director methods - *--------------------------------------------------------------------*/ - -#if 0 - /*---------------------------------------------------------------------- - * emitDirectorUpcalls() - *--------------------------------------------------------------------*/ - - void emitDirectorUpcalls() { - if (n_dmethods) { - Wrapper *w = NewWrapper(); - String *dmethod_data = NewString(""); - int n_methods = 0; - Iterator udata_iter; - - udata_iter = First(dmethods_seq); - while (udata_iter.item) { - UpcallData *udata = udata_iter.item; - Printf(dmethod_data, " { \"%s\", \"%s\" }", Getattr(udata, "imclass_method"), Getattr(udata, "imclass_fdesc")); - ++n_methods; - - udata_iter = Next(udata_iter); - - if (udata_iter.item) - Putc(',', dmethod_data); - Putc('\n', dmethod_data); - } - - - Wrapper_print(w, f_wrappers); - Delete(dmethod_data); - Delete(swig_module_init); - DelWrapper(w); - } - } -#endif - - /*---------------------------------------------------------------------- - * emitDirectorExtraMethods() - * - * This is where the director connect method is generated. - *--------------------------------------------------------------------*/ - void emitDirectorExtraMethods(Node *n) { - if (!Swig_directorclass(n)) - return; - - // Output the director connect method: - String *norm_name = SwigType_namestr(Getattr(n, "name")); - String *dirclassname = directorClassName(n); - String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect"); - String *wname = Swig_name_wrapper(swig_director_connect); - String *sym_name = Getattr(n, "sym:name"); - String *qualified_classname = Copy(sym_name); - String *nspace = getNSpace(); - String *dirClassName = directorClassName(n); - String *smartptr = Getattr(n, "feature:smartptr"); - if (!GetFlag(n, "feature:flatnested")) { - for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) { - - Push(qualified_classname, "."); - Push(qualified_classname, Getattr(outer_class, "sym:name")); - } - } - if (nspace) - Insert(qualified_classname, 0, NewStringf("%s.", nspace)); - - Printv(imclass_class_code, "\n [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL); - Printf(imclass_class_code, " public static extern void %s(global::System.Runtime.InteropServices.HandleRef jarg1", swig_director_connect); - - Wrapper *code_wrap = NewWrapper(); - Printf(code_wrap->def, "SWIGEXPORT void SWIGSTDCALL %s(void *objarg", wname); - - if (smartptr) { - Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", smartptr, smartptr); - Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n"); - Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n"); - Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName); - } else { - Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name); - Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName); - } - - Printf(code_wrap->code, " director->swig_connect_director("); - - for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) { - UpcallData *udata = Getitem(dmethods_seq, i); - String *methid = Getattr(udata, "class_methodidx"); - - Printf(code_wrap->def, ", "); - if (i != first_class_dmethod) - Printf(code_wrap->code, ", "); - Printf(code_wrap->def, "%s::SWIG_Callback%s_t callback%s", dirclassname, methid, methid); - Printf(code_wrap->code, "callback%s", methid); - Printf(imclass_class_code, ", %s.SwigDelegate%s_%s delegate%s", qualified_classname, sym_name, methid, methid); - } - - Printf(code_wrap->def, ") {\n"); - Printf(code_wrap->code, ");\n"); - Printf(imclass_class_code, ");\n"); - Printf(code_wrap->code, "}\n"); - - Wrapper_print(code_wrap, f_wrappers); - DelWrapper(code_wrap); - - Delete(wname); - Delete(swig_director_connect); - Delete(qualified_classname); - Delete(dirclassname); - } - - /* --------------------------------------------------------------- - * classDirectorMethod() - * - * Emit a virtual director method to pass a method call on to the - * underlying C# object. - * - * --------------------------------------------------------------- */ - - int classDirectorMethod(Node *n, Node *parent, String *super) { - String *classname = Getattr(parent, "sym:name"); - String *c_classname = Getattr(parent, "name"); - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - SwigType *returntype = Getattr(n, "type"); - String *overloaded_name = getOverloadedName(n); - String *storage = Getattr(n, "storage"); - String *value = Getattr(n, "value"); - String *decl = Getattr(n, "decl"); - String *declaration = NewString(""); - String *pre_code = NewString(""); - String *post_code = NewString(""); - String *terminator_code = NewString(""); - String *tm; - Parm *p; - int i; - Wrapper *w = NewWrapper(); - ParmList *l = Getattr(n, "parms"); - bool is_void = !(Cmp(returntype, "void")); - String *qualified_return = 0; - bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0"))); - int status = SWIG_OK; - bool output_director = true; - String *dirclassname = directorClassName(parent); - String *qualified_name = NewStringf("%s::%s", dirclassname, name); - SwigType *c_ret_type = NULL; - String *jupcall_args = NewString(""); - String *imclass_dmethod; - String *callback_typedef_parms = NewString(""); - String *delegate_parms = NewString(""); - String *proxy_method_types = NewString(""); - String *callback_def = NewString(""); - String *callback_code = NewString(""); - String *imcall_args = NewString(""); - bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; - - // Kludge Alert: functionWrapper sets sym:overload properly, but it - // isn't at this point, so we have to manufacture it ourselves. At least - // we're consistent with the sym:overload name in functionWrapper. (?? when - // does the overloaded method name get set?) - - imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name)); - - qualified_return = SwigType_rcaststr(returntype, "c_result"); - - if (!is_void && (!ignored_method || pure_virtual)) { - if (!SwigType_isclass(returntype)) { - if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { - String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); - Delete(construct_result); - } else { - String *base_typename = SwigType_base(returntype); - String *resolved_typename = SwigType_typedef_resolve_all(base_typename); - Symtab *symtab = Getattr(n, "sym:symtab"); - Node *typenode = Swig_symbol_clookup(resolved_typename, symtab); - - if (SwigType_ispointer(returntype) || (typenode && Getattr(typenode, "abstracts"))) { - /* initialize pointers to something sane. Same for abstract - classes when a reference is returned. */ - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); - } else { - /* If returning a reference, initialize the pointer to a sane - default - if a C# exception occurs, then the pointer returns - something other than a NULL-initialized reference. */ - SwigType *noref_type = SwigType_del_reference(Copy(returntype)); - String *noref_ltype = SwigType_lstr(noref_type, 0); - String *return_ltype = SwigType_lstr(returntype, 0); - - Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL); - Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL); - Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype); - Printf(w->code, "c_result = &result_default;\n"); - Delete(return_ltype); - Delete(noref_ltype); - Delete(noref_type); - } - - Delete(base_typename); - Delete(resolved_typename); - } - } else { - SwigType *vt; - - vt = cplus_value_type(returntype); - if (!vt) { - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL); - } else { - Wrapper_add_localv(w, "c_result", SwigType_lstr(vt, "c_result"), NIL); - Delete(vt); - } - } - } - - /* Create the intermediate class wrapper */ - tm = Swig_typemap_lookup("imtype", n, "", 0); - if (tm) { - String *imtypeout = Getattr(n, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap - if (imtypeout) - tm = imtypeout; - const String *im_directoroutattributes = Getattr(n, "tmap:imtype:directoroutattributes"); - if (im_directoroutattributes) { - Printf(callback_def, " %s\n", im_directoroutattributes); - if (!ignored_method) - Printf(director_delegate_definitions, " %s\n", im_directoroutattributes); - } - - Printf(callback_def, " private %s SwigDirectorMethod%s(", tm, overloaded_name); - if (!ignored_method) { - const String *csdirectordelegatemodifiers = Getattr(n, "feature:csdirectordelegatemodifiers"); - String *modifiers = (csdirectordelegatemodifiers ? NewStringf("%s%s", csdirectordelegatemodifiers, Len(csdirectordelegatemodifiers) > 0 ? " " : "") : NewStringf("public ")); - Printf(director_delegate_definitions, " %sdelegate %s", modifiers, tm); - Delete(modifiers); - } - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(returntype, 0)); - } - - if ((c_ret_type = Swig_typemap_lookup("ctype", n, "", 0))) { - if (!is_void && !ignored_method) { - String *jretval_decl = NewStringf("%s jresult", c_ret_type); - Wrapper_add_localv(w, "jresult", jretval_decl, "= 0", NIL); - Delete(jretval_decl); - } - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - Swig_director_parms_fixup(l); - - /* Attach the standard typemaps */ - Swig_typemap_attach_parms("out", l, 0); - Swig_typemap_attach_parms("ctype", l, 0); - Swig_typemap_attach_parms("imtype", l, 0); - Swig_typemap_attach_parms("cstype", l, 0); - Swig_typemap_attach_parms("directorin", l, w); - Swig_typemap_attach_parms("csdirectorin", l, 0); - Swig_typemap_attach_parms("directorargout", l, w); - - /* Preamble code */ - if (!ignored_method) - Printf(w->code, "if (!swig_callback%s) {\n", overloaded_name); - - if (!pure_virtual) { - String *super_call = Swig_method_call(super, l); - if (is_void) { - Printf(w->code, "%s;\n", super_call); - if (!ignored_method) - Printf(w->code, "return;\n"); - } else { - Printf(w->code, "return %s;\n", super_call); - } - Delete(super_call); - } else { - Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); - if (!is_void) - Printf(w->code, "return %s;", qualified_return); - else if (!ignored_method) - Printf(w->code, "return;\n"); - } - - if (!ignored_method) - Printf(w->code, "} else {\n"); - - /* Go through argument list, convert from native to C# */ - for (i = 0, p = l; p; ++i) { - /* Is this superfluous? */ - while (checkAttribute(p, "tmap:directorin:numinputs", "0")) { - p = Getattr(p, "tmap:directorin:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *ln = makeParameterName(n, p, i, false); - String *c_param_type = NULL; - String *c_decl = NewString(""); - String *arg = NewString(""); - - Printf(arg, "j%s", ln); - - /* And add to the upcall args */ - if (i > 0) - Printf(jupcall_args, ", "); - Printf(jupcall_args, "%s", arg); - - /* Get parameter's intermediary C type */ - if ((c_param_type = Getattr(p, "tmap:ctype"))) { - String *ctypeout = Getattr(p, "tmap:ctype:out"); // the type in the ctype typemap's out attribute overrides the type in the typemap - if (ctypeout) - c_param_type = ctypeout; - - /* Add to local variables */ - Printf(c_decl, "%s %s", c_param_type, arg); - if (!ignored_method) - Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL); - - /* Add input marshalling code */ - if ((tm = Getattr(p, "tmap:directorin"))) { - - Setattr(p, "emit:directorinput", arg); - Replaceall(tm, "$input", arg); - Replaceall(tm, "$owner", "0"); - - if (Len(tm)) - if (!ignored_method) - Printf(w->code, "%s\n", tm); - - /* Add C type to callback typedef */ - if (i > 0) - Printf(callback_typedef_parms, ", "); - Printf(callback_typedef_parms, "%s", c_param_type); - - /* Add parameter to the intermediate class code if generating the - * intermediate's upcall code */ - if ((tm = Getattr(p, "tmap:imtype"))) { - - String *imtypeout = Getattr(p, "tmap:imtype:out"); // the type in the imtype typemap's out attribute overrides the type in the typemap - if (imtypeout) - tm = imtypeout; - const String *im_directorinattributes = Getattr(p, "tmap:imtype:directorinattributes"); - - String *din = Copy(Getattr(p, "tmap:csdirectorin")); - - if (din) { - Replaceall(din, "$module", module_class_name); - Replaceall(din, "$imclassname", imclass_name); - substituteClassname(pt, din); - Replaceall(din, "$iminput", ln); - - // pre and post attribute support - String *pre = Getattr(p, "tmap:csdirectorin:pre"); - if (pre) { - substituteClassname(pt, pre); - Replaceall(pre, "$iminput", ln); - if (Len(pre_code) > 0) - Printf(pre_code, "\n"); - Printv(pre_code, pre, NIL); - } - String *post = Getattr(p, "tmap:csdirectorin:post"); - if (post) { - substituteClassname(pt, post); - Replaceall(post, "$iminput", ln); - if (Len(post_code) > 0) - Printf(post_code, "\n"); - Printv(post_code, post, NIL); - } - String *terminator = Getattr(p, "tmap:csdirectorin:terminator"); - if (terminator) { - substituteClassname(pt, terminator); - Replaceall(terminator, "$iminput", ln); - if (Len(terminator_code) > 0) - Insert(terminator_code, 0, "\n"); - Insert(terminator_code, 0, terminator); - } - - if (i > 0) { - Printf(delegate_parms, ", "); - Printf(proxy_method_types, ", "); - Printf(imcall_args, ", "); - } - Printf(delegate_parms, "%s%s %s", im_directorinattributes ? im_directorinattributes : empty_string, tm, ln); - - if (Cmp(din, ln)) { - Printv(imcall_args, din, NIL); - } else - Printv(imcall_args, ln, NIL); - - /* Get the C# parameter type */ - if ((tm = Getattr(p, "tmap:cstype"))) { - substituteClassname(pt, tm); - int flags = DOH_REPLACE_FIRST | DOH_REPLACE_ID_BEGIN | DOH_REPLACE_NOCOMMENT; - if (Replace(tm, "ref ", "", flags) || Replace(tm, "ref\t", "", flags)) { - Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm); - } else if (Replace(tm, "out ", "", flags) || Replace(tm, "out\t", "", flags)) { - Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm); - } else { - Printf(proxy_method_types, "typeof(%s)", tm); - } - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt, 0)); - } - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF, input_file, line_number, "No csdirectorin typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - p = Getattr(p, "tmap:directorin:next"); - - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF, input_file, line_number, - "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - p = nextSibling(p); - output_director = false; - } - } else { - Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - p = nextSibling(p); - } - - Delete(ln); - Delete(arg); - Delete(c_decl); - } - - /* header declaration, start wrapper definition */ - String *target; - SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type"); - target = Swig_method_decl(rtype, decl, qualified_name, l, 0); - Printf(w->def, "%s", target); - Delete(qualified_name); - Delete(target); - target = Swig_method_decl(rtype, decl, name, l, 1); - Printf(declaration, " virtual %s", target); - Delete(target); - - // Add any exception specifications to the methods in the director class - if (Getattr(n, "noexcept")) { - Append(w->def, " noexcept"); - Append(declaration, " noexcept"); - } - ParmList *throw_parm_list = NULL; - if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { - int gencomma = 0; - - Append(w->def, " throw("); - Append(declaration, " throw("); - - if (throw_parm_list) - Swig_typemap_attach_parms("throws", throw_parm_list, 0); - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - if (gencomma++) { - Append(w->def, ", "); - Append(declaration, ", "); - } - Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0)); - Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0)); - } - } - - Append(w->def, ")"); - Append(declaration, ")"); - } - - Append(w->def, " {"); - Append(declaration, ";\n"); - - /* Finish off the inherited upcall's definition */ - - Printf(callback_def, "%s)", delegate_parms); - Printf(callback_def, " {\n"); - - /* Emit the intermediate class's upcall to the actual class */ - - String *upcall = NewStringf("%s(%s)", symname, imcall_args); - - if ((tm = Swig_typemap_lookup("csdirectorout", n, "", 0))) { - substituteClassname(returntype, tm); - Replaceall(tm, "$cscall", upcall); - if (!is_void) - Insert(tm, 0, "return "); - Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap - - // pre and post attribute support - bool is_pre_code = Len(pre_code) > 0; - bool is_post_code = Len(post_code) > 0; - bool is_terminator_code = Len(terminator_code) > 0; - if (is_pre_code && is_post_code) - Printf(callback_code, "%s\n try {\n %s;\n } finally {\n%s\n }\n", pre_code, tm, post_code); - else if (is_pre_code) - Printf(callback_code, "%s\n %s;\n", pre_code, tm); - else if (is_post_code) - Printf(callback_code, " try {\n %s;\n } finally {\n%s\n }\n", tm, post_code); - else - Printf(callback_code, " %s;\n", tm); - if (is_terminator_code) - Printv(callback_code, "\n", terminator_code, NIL); - } - - Printf(callback_code, " }\n"); - Delete(upcall); - - if (!ignored_method) { - if (!is_void) - Printf(w->code, "jresult = (%s) ", c_ret_type); - - Printf(w->code, "swig_callback%s(%s);\n", overloaded_name, jupcall_args); - - if (!is_void) { - String *jresult_str = NewString("jresult"); - String *result_str = NewString("c_result"); - - /* Copy jresult into c_result... */ - if ((tm = Swig_typemap_lookup("directorout", n, result_str, w))) { - Replaceall(tm, "$input", jresult_str); - Replaceall(tm, "$result", result_str); - Printf(w->code, "%s\n", tm); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, - "Unable to use return type %s used in %s::%s (skipping director method)\n", - SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - Delete(jresult_str); - Delete(result_str); - } - - /* Marshal outputs */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:directorargout"))) { - canThrow(n, "directorargout", p); - Replaceall(tm, "$result", "jresult"); - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NIL); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } - } - - /* Terminate wrapper code */ - Printf(w->code, "}\n"); - if (!is_void) - Printf(w->code, "return %s;", qualified_return); - } - - Printf(w->code, "}"); - - // We expose virtual protected methods via an extra public inline method which makes a straight call to the wrapped class' method - String *inline_extra_method = NewString(""); - if (dirprot_mode() && !is_public(n) && !pure_virtual) { - Printv(inline_extra_method, declaration, NIL); - String *extra_method_name = NewStringf("%sSwigPublic", name); - Replaceall(inline_extra_method, name, extra_method_name); - Replaceall(inline_extra_method, ";\n", " {\n "); - if (!is_void) - Printf(inline_extra_method, "return "); - String *methodcall = Swig_method_call(super, l); - Printv(inline_extra_method, methodcall, ";\n }\n", NIL); - Delete(methodcall); - Delete(extra_method_name); - } - - /* emit the director method */ - if (status == SWIG_OK && output_director) { - if (!is_void) { - Replaceall(w->code, "$null", qualified_return); - } else { - Replaceall(w->code, "$null", ""); - } - if (!ignored_method) - Printv(director_delegate_callback, "\n", callback_def, callback_code, NIL); - if (!Getattr(n, "defaultargs")) { - Replaceall(w->code, "$symname", symname); - Wrapper_print(w, f_directors); - Printv(f_directors_h, declaration, NIL); - Printv(f_directors_h, inline_extra_method, NIL); - } - } - - if (!ignored_method) { - /* Emit the actual upcall through */ - UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name); - String *methid = Getattr(udata, "class_methodidx"); - Setattr(n, "upcalldata", udata); - /* - Printf(stdout, "setting upcalldata, nodeType: %s %s::%s %p\n", nodeType(n), classname, Getattr(n, "name"), n); - */ - - Printf(director_callback_typedefs, " typedef %s (SWIGSTDCALL* SWIG_Callback%s_t)(", c_ret_type, methid); - Printf(director_callback_typedefs, "%s);\n", callback_typedef_parms); - Printf(director_callbacks, " SWIG_Callback%s_t swig_callback%s;\n", methid, overloaded_name); - - Printf(director_delegate_definitions, " SwigDelegate%s_%s(%s);\n", classname, methid, delegate_parms); - Printf(director_delegate_instances, " private SwigDelegate%s_%s swigDelegate%s;\n", classname, methid, methid); - Printf(director_method_types, " private static global::System.Type[] swigMethodTypes%s = new global::System.Type[] { %s };\n", methid, proxy_method_types); - Printf(director_connect_parms, "SwigDirector%s%s delegate%s", classname, methid, methid); - } - - Delete(pre_code); - Delete(post_code); - Delete(terminator_code); - Delete(qualified_return); - Delete(declaration); - Delete(callback_typedef_parms); - Delete(delegate_parms); - Delete(proxy_method_types); - Delete(callback_def); - Delete(callback_code); - Delete(dirclassname); - DelWrapper(w); - - return status; - } - - /* ------------------------------------------------------------ - * classDirectorConstructor() - * ------------------------------------------------------------ */ - - int classDirectorConstructor(Node *n) { - Node *parent = parentNode(n); - String *decl = Getattr(n, "decl"); - String *supername = Swig_class_name(parent); - String *dirclassname = directorClassName(parent); - String *sub = NewString(""); - Parm *p; - ParmList *superparms = Getattr(n, "parms"); - ParmList *parms; - int argidx = 0; - - /* Assign arguments to superclass's parameters, if not already done */ - for (p = superparms; p; p = nextSibling(p)) { - String *pname = Getattr(p, "name"); - - if (!pname) { - pname = NewStringf("arg%d", argidx++); - Setattr(p, "name", pname); - } - } - - // TODO: Is this copy needed? - parms = CopyParmList(superparms); - - if (!Getattr(n, "defaultargs")) { - /* constructor */ - { - String *basetype = Getattr(parent, "classtype"); - String *target = Swig_method_decl(0, decl, dirclassname, parms, 0); - String *call = Swig_csuperclass_call(0, basetype, superparms); - - Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor")); - Printf(f_directors, " swig_init_callbacks();\n"); - Printf(f_directors, "}\n\n"); - - Delete(target); - Delete(call); - } - - /* constructor header */ - { - String *target = Swig_method_decl(0, decl, dirclassname, parms, 1); - Printf(f_directors_h, " %s;\n", target); - Delete(target); - } - } - - Delete(sub); - Delete(supername); - Delete(parms); - Delete(dirclassname); - return Language::classDirectorConstructor(n); - } - - /* ------------------------------------------------------------ - * classDirectorDefaultConstructor() - * ------------------------------------------------------------ */ - - int classDirectorDefaultConstructor(Node *n) { - String *dirclassname = directorClassName(n); - String *classtype = SwigType_namestr(Getattr(n, "name")); - Wrapper *w = NewWrapper(); - - Printf(w->def, "%s::%s() : %s {", dirclassname, dirclassname, Getattr(n, "director:ctor")); - Printf(w->code, "}\n"); - Wrapper_print(w, f_directors); - - Printf(f_directors_h, " %s();\n", dirclassname); - DelWrapper(w); - Delete(classtype); - Delete(dirclassname); - return Language::classDirectorDefaultConstructor(n); - } - - - /* ------------------------------------------------------------ - * classDirectorInit() - * ------------------------------------------------------------ */ - - int classDirectorInit(Node *n) { - Delete(none_comparison); - none_comparison = NewString(""); // not used - - Delete(director_ctor_code); - director_ctor_code = NewString("$director_new"); - - directorDeclaration(n); - - Printf(f_directors_h, "%s {\n", Getattr(n, "director:decl")); - Printf(f_directors_h, "\npublic:\n"); - - /* Keep track of the director methods for this class */ - first_class_dmethod = curr_class_dmethod = n_dmethods; - - director_callback_typedefs = NewString(""); - director_callbacks = NewString(""); - director_delegate_callback = NewString(""); - director_delegate_definitions = NewString(""); - director_delegate_instances = NewString(""); - director_method_types = NewString(""); - director_connect_parms = NewString(""); - - return Language::classDirectorInit(n); - } - - int classDeclaration(Node *n) { - String *old_director_callback_typedefs = director_callback_typedefs; - String *old_director_callbacks = director_callbacks; - String *old_director_delegate_callback = director_delegate_callback; - String *old_director_delegate_definitions = director_delegate_definitions; - String *old_director_delegate_instances = director_delegate_instances; - String *old_director_method_types = director_method_types; - String *old_director_connect_parms = director_connect_parms; - - int ret = Language::classDeclaration(n); - - // these variables are deleted in emitProxyClassDefAndCPPCasts, hence no Delete here - director_callback_typedefs = old_director_callback_typedefs; - director_callbacks = old_director_callbacks; - director_delegate_callback = old_director_delegate_callback; - director_delegate_definitions = old_director_delegate_definitions; - director_delegate_instances = old_director_delegate_instances; - director_method_types = old_director_method_types; - director_connect_parms = old_director_connect_parms; - - return ret; - } - - /* ---------------------------------------------------------------------- - * classDirectorDestructor() - * ---------------------------------------------------------------------- */ - - int classDirectorDestructor(Node *n) { - Node *current_class = getCurrentClass(); - String *dirclassname = directorClassName(current_class); - Wrapper *w = NewWrapper(); - - if (Getattr(n, "noexcept")) { - Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirclassname); - Printf(w->def, "%s::~%s() noexcept {\n", dirclassname, dirclassname); - } else if (Getattr(n, "throw")) { - Printf(f_directors_h, " virtual ~%s() throw();\n", dirclassname); - Printf(w->def, "%s::~%s() throw() {\n", dirclassname, dirclassname); - } else { - Printf(f_directors_h, " virtual ~%s();\n", dirclassname); - Printf(w->def, "%s::~%s() {\n", dirclassname, dirclassname); - } - - Printv(w->code, "}\n", NIL); - - Wrapper_print(w, f_directors); - - DelWrapper(w); - Delete(dirclassname); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * classDirectorEnd() - * ------------------------------------------------------------ */ - - int classDirectorEnd(Node *n) { - int i; - String *dirclassname = directorClassName(n); - - Wrapper *w = NewWrapper(); - - if (Len(director_callback_typedefs) > 0) { - Printf(f_directors_h, "\n%s", director_callback_typedefs); - } - - Printf(f_directors_h, " void swig_connect_director("); - - Printf(w->def, "void %s::swig_connect_director(", dirclassname); - - for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { - UpcallData *udata = Getitem(dmethods_seq, i); - String *methid = Getattr(udata, "class_methodidx"); - String *overname = Getattr(udata, "overname"); - - Printf(f_directors_h, "SWIG_Callback%s_t callback%s", methid, overname); - Printf(w->def, "SWIG_Callback%s_t callback%s", methid, overname); - Printf(w->code, "swig_callback%s = callback%s;\n", overname, overname); - if (i != curr_class_dmethod - 1) { - Printf(f_directors_h, ", "); - Printf(w->def, ", "); - } - } - - Printf(f_directors_h, ");\n"); - Printf(w->def, ") {"); - - - if (Len(director_callbacks) > 0) { - Printf(f_directors_h, "\nprivate:\n%s", director_callbacks); - } - Printf(f_directors_h, " void swig_init_callbacks();\n"); - Printf(f_directors_h, "};\n\n"); - Printf(w->code, "}\n\n"); - - Printf(w->code, "void %s::swig_init_callbacks() {\n", dirclassname); - for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { - UpcallData *udata = Getitem(dmethods_seq, i); - String *overname = Getattr(udata, "overname"); - Printf(w->code, "swig_callback%s = 0;\n", overname); - } - Printf(w->code, "}"); - - Wrapper_print(w, f_directors); - - DelWrapper(w); - Delete(dirclassname); - - return Language::classDirectorEnd(n); - } - - /* -------------------------------------------------------------------- - * classDirectorDisown() - * ------------------------------------------------------------------*/ - virtual int classDirectorDisown(Node *n) { - (void) n; - return SWIG_OK; - } - - /*---------------------------------------------------------------------- - * extraDirectorProtectedCPPMethodsRequired() - *--------------------------------------------------------------------*/ - - bool extraDirectorProtectedCPPMethodsRequired() const { - return false; - } - - /*---------------------------------------------------------------------- - * directorDeclaration() - * - * Generate the director class's declaration - * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {" - *--------------------------------------------------------------------*/ - - void directorDeclaration(Node *n) { - - String *base = Getattr(n, "classtype"); - String *class_ctor = NewString("Swig::Director()"); - - String *dirclassname = directorClassName(n); - String *declaration = Swig_class_declaration(n, dirclassname); - - Printf(declaration, " : public %s, public Swig::Director", base); - - // Stash stuff for later. - Setattr(n, "director:decl", declaration); - Setattr(n, "director:ctor", class_ctor); - - Delete(dirclassname); - } - - /*---------------------------------------------------------------------- - * nestedClassesSupport() - *--------------------------------------------------------------------*/ - - NestedClassSupport nestedClassesSupport() const { - return NCS_Full; - } -}; /* class CSHARP */ - -/* ----------------------------------------------------------------------------- - * swig_csharp() - Instantiate module - * ----------------------------------------------------------------------------- */ - -static Language *new_swig_csharp() { - return new CSHARP(); -} -extern "C" Language *swig_csharp(void) { - return new_swig_csharp(); -} - -/* ----------------------------------------------------------------------------- - * Static member variables - * ----------------------------------------------------------------------------- */ - -const char *CSHARP::usage = "\ -C# Options (available with -csharp)\n\ - -dllimport <dl> - Override DllImport attribute name to <dl>\n\ - -namespace <nm> - Generate wrappers into C# namespace <nm>\n\ - -noproxy - Generate the low-level functional interface instead\n\ - of proxy classes\n\ - -oldvarnames - Old intermediary method names for variable wrappers\n\ - -outfile <file> - Write all C# into a single <file> located in the output directory\n\ -\n"; diff --git a/contrib/tools/swig/Source/Modules/d.cxx b/contrib/tools/swig/Source/Modules/d.cxx deleted file mode 100644 index 31f300f2ea8..00000000000 --- a/contrib/tools/swig/Source/Modules/d.cxx +++ /dev/null @@ -1,4649 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * d.cxx - * - * D language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" -#include <ctype.h> - -// Hash type used for storing information about director callbacks for a class. -typedef DOH UpcallData; - -class D : public Language { - static const char *usage; - const String *empty_string; - const String *public_string; - const String *protected_string; - - /* - * Files and file sections containing C/C++ code. - */ - File *f_begin; - File *f_runtime; - File *f_runtime_h; - File *f_header; - File *f_wrappers; - File *f_init; - File *f_directors; - File *f_directors_h; - List *filenames_list; - - /* - * Command line-set modes of operation. - */ - // Whether a single proxy D module is generated or classes and enums are - // written to their own files. - bool split_proxy_dmodule; - - // The major D version targeted (currently 1 or 2). - unsigned short d_version; - - /* - * State variables which indicate what is being wrapped at the moment. - * This is probably not the most elegant way of handling state, but it has - * proven to work in the C# and Java modules. - */ - // Indicates if wrapping a native function. - bool native_function_flag; - - // Indicates if wrapping a static functions or member variables - bool static_flag; - - // Indicates if wrapping a nonstatic member variable - bool variable_wrapper_flag; - - // Indicates if wrapping a member variable/enum/const. - bool wrapping_member_flag; - - // Indicates if wrapping a global variable. - bool global_variable_flag; - - // Name of a variable being wrapped. - String *variable_name; - - /* - * Variables temporarily holding the generated C++ code. - */ - // C++ code for the generated wrapper functions for casts up the C++ - // for inheritance hierarchies. - String *upcasts_code; - - // Function pointer typedefs for handling director callbacks on the C++ side. - String *director_callback_typedefs; - - // Variables for storing the function pointers to the director callbacks on - // the C++ side. - String *director_callback_pointers; - - /* - * Names of generated D entities. - */ - // The name of the D module containing the interface to the C wrapper. - String *im_dmodule_name; - - // The fully qualified name of the wrap D module (package name included). - String *im_dmodule_fq_name; - - // The name of the proxy module which exposes the (SWIG) module contents as a - // D module. - String *proxy_dmodule_name; - - // The fully qualified name of the proxy D module. - String *proxy_dmodule_fq_name; - - // Optional: Package the D modules are placed in (set via the -package - // command line option). - String *package; - - // The directory the generated D module files are written to. Is constructed - // from the package path if a target package is set, points to the general - // output directory otherwise. - String *dmodule_directory; - - // The name of the library which contains the C wrapper (used when generating - // the dynamic library loader). Can be overridden via the -wrapperlibrary - // command line flag. - String *wrap_library_name; - - /* - * Variables temporarily holding the generated D code. - */ - // Import statements written to the intermediary D module header set via - // %pragma(d) imdmoduleimports. - String *im_dmodule_imports; - - // The code for the intermediary D module body. - String *im_dmodule_code; - - // Import statements for all proxy modules (the main proxy module and, if in - // split proxy module mode, the proxy class modules) from - // %pragma(d) globalproxyimports. - String *global_proxy_imports; - - // The D code for the main proxy modules. nspace_proxy_dmodules is a hash from - // the namespace name as key to an {"imports", "code"}. If the nspace feature - // is not active, only proxy_dmodule_imports and proxy_dmodule_code are used, - // which contain the code for the root proxy module. - // - // These variables should not be accessed directly but rather via the - // proxy{Imports, Code}Buffer)() helper functions which return the right - // buffer for a given namespace. If not in split proxy mode, they contain the - // whole proxy code. - String *proxy_dmodule_imports; - String *proxy_dmodule_code; - Hash *nspace_proxy_dmodules; - - // The D code generated for the currently processed enum. - String *proxy_enum_code; - - /* - * D data for the current proxy class. - * - * These strings are mainly used to temporarily accumulate code from the - * various member handling functions while a single class is processed and are - * no longer relevant once that class has been finished, i.e. after - * classHandler() has returned. - */ - // The unqualified name of the current proxy class. - String *proxy_class_name; - - // The name of the current proxy class, qualified with the name of the - // namespace it is in, if any. - String *proxy_class_qname; - - // The import directives for the current proxy class. They are written to the - // same D module the proxy class is written to. - String *proxy_class_imports; - - // Code for enumerations nested in the current proxy class. Is emitted earlier - // than the rest of the body to work around forward referencing-issues. - String *proxy_class_enums_code; - - // The generated D code making up the body of the current proxy class. - String *proxy_class_body_code; - - // D code which is emitted right after the proxy class. - String *proxy_class_epilogue_code; - - // The full code for the current proxy class, including the epilogue. - String* proxy_class_code; - - // Contains a D call to the function wrapping C++ the destructor of the - // current class (if there is a public C++ destructor). - String *destructor_call; - - // D code for the director callbacks generated for the current class. - String *director_dcallbacks_code; - - /* - * Code for dynamically loading the wrapper library on the D side. - */ - // D code which is inserted into the im D module if dynamic linking is used. - String *wrapper_loader_code; - - // The D code to bind a function pointer to a library symbol. - String *wrapper_loader_bind_command; - - // The cumulated binding commands binding all the functions declared in the - // intermediary D module to the C/C++ library symbols. - String *wrapper_loader_bind_code; - - /* - * Director data. - */ - List *dmethods_seq; - Hash *dmethods_table; - int n_dmethods; - int first_class_dmethod; - int curr_class_dmethod; - - /* - * SWIG types data. - */ - // Collects information about encountered types SWIG does not know about (e.g. - // incomplete types). This is used later to generate type wrapper proxy - // classes for the unknown types. - Hash *unknown_types; - - -public: - /* --------------------------------------------------------------------------- - * D::D() - * --------------------------------------------------------------------------- */ - D():empty_string(NewString("")), - public_string(NewString("public")), - protected_string(NewString("protected")), - f_begin(NULL), - f_runtime(NULL), - f_runtime_h(NULL), - f_header(NULL), - f_wrappers(NULL), - f_init(NULL), - f_directors(NULL), - f_directors_h(NULL), - filenames_list(NULL), - split_proxy_dmodule(false), - d_version(1), - native_function_flag(false), - static_flag(false), - variable_wrapper_flag(false), - wrapping_member_flag(false), - global_variable_flag(false), - variable_name(NULL), - upcasts_code(NULL), - director_callback_typedefs(NULL), - director_callback_pointers(NULL), - im_dmodule_name(NULL), - im_dmodule_fq_name(NULL), - proxy_dmodule_name(NULL), - proxy_dmodule_fq_name(NULL), - package(NULL), - dmodule_directory(NULL), - wrap_library_name(NULL), - im_dmodule_imports(NULL), - im_dmodule_code(NULL), - global_proxy_imports(NULL), - proxy_dmodule_imports(NULL), - proxy_dmodule_code(NULL), - nspace_proxy_dmodules(NULL), - proxy_enum_code(NULL), - proxy_class_name(NULL), - proxy_class_qname(NULL), - proxy_class_imports(NULL), - proxy_class_enums_code(NULL), - proxy_class_body_code(NULL), - proxy_class_epilogue_code(NULL), - proxy_class_code(NULL), - destructor_call(NULL), - director_dcallbacks_code(NULL), - wrapper_loader_code(NULL), - wrapper_loader_bind_command(NULL), - wrapper_loader_bind_code(NULL), - dmethods_seq(NULL), - dmethods_table(NULL), - n_dmethods(0), - first_class_dmethod(0), - curr_class_dmethod(0), - unknown_types(NULL) { - - // For now, multiple inheritance with directors is not possible. It should be - // easy to implement though. - director_multiple_inheritance = 0; - director_language = 1; - - // Not used: - Delete(none_comparison); - none_comparison = NewString(""); - } - - /* --------------------------------------------------------------------------- - * D::main() - * --------------------------------------------------------------------------- */ - virtual void main(int argc, char *argv[]) { - SWIG_library_directory("d"); - - // Look for certain command line options - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if ((strcmp(argv[i], "-d2") == 0)) { - Swig_mark_arg(i); - d_version = 2; - } else if (strcmp(argv[i], "-wrapperlibrary") == 0) { - if (argv[i + 1]) { - wrap_library_name = NewString(""); - Printf(wrap_library_name, argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-package") == 0) { - if (argv[i + 1]) { - package = NewString(""); - Printf(package, argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if ((strcmp(argv[i], "-splitproxy") == 0)) { - Swig_mark_arg(i); - split_proxy_dmodule = true; - } else if (strcmp(argv[i], "-help") == 0) { - Printf(stdout, "%s\n", usage); - } - } - } - - // Add a symbol to the parser for conditional compilation - Preprocessor_define("SWIGD 1", 0); - - // Also make the target D version available as preprocessor symbol for - // use in our library files. - String *version_define = NewStringf("SWIG_D_VERSION %u", d_version); - Preprocessor_define(version_define, 0); - Delete(version_define); - - // Add typemap definitions - SWIG_typemap_lang("d"); - SWIG_config_file("d.swg"); - - allow_overloading(); - } - - /* --------------------------------------------------------------------------- - * D::top() - * --------------------------------------------------------------------------- */ - virtual int top(Node *n) { - // Get any options set in the module directive - Node *optionsnode = Getattr(Getattr(n, "module"), "options"); - - if (optionsnode) { - if (Getattr(optionsnode, "imdmodulename")) { - im_dmodule_name = Copy(Getattr(optionsnode, "imdmodulename")); - } - - if (Getattr(optionsnode, "directors")) { - // Check if directors are enabled for this module. Note: This is a - // "master switch", if it is not set, not director code will be emitted - // at all. %feature("director") statements are also required to enable - // directors for individual classes or methods. - // - // Use the »directors« attributte of the %module directive to enable - // director generation (e.g. »%module(directors="1") modulename«). - allow_directors(); - } - - if (Getattr(optionsnode, "dirprot")) { - allow_dirprot(); - } - - allow_allprotected(GetFlag(optionsnode, "allprotected")); - } - - /* Initialize all of the output files */ - String *outfile = Getattr(n, "outfile"); - String *outfile_h = Getattr(n, "outfile_h"); - - if (!outfile) { - Printf(stderr, "Unable to determine outfile\n"); - Exit(EXIT_FAILURE); - } - - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - - if (directorsEnabled()) { - if (!outfile_h) { - Printf(stderr, "Unable to determine outfile_h\n"); - Exit(EXIT_FAILURE); - } - f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); - if (!f_runtime_h) { - FileErrorDisplay(outfile_h); - Exit(EXIT_FAILURE); - } - } - - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - f_wrappers = NewString(""); - f_directors_h = NewString(""); - f_directors = NewString(""); - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", f_init); - Swig_register_filebyname("director", f_directors); - Swig_register_filebyname("director_h", f_directors_h); - - unknown_types = NewHash(); - filenames_list = NewList(); - - // Make the package name and the resulting module output path. - if (package) { - // Append a dot so we can prepend the package variable directly to the - // module names in the rest of the code. - Printv(package, ".", NIL); - } else { - // Write the generated D modules to the »root« package by default. - package = NewString(""); - } - - dmodule_directory = Copy(SWIG_output_directory()); - if (Len(package) > 0) { - String *package_directory = Copy(package); - Replaceall(package_directory, ".", SWIG_FILE_DELIMITER); - Printv(dmodule_directory, package_directory, NIL); - Delete(package_directory); - } - - // Make the wrap and proxy D module names. - // The wrap module name can be set in the module directive. - if (!im_dmodule_name) { - im_dmodule_name = NewStringf("%s_im", Getattr(n, "name")); - } - im_dmodule_fq_name = NewStringf("%s%s", package, im_dmodule_name); - proxy_dmodule_name = Copy(Getattr(n, "name")); - proxy_dmodule_fq_name = NewStringf("%s%s", package, proxy_dmodule_name); - - im_dmodule_code = NewString(""); - proxy_class_imports = NewString(""); - proxy_class_enums_code = NewString(""); - proxy_class_body_code = NewString(""); - proxy_class_epilogue_code = NewString(""); - proxy_class_code = NewString(""); - destructor_call = NewString(""); - proxy_dmodule_code = NewString(""); - proxy_dmodule_imports = NewString(""); - nspace_proxy_dmodules = NewHash(); - im_dmodule_imports = NewString(""); - upcasts_code = NewString(""); - global_proxy_imports = NewString(""); - wrapper_loader_code = NewString(""); - wrapper_loader_bind_command = NewString(""); - wrapper_loader_bind_code = NewString(""); - dmethods_seq = NewList(); - dmethods_table = NewHash(); - n_dmethods = 0; - - // By default, expect the dynamically loaded wrapper library to be named - // [lib]<module>_wrap[.so/.dll]. - if (!wrap_library_name) - wrap_library_name = NewStringf("%s_wrap", Getattr(n, "name")); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "D"); - - if (directorsEnabled()) { - Printf(f_runtime, "#define SWIG_DIRECTORS\n"); - - /* Emit initial director header and director code: */ - Swig_banner(f_directors_h); - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", proxy_dmodule_name); - Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", proxy_dmodule_name); - - Printf(f_directors, "\n\n"); - Printf(f_directors, "/* ---------------------------------------------------\n"); - Printf(f_directors, " * C++ director class methods\n"); - Printf(f_directors, " * --------------------------------------------------- */\n\n"); - if (outfile_h) { - String *filename = Swig_file_filename(outfile_h); - Printf(f_directors, "#include \"%s\"\n\n", filename); - Delete(filename); - } - } - - Printf(f_runtime, "\n"); - - Swig_name_register("wrapper", "D_%f"); - - Printf(f_wrappers, "\n#ifdef __cplusplus\n"); - Printf(f_wrappers, "extern \"C\" {\n"); - Printf(f_wrappers, "#endif\n\n"); - - // Emit all the wrapper code. - Language::top(n); - - if (directorsEnabled()) { - // Insert director runtime into the f_runtime file (before %header section). - Swig_insert_file("director_common.swg", f_runtime); - Swig_insert_file("director.swg", f_runtime); - } - - // Generate the wrap D module. - // TODO: Add support for »static« linking. - { - String *filen = NewStringf("%s%s.d", dmodule_directory, im_dmodule_name); - File *im_d_file = NewFile(filen, "w", SWIG_output_files()); - if (!im_d_file) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the intermediary class file. - emitBanner(im_d_file); - - Printf(im_d_file, "module %s;\n", im_dmodule_fq_name); - - Printv(im_d_file, im_dmodule_imports, "\n", NIL); - - Replaceall(wrapper_loader_code, "$wraplibrary", wrap_library_name); - Replaceall(wrapper_loader_code, "$wrapperloaderbindcode", wrapper_loader_bind_code); - Replaceall(wrapper_loader_code, "$module", proxy_dmodule_name); - Printf(im_d_file, "%s\n", wrapper_loader_code); - - // Add the wrapper function declarations. - replaceModuleVariables(im_dmodule_code); - Printv(im_d_file, im_dmodule_code, NIL); - - Delete(im_d_file); - } - - // Generate the main D proxy module. - { - String *filen = NewStringf("%s%s.d", dmodule_directory, proxy_dmodule_name); - File *proxy_d_file = NewFile(filen, "w", SWIG_output_files()); - if (!proxy_d_file) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - emitBanner(proxy_d_file); - - Printf(proxy_d_file, "module %s;\n", proxy_dmodule_fq_name); - Printf(proxy_d_file, "\nstatic import %s;\n", im_dmodule_fq_name); - Printv(proxy_d_file, global_proxy_imports, NIL); - Printv(proxy_d_file, proxy_dmodule_imports, NIL); - Printv(proxy_d_file, "\n", NIL); - - // Write a D type wrapper class for each SWIG type to the proxy module code. - for (Iterator swig_type = First(unknown_types); swig_type.key; swig_type = Next(swig_type)) { - writeTypeWrapperClass(swig_type.key, swig_type.item); - } - - // Add the proxy functions (and classes, if they are not written to a separate file). - replaceModuleVariables(proxy_dmodule_code); - Printv(proxy_d_file, proxy_dmodule_code, NIL); - - Delete(proxy_d_file); - } - - // Generate the additional proxy modules for nspace support. - for (Iterator it = First(nspace_proxy_dmodules); it.key; it = Next(it)) { - String *module_name = createLastNamespaceName(it.key); - - String *filename = NewStringf("%s%s.d", outputDirectory(it.key), module_name); - File *file = NewFile(filename, "w", SWIG_output_files()); - if (!file) { - FileErrorDisplay(filename); - Exit(EXIT_FAILURE); - } - Delete(filename); - - emitBanner(file); - - Printf(file, "module %s%s.%s;\n", package, it.key, module_name); - Printf(file, "\nstatic import %s;\n", im_dmodule_fq_name); - Printv(file, global_proxy_imports, NIL); - Printv(file, Getattr(it.item, "imports"), NIL); - Printv(file, "\n", NIL); - - String *code = Getattr(it.item, "code"); - replaceModuleVariables(code); - Printv(file, code, NIL); - - Delete(file); - Delete(module_name); - } - - if (upcasts_code) - Printv(f_wrappers, upcasts_code, NIL); - - Printf(f_wrappers, "#ifdef __cplusplus\n"); - Printf(f_wrappers, "}\n"); - Printf(f_wrappers, "#endif\n"); - - // Check for overwriting file problems on filesystems that are case insensitive - Iterator it1; - Iterator it2; - for (it1 = First(filenames_list); it1.item; it1 = Next(it1)) { - String *item1_lower = Swig_string_lower(it1.item); - for (it2 = Next(it1); it2.item; it2 = Next(it2)) { - String *item2_lower = Swig_string_lower(it2.item); - if (it1.item && it2.item) { - if (Strcmp(item1_lower, item2_lower) == 0) { - Swig_warning(WARN_LANG_PORTABILITY_FILENAME, input_file, line_number, - "Portability warning: File %s will be overwritten by %s on case insensitive filesystems such as " - "Windows' FAT32 and NTFS unless the class/module name is renamed\n", it1.item, it2.item); - } - } - Delete(item2_lower); - } - Delete(item1_lower); - } - - Delete(unknown_types); - unknown_types = NULL; - Delete(filenames_list); - filenames_list = NULL; - Delete(im_dmodule_name); - im_dmodule_name = NULL; - Delete(im_dmodule_fq_name); - im_dmodule_fq_name = NULL; - Delete(im_dmodule_code); - im_dmodule_code = NULL; - Delete(proxy_class_imports); - proxy_class_imports = NULL; - Delete(proxy_class_enums_code); - proxy_class_enums_code = NULL; - Delete(proxy_class_body_code); - proxy_class_body_code = NULL; - Delete(proxy_class_epilogue_code); - proxy_class_epilogue_code = NULL; - Delete(proxy_class_code); - proxy_class_code = NULL; - Delete(destructor_call); - destructor_call = NULL; - Delete(proxy_dmodule_name); - proxy_dmodule_name = NULL; - Delete(proxy_dmodule_fq_name); - proxy_dmodule_fq_name = NULL; - Delete(proxy_dmodule_code); - proxy_dmodule_code = NULL; - Delete(proxy_dmodule_imports); - proxy_dmodule_imports = NULL; - Delete(nspace_proxy_dmodules); - nspace_proxy_dmodules = NULL; - Delete(im_dmodule_imports); - im_dmodule_imports = NULL; - Delete(upcasts_code); - upcasts_code = NULL; - Delete(global_proxy_imports); - global_proxy_imports = NULL; - Delete(wrapper_loader_code); - wrapper_loader_code = NULL; - Delete(wrapper_loader_bind_code); - wrapper_loader_bind_code = NULL; - Delete(wrapper_loader_bind_command); - wrapper_loader_bind_command = NULL; - Delete(dmethods_seq); - dmethods_seq = NULL; - Delete(dmethods_table); - dmethods_table = NULL; - Delete(package); - package = NULL; - Delete(dmodule_directory); - dmodule_directory = NULL; - n_dmethods = 0; - - // Merge all the generated C/C++ code and close the output files. - Dump(f_runtime, f_begin); - Dump(f_header, f_begin); - - if (directorsEnabled()) { - Dump(f_directors, f_begin); - Dump(f_directors_h, f_runtime_h); - - Printf(f_runtime_h, "\n"); - Printf(f_runtime_h, "#endif\n"); - - Delete(f_runtime_h); - f_runtime_h = NULL; - Delete(f_directors); - f_directors = NULL; - Delete(f_directors_h); - f_directors_h = NULL; - } - - Dump(f_wrappers, f_begin); - Wrapper_pretty_print(f_init, f_begin); - Delete(f_header); - Delete(f_wrappers); - Delete(f_init); - Delete(f_runtime); - Delete(f_begin); - - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::insertDirective() - * --------------------------------------------------------------------------- */ - virtual int insertDirective(Node *n) { - int ret = SWIG_OK; - String *code = Getattr(n, "code"); - String *section = Getattr(n, "section"); - replaceModuleVariables(code); - - if (!ImportMode && (Cmp(section, "proxycode") == 0)) { - if (proxy_class_body_code) { - Swig_typemap_replace_embedded_typemap(code, n); - Printv(proxy_class_body_code, code, NIL); - } - } else { - ret = Language::insertDirective(n); - } - return ret; - } - - /* --------------------------------------------------------------------------- - * D::pragmaDirective() - * - * Valid Pragmas: - * imdmodulecode - text (D code) is copied verbatim to the wrap module - * imdmoduleimports - import statements for the im D module - * - * proxydmodulecode - text (D code) is copied verbatim to the proxy module - * (the main proxy module if in split proxy mode). - * globalproxyimports - import statements inserted into _all_ proxy modules. - * - * wrapperloadercode - D code for loading the wrapper library (is copied to - * the im D module). - * wrapperloaderbindcommand - D code for binding a symbol from the wrapper - * library to the declaration in the im D module. - * --------------------------------------------------------------------------- */ - virtual int pragmaDirective(Node *n) { - if (!ImportMode) { - String *lang = Getattr(n, "lang"); - String *code = Getattr(n, "name"); - String *value = Getattr(n, "value"); - - if (Strcmp(lang, "d") == 0) { - String *strvalue = NewString(value); - Replaceall(strvalue, "\\\"", "\""); - - if (Strcmp(code, "imdmodulecode") == 0) { - Printf(im_dmodule_code, "%s\n", strvalue); - } else if (Strcmp(code, "imdmoduleimports") == 0) { - replaceImportTypeMacros(strvalue); - Chop(strvalue); - Printf(im_dmodule_imports, "%s\n", strvalue); - } else if (Strcmp(code, "proxydmodulecode") == 0) { - Printf(proxyCodeBuffer(0), "%s\n", strvalue); - } else if (Strcmp(code, "globalproxyimports") == 0) { - replaceImportTypeMacros(strvalue); - Chop(strvalue); - Printf(global_proxy_imports, "%s\n", strvalue); - } else if (Strcmp(code, "wrapperloadercode") == 0) { - Delete(wrapper_loader_code); - wrapper_loader_code = Copy(strvalue); - } else if (Strcmp(code, "wrapperloaderbindcommand") == 0) { - Delete(wrapper_loader_bind_command); - wrapper_loader_bind_command = Copy(strvalue); - } else { - Swig_error(input_file, line_number, "Unrecognized pragma.\n"); - } - Delete(strvalue); - } - } - return Language::pragmaDirective(n); - } - - /* --------------------------------------------------------------------------- - * D::enumDeclaration() - * - * Wraps C/C++ enums as D enums. - * --------------------------------------------------------------------------- */ - virtual int enumDeclaration(Node *n) { - if (ImportMode) - return SWIG_OK; - - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - proxy_enum_code = NewString(""); - String *symname = Getattr(n, "sym:name"); - String *typemap_lookup_type = Getattr(n, "name"); - - // Emit the enum declaration. - if (typemap_lookup_type) { - const String *enummodifiers = lookupCodeTypemap(n, "dclassmodifiers", typemap_lookup_type, WARN_D_TYPEMAP_CLASSMOD_UNDEF); - Printv(proxy_enum_code, "\n", enummodifiers, " ", symname, " {\n", NIL); - } else { - // Handle anonymous enums. - Printv(proxy_enum_code, "\nenum {\n", NIL); - } - - // Emit each enum item. - Language::enumDeclaration(n); - - if (GetFlag(n, "nonempty")) { - // Finish the enum. - if (typemap_lookup_type) { - Printv(proxy_enum_code, - lookupCodeTypemap(n, "dcode", typemap_lookup_type, WARN_NONE), // Extra D code - "\n}\n", NIL); - } else { - // Handle anonymous enums. - Printv(proxy_enum_code, "\n}\n", NIL); - } - Replaceall(proxy_enum_code, "$dclassname", symname); - } else { - // D enum declarations must have at least one member to be legal, so emit - // an alias to int instead (their ctype/imtype is always int). - Delete(proxy_enum_code); - proxy_enum_code = NewStringf("\nalias int %s;\n", symname); - } - - const String* imports = - lookupCodeTypemap(n, "dimports", typemap_lookup_type, WARN_NONE); - String* imports_trimmed; - if (Len(imports) > 0) { - imports_trimmed = Copy(imports); - Chop(imports_trimmed); - replaceImportTypeMacros(imports_trimmed); - Printv(imports_trimmed, "\n", NIL); - } else { - imports_trimmed = NewString(""); - } - - if (is_wrapping_class()) { - // Enums defined within the C++ class are written into the proxy - // class. - Printv(proxy_class_imports, imports_trimmed, NIL); - Printv(proxy_class_enums_code, proxy_enum_code, NIL); - } else { - // Write non-anonymous enums to their own file if in split proxy module - // mode. - if (split_proxy_dmodule && typemap_lookup_type) { - assertClassNameValidity(proxy_class_name); - - String *nspace = Getattr(n, "sym:nspace"); - String *output_directory = outputDirectory(nspace); - String *filename = NewStringf("%s%s.d", output_directory, symname); - Delete(output_directory); - - File *class_file = NewFile(filename, "w", SWIG_output_files()); - if (!class_file) { - FileErrorDisplay(filename); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filename)); - Delete(filename); - - emitBanner(class_file); - if (nspace) { - Printf(class_file, "module %s%s.%s;\n", package, nspace, symname); - } else { - Printf(class_file, "module %s%s;\n", package, symname); - } - Printv(class_file, imports_trimmed, NIL); - - Printv(class_file, proxy_enum_code, NIL); - - Delete(class_file); - } else { - String *nspace = Getattr(n, "sym:nspace"); - Printv(proxyImportsBuffer(nspace), imports, NIL); - Printv(proxyCodeBuffer(nspace), proxy_enum_code, NIL); - } - } - - Delete(imports_trimmed); - - Delete(proxy_enum_code); - proxy_enum_code = NULL; - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::enumvalueDeclaration() - * --------------------------------------------------------------------------- */ - virtual int enumvalueDeclaration(Node *n) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL); - String *value = Getattr(n, "value"); - String *name = Getattr(n, "name"); - Node *parent = parentNode(n); - String *tmpValue; - - // Strange hack from parent method. - // RESEARCH: What is this doing? - if (value) - tmpValue = NewString(value); - else - tmpValue = NewString(name); - // Note that this is used in enumValue() amongst other places - Setattr(n, "value", tmpValue); - - // Deal with enum values that are not int - int swigtype = SwigType_type(Getattr(n, "type")); - if (swigtype == T_BOOL) { - const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0"; - Setattr(n, "enumvalue", val); - } else if (swigtype == T_CHAR) { - String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue")); - Setattr(n, "enumvalue", val); - Delete(val); - } - - // Emit the enum item. - { - if (!GetFlag(n, "firstenumitem")) - Printf(proxy_enum_code, ",\n"); - - Printf(proxy_enum_code, " %s", Getattr(n, "sym:name")); - - // Check for the %dconstvalue feature - String *value = Getattr(n, "feature:d:constvalue"); - - // Note that in D, enum values must be compile-time constants. Thus, - // %dmanifestconst(0) (getting the enum values at runtime) is not supported. - value = value ? value : Getattr(n, "enumvalue"); - if (value) { - Printf(proxy_enum_code, " = %s", value); - } - - // Keep track that the currently processed enum has at least one value. - SetFlag(parent, "nonempty"); - } - - Delete(tmpValue); - Swig_restore(n); - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::memberfunctionHandler() - * --------------------------------------------------------------------------- */ - virtual int memberfunctionHandler(Node *n) { - Language::memberfunctionHandler(n); - - String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = - Swig_name_member(getNSpace(), proxy_class_name, overloaded_name); - Setattr(n, "imfuncname", intermediary_function_name); - - String *proxy_func_name = Getattr(n, "sym:name"); - Setattr(n, "proxyfuncname", proxy_func_name); - if (split_proxy_dmodule && - Len(Getattr(n, "parms")) == 0 && - Strncmp(proxy_func_name, package, Len(proxy_func_name)) == 0) { - // If we are in split proxy mode and the function is named like the - // target package, the D compiler is unable to resolve the ambiguity - // between the package name and an argument-less function call. - // TODO: This might occur with nspace as well, augment the check. - Swig_warning(WARN_D_NAME_COLLISION, input_file, line_number, - "%s::%s might collide with the package name, consider using %%rename to resolve the ambiguity.\n", - proxy_class_name, proxy_func_name); - } - - writeProxyClassFunction(n); - - Delete(overloaded_name); - - // For each function, look if we have to alias in the parent class function - // for the overload resolution process to work as expected from C++ - // (http://www.digitalmars.com/d/2.0/function.html#function-inheritance). - // For multiple overloads, only emit the alias directive once (for the - // last method, »sym:nextSibling« is null then). - // Smart pointer classes do not mirror the inheritance hierarchy of the - // underlying types, so aliasing the base class methods in is not required - // for them. - // DMD BUG: We have to emit the alias after the last function because - // taking a delegate in the overload checking code fails otherwise - // (http://d.puremagic.com/issues/show_bug.cgi?id=4860). - if (!Getattr(n, "sym:nextSibling") && !is_smart_pointer() && - !areAllOverloadsOverridden(n)) { - String *name = Getattr(n, "sym:name"); - Printf(proxy_class_body_code, "\nalias $dbaseclass.%s %s;\n", name, name); - } - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::staticmemberfunctionHandler() - * --------------------------------------------------------------------------- */ - virtual int staticmemberfunctionHandler(Node *n) { - static_flag = true; - - Language::staticmemberfunctionHandler(n); - - String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = - Swig_name_member(getNSpace(), proxy_class_name, overloaded_name); - Setattr(n, "proxyfuncname", Getattr(n, "sym:name")); - Setattr(n, "imfuncname", intermediary_function_name); - writeProxyClassFunction(n); - Delete(overloaded_name); - - static_flag = false; - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::globalvariableHandler() - * --------------------------------------------------------------------------- */ - virtual int globalvariableHandler(Node *n) { - variable_name = Getattr(n, "sym:name"); - global_variable_flag = true; - int ret = Language::globalvariableHandler(n); - global_variable_flag = false; - - return ret; - } - - /* --------------------------------------------------------------------------- - * D::membervariableHandler() - * --------------------------------------------------------------------------- */ - virtual int membervariableHandler(Node *n) { - variable_name = Getattr(n, "sym:name"); - wrapping_member_flag = true; - variable_wrapper_flag = true; - Language::membervariableHandler(n); - wrapping_member_flag = false; - variable_wrapper_flag = false; - - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::staticmembervariableHandler() - * --------------------------------------------------------------------------- */ - virtual int staticmembervariableHandler(Node *n) { - if (GetFlag(n, "feature:d:manifestconst") != 1) { - Delattr(n, "value"); - } - - variable_name = Getattr(n, "sym:name"); - wrapping_member_flag = true; - static_flag = true; - Language::staticmembervariableHandler(n); - wrapping_member_flag = false; - static_flag = false; - - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::memberconstantHandler() - * --------------------------------------------------------------------------- */ - virtual int memberconstantHandler(Node *n) { - variable_name = Getattr(n, "sym:name"); - wrapping_member_flag = true; - Language::memberconstantHandler(n); - wrapping_member_flag = false; - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::constructorHandler() - * --------------------------------------------------------------------------- */ - virtual int constructorHandler(Node *n) { - Language::constructorHandler(n); - - // Wrappers not wanted for some methods where the parameters cannot be overloadedprocess in D. - if (Getattr(n, "overload:ignore")) { - return SWIG_OK; - } - - ParmList *l = Getattr(n, "parms"); - String *tm; - String *proxy_constructor_code = NewString(""); - int i; - - // Holds code for the constructor helper method generated only when the din - // typemap has code in the pre or post attributes. - String *helper_code = NewString(""); - String *helper_args = NewString(""); - String *pre_code = NewString(""); - String *post_code = NewString(""); - String *terminator_code = NewString(""); - NewString(""); - - String *overloaded_name = getOverloadedName(n); - String *mangled_overname = Swig_name_construct(getNSpace(), overloaded_name); - String *imcall = NewString(""); - - const String *methodmods = Getattr(n, "feature:d:methodmodifiers"); - methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - - // Typemaps were attached earlier to the node, get the return type of the - // call to the C++ constructor wrapper. - const String *wrapper_return_type = lookupDTypemap(n, "imtype", true); - - String *imtypeout = Getattr(n, "tmap:imtype:out"); - if (imtypeout) { - // The type in the imtype typemap's out attribute overrides the type in - // the typemap itself. - wrapper_return_type = imtypeout; - } - - Printf(proxy_constructor_code, "\n%s this(", methodmods); - Printf(helper_code, "static private %s SwigConstruct%s(", - wrapper_return_type, proxy_class_name); - - Printv(imcall, im_dmodule_fq_name, ".", mangled_overname, "(", NIL); - - /* Attach the non-standard typemaps to the parameter list */ - Swig_typemap_attach_parms("in", l, NULL); - Swig_typemap_attach_parms("dtype", l, NULL); - Swig_typemap_attach_parms("din", l, NULL); - - emit_mark_varargs(l); - - int gencomma = 0; - - /* Output each parameter */ - Parm *p = l; - for (i = 0; p; i++) { - if (checkAttribute(p, "varargs:ignore", "1")) { - // Skip ignored varargs. - p = nextSibling(p); - continue; - } - - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - // Skip ignored parameters. - p = Getattr(p, "tmap:in:next"); - continue; - } - - SwigType *pt = Getattr(p, "type"); - String *param_type = NewString(""); - - // Get the D parameter type. - if ((tm = lookupDTypemap(p, "dtype", true))) { - const String *inattributes = Getattr(p, "tmap:dtype:inattributes"); - Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm); - } else { - Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, - "No dtype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - if (gencomma) - Printf(imcall, ", "); - - String *arg = makeParameterName(n, p, i, false); - String *parmtype = 0; - - // Get the D code to convert the parameter value to the type used in the - // intermediary D module. - if ((tm = lookupDTypemap(p, "din"))) { - Replaceall(tm, "$dinput", arg); - String *pre = Getattr(p, "tmap:din:pre"); - if (pre) { - replaceClassname(pre, pt); - Replaceall(pre, "$dinput", arg); - if (Len(pre_code) > 0) - Printf(pre_code, "\n"); - Printv(pre_code, pre, NIL); - } - String *post = Getattr(p, "tmap:din:post"); - if (post) { - replaceClassname(post, pt); - Replaceall(post, "$dinput", arg); - if (Len(post_code) > 0) - Printf(post_code, "\n"); - Printv(post_code, post, NIL); - } - String *terminator = Getattr(p, "tmap:din:terminator"); - if (terminator) { - replaceClassname(terminator, pt); - Replaceall(terminator, "$dinput", arg); - if (Len(terminator_code) > 0) - Insert(terminator_code, 0, "\n"); - Insert(terminator_code, 0, terminator); - } - parmtype = Getattr(p, "tmap:din:parmtype"); - if (parmtype) - Replaceall(parmtype, "$dinput", arg); - Printv(imcall, tm, NIL); - } else { - Swig_warning(WARN_D_TYPEMAP_DIN_UNDEF, input_file, line_number, - "No din typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Add parameter to proxy function */ - if (gencomma) { - Printf(proxy_constructor_code, ", "); - Printf(helper_code, ", "); - Printf(helper_args, ", "); - } - Printf(proxy_constructor_code, "%s %s", param_type, arg); - Printf(helper_code, "%s %s", param_type, arg); - Printf(helper_args, "%s", parmtype ? parmtype : arg); - ++gencomma; - - Delete(parmtype); - Delete(arg); - Delete(param_type); - p = Getattr(p, "tmap:in:next"); - } - - Printf(imcall, ")"); - - Printf(proxy_constructor_code, ")"); - Printf(helper_code, ")"); - - // Insert the dconstructor typemap (replacing $directorconnect as needed). - Hash *attributes = NewHash(); - String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj"); - String *construct_tm = Copy(lookupCodeTypemap(n, "dconstructor", - typemap_lookup_type, WARN_D_TYPEMAP_DCONSTRUCTOR_UNDEF, attributes)); - if (construct_tm) { - const bool use_director = (parentNode(n) && Swig_directorclass(n)); - if (!use_director) { - Replaceall(construct_tm, "$directorconnect", ""); - } else { - String *connect_attr = Getattr(attributes, "tmap:dconstructor:directorconnect"); - - if (connect_attr) { - Replaceall(construct_tm, "$directorconnect", connect_attr); - } else { - Swig_warning(WARN_D_NO_DIRECTORCONNECT_ATTR, input_file, line_number, - "\"directorconnect\" attribute missing in %s \"dconstructor\" typemap.\n", - Getattr(n, "name")); - Replaceall(construct_tm, "$directorconnect", ""); - } - } - - Printv(proxy_constructor_code, " ", construct_tm, NIL); - } - - replaceExcode(n, proxy_constructor_code, "dconstructor", attributes); - - bool is_pre_code = Len(pre_code) > 0; - bool is_post_code = Len(post_code) > 0; - bool is_terminator_code = Len(terminator_code) > 0; - if (is_pre_code || is_post_code || is_terminator_code) { - Printf(helper_code, " {\n"); - if (is_pre_code) { - Printv(helper_code, pre_code, "\n", NIL); - } - if (is_post_code) { - Printf(helper_code, " try {\n"); - Printv(helper_code, " return ", imcall, ";\n", NIL); - Printv(helper_code, " } finally {\n", post_code, "\n }", NIL); - } else { - Printv(helper_code, " return ", imcall, ";", NIL); - } - if (is_terminator_code) { - Printv(helper_code, "\n", terminator_code, NIL); - } - Printf(helper_code, "\n}\n"); - String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", - proxy_class_name, proxy_class_name, helper_args); - Replaceall(proxy_constructor_code, "$imcall", helper_name); - Delete(helper_name); - } else { - Replaceall(proxy_constructor_code, "$imcall", imcall); - } - - Printv(proxy_class_body_code, proxy_constructor_code, "\n", NIL); - - Delete(helper_args); - Delete(pre_code); - Delete(post_code); - Delete(terminator_code); - Delete(construct_tm); - Delete(attributes); - Delete(overloaded_name); - Delete(imcall); - - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::destructorHandler() - * --------------------------------------------------------------------------- */ - virtual int destructorHandler(Node *n) { - Language::destructorHandler(n); - String *symname = Getattr(n, "sym:name"); - - Printv(destructor_call, im_dmodule_fq_name, ".", Swig_name_destroy(getNSpace(),symname), "(cast(void*)swigCPtr)", NIL); - const String *methodmods = Getattr(n, "feature:d:methodmodifiers"); - if (methodmods) - Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods); - - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::classHandler() - * --------------------------------------------------------------------------- */ - virtual int classHandler(Node *n) { - String *nspace = getNSpace(); - File *class_file = NULL; - - proxy_class_name = Copy(Getattr(n, "sym:name")); - if (nspace) { - proxy_class_qname = NewStringf("%s.%s", nspace, proxy_class_name); - } else { - proxy_class_qname = Copy(proxy_class_name); - } - - if (!addSymbol(proxy_class_name, n, nspace)) { - return SWIG_ERROR; - } - - assertClassNameValidity(proxy_class_name); - - if (split_proxy_dmodule) { - String *output_directory = outputDirectory(nspace); - String *filename = NewStringf("%s%s.d", output_directory, proxy_class_name); - class_file = NewFile(filename, "w", SWIG_output_files()); - Delete(output_directory); - if (!class_file) { - FileErrorDisplay(filename); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filename)); - Delete(filename); - - emitBanner(class_file); - if (nspace) { - Printf(class_file, "module %s%s.%s;\n", package, nspace, proxy_class_name); - } else { - Printf(class_file, "module %s%s;\n", package, proxy_class_name); - } - Printf(class_file, "\nstatic import %s;\n", im_dmodule_fq_name); - } - - Clear(proxy_class_imports); - Clear(proxy_class_enums_code); - Clear(proxy_class_body_code); - Clear(proxy_class_epilogue_code); - Clear(proxy_class_code); - Clear(destructor_call); - - - // Traverse the tree for this class, using the *Handler()s to generate code - // to the proxy_class_* variables. - Language::classHandler(n); - - - writeProxyClassAndUpcasts(n); - writeDirectorConnectWrapper(n); - - Replaceall(proxy_class_code, "$dclassname", proxy_class_name); - - String *dclazzname = Swig_name_member(getNSpace(), proxy_class_name, ""); - Replaceall(proxy_class_code, "$dclazzname", dclazzname); - Delete(dclazzname); - - if (split_proxy_dmodule) { - Printv(class_file, global_proxy_imports, NIL); - Printv(class_file, proxy_class_imports, NIL); - - replaceModuleVariables(proxy_class_code); - Printv(class_file, proxy_class_code, NIL); - - Delete(class_file); - } else { - Printv(proxyImportsBuffer(getNSpace()), proxy_class_imports, NIL); - Printv(proxyCodeBuffer(getNSpace()), proxy_class_code, NIL); - } - - Delete(proxy_class_qname); - proxy_class_qname = NULL; - Delete(proxy_class_name); - proxy_class_name = NULL; - - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::constantWrapper() - * - * Used for wrapping constants declared by #define or %constant and also for - * (primitive) static member constants initialised inline. - * - * If the %dmanifestconst feature is used, the C/C++ constant value is used to - * initialize a D »const«. If not, a »getter« method is generated which - * retrieves the value via a call to the C wrapper. However, if there is a - * %dconstvalue specified, it overrides all other settings. - * --------------------------------------------------------------------------- */ - virtual int constantWrapper(Node *n) { - String *symname = Getattr(n, "sym:name"); - if (!addSymbol(symname, n)) - return SWIG_ERROR; - - // The %dmanifestconst feature determines if a D manifest constant - // (const/enum) or a getter function is created. - if (GetFlag(n, "feature:d:manifestconst") != 1) { - // Default constant handling will work with any type of C constant. It - // generates a getter function (which is the same as a read only property - // in D) which retrieves the value via by calling the C wrapper. - // Note that this is only called for global constants, static member - // constants are already handled in staticmemberfunctionHandler(). - - Swig_save("constantWrapper", n, "value", NIL); - Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:dtype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:dtype:outattributes", NIL); - - // Add the stripped quotes back in. - String *old_value = Getattr(n, "value"); - SwigType *t = Getattr(n, "type"); - if (SwigType_type(t) == T_STRING) { - Setattr(n, "value", NewStringf("\"%s\"", old_value)); - Delete(old_value); - } else if (SwigType_type(t) == T_CHAR) { - Setattr(n, "value", NewStringf("\'%s\'", old_value)); - Delete(old_value); - } - - SetFlag(n, "feature:immutable"); - int result = globalvariableHandler(n); - - Swig_restore(n); - return result; - } - - String *constants_code = NewString(""); - SwigType *t = Getattr(n, "type"); - SwigType *valuetype = Getattr(n, "valuetype"); - ParmList *l = Getattr(n, "parms"); - - // Attach the non-standard typemaps to the parameter list. - Swig_typemap_attach_parms("dtype", l, NULL); - - // Get D return type. - String *return_type = NewString(""); - String *tm; - if ((tm = lookupDTypemap(n, "dtype"))) { - String *dtypeout = Getattr(n, "tmap:dtype:out"); - if (dtypeout) { - // The type in the out attribute of the typemap overrides the type - // in the dtype typemap. - tm = dtypeout; - replaceClassname(tm, t); - } - Printf(return_type, "%s", tm); - } else { - Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, - "No dtype typemap defined for %s\n", SwigType_str(t, 0)); - } - - const String *itemname = wrapping_member_flag ? variable_name : symname; - - String *attributes = Getattr(n, "feature:d:methodmodifiers"); - if (attributes) { - attributes = Copy(attributes); - } else { - attributes = Copy(is_public(n) ? public_string : protected_string); - } - - if (d_version == 1) { - if (static_flag) { - Printv(attributes, " static", NIL); - } - Printf(constants_code, "\n%s const %s %s = ", attributes, return_type, itemname); - } else { - Printf(constants_code, "\n%s enum %s %s = ", attributes, return_type, itemname); - } - Delete(attributes); - - // Retrieve the override value set via %dconstvalue, if any. - String *override_value = Getattr(n, "feature:d:constvalue"); - if (override_value) { - Printf(constants_code, "%s;\n", override_value); - } else { - // Just take the value from the C definition and hope it compiles in D. - if (Getattr(n, "wrappedasconstant")) { - if (SwigType_type(valuetype) == T_CHAR) - Printf(constants_code, "\'%(escape)s\';\n", Getattr(n, "staticmembervariableHandler:value")); - else - Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value")); - } else { - // Add the stripped quotes back in. - String* value = Getattr(n, "value"); - if (SwigType_type(t) == T_STRING) { - Printf(constants_code, "\"%s\";\n", value); - } else if (SwigType_type(t) == T_CHAR) { - Printf(constants_code, "\'%s\';\n", value); - } else { - Printf(constants_code, "%s;\n", value); - } - } - } - - // Emit the generated code to appropriate place. - if (wrapping_member_flag) { - Printv(proxy_class_body_code, constants_code, NIL); - } else { - Printv(proxyCodeBuffer(getNSpace()), constants_code, NIL); - } - - // Cleanup. - Delete(return_type); - Delete(constants_code); - - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::functionWrapper() - * - * Generates the C wrapper code for a function and the corresponding - * declaration in the wrap D module. - * --------------------------------------------------------------------------- */ - virtual int functionWrapper(Node *n) { - String *symname = Getattr(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - String *tm; - Parm *p; - int i; - String *c_return_type = NewString(""); - String *im_return_type = NewString(""); - String *cleanup = NewString(""); - String *outarg = NewString(""); - String *body = NewString(""); - int num_arguments = 0; - bool is_void_return; - String *overloaded_name = getOverloadedName(n); - - if (!Getattr(n, "sym:overloaded")) { - if (!addSymbol(Getattr(n, "sym:name"), n)) - return SWIG_ERROR; - } - - // A new wrapper function object - Wrapper *f = NewWrapper(); - - // Make a wrapper name for this function - String *wname = Swig_name_wrapper(overloaded_name); - - /* Attach the non-standard typemaps to the parameter list. */ - Swig_typemap_attach_parms("ctype", l, f); - Swig_typemap_attach_parms("imtype", l, f); - - /* Get return types */ - if ((tm = lookupDTypemap(n, "ctype"))) { - String *ctypeout = Getattr(n, "tmap:ctype:out"); - if (ctypeout) { - // The type in the ctype typemap's out attribute overrides the type in - // the typemap itself. - tm = ctypeout; - } - Printf(c_return_type, "%s", tm); - } else { - Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number, - "No ctype typemap defined for %s\n", SwigType_str(t, 0)); - } - - if ((tm = lookupDTypemap(n, "imtype"))) { - String *imtypeout = Getattr(n, "tmap:imtype:out"); - if (imtypeout) { - // The type in the imtype typemap's out attribute overrides the type in - // the typemap itself. - tm = imtypeout; - } - Printf(im_return_type, "%s", tm); - } else { - Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(t, 0)); - } - - is_void_return = (Cmp(c_return_type, "void") == 0); - if (!is_void_return) - Wrapper_add_localv(f, "jresult", c_return_type, "jresult", NIL); - - Printv(f->def, " SWIGEXPORT ", c_return_type, " ", wname, "(", NIL); - - // Emit all of the local variables for holding arguments. - emit_parameter_variables(l, f); - - /* Attach the standard typemaps */ - emit_attach_parmmaps(l, f); - - // Parameter overloading - Setattr(n, "wrap:parms", l); - Setattr(n, "wrap:name", wname); - - // Wrappers not wanted for some methods where the parameters cannot be overloaded in D - if (Getattr(n, "sym:overloaded")) { - // Emit warnings for the few cases that can't be overloaded in D and give up on generating wrapper - Swig_overload_check(n); - if (Getattr(n, "overload:ignore")) { - DelWrapper(f); - return SWIG_OK; - } - } - - // Collect the parameter list for the intermediary D module declaration of - // the generated wrapper function. - String *im_dmodule_parameters = NewString("("); - - /* Get number of required and total arguments */ - num_arguments = emit_num_arguments(l); - int gencomma = 0; - - // Now walk the function parameter list and generate code to get arguments - for (i = 0, p = l; i < num_arguments; i++) { - - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *ln = Getattr(p, "lname"); - String *im_param_type = NewString(""); - String *c_param_type = NewString(""); - String *arg = NewString(""); - - Printf(arg, "j%s", ln); - - /* Get the ctype types of the parameter */ - if ((tm = lookupDTypemap(p, "ctype", true))) { - Printv(c_param_type, tm, NIL); - } else { - Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Get the intermediary class parameter types of the parameter */ - if ((tm = lookupDTypemap(p, "imtype", true))) { - const String *inattributes = Getattr(p, "tmap:imtype:inattributes"); - Printf(im_param_type, "%s%s", inattributes ? inattributes : empty_string, tm); - } else { - Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Add parameter to intermediary class method */ - if (gencomma) - Printf(im_dmodule_parameters, ", "); - Printf(im_dmodule_parameters, "%s %s", im_param_type, arg); - - // Add parameter to C function - Printv(f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL); - - gencomma = 1; - - // Get typemap for this argument - if ((tm = Getattr(p, "tmap:in"))) { - canThrow(n, "in", p); - Replaceall(tm, "$input", arg); - Setattr(p, "emit:input", arg); - Printf(f->code, "%s\n", tm); - p = Getattr(p, "tmap:in:next"); - } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); - p = nextSibling(p); - } - Delete(im_param_type); - Delete(c_param_type); - Delete(arg); - } - - /* Insert constraint checking code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - canThrow(n, "check", p); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert cleanup code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:freearg"))) { - canThrow(n, "freearg", p); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(cleanup, tm, "\n", NIL); - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert argument output code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - canThrow(n, "argout", p); - Replaceall(tm, "$result", "jresult"); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - // Look for usage of throws typemap and the canthrow flag - ParmList *throw_parm_list = NULL; - if ((throw_parm_list = Getattr(n, "catchlist"))) { - Swig_typemap_attach_parms("throws", throw_parm_list, f); - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - canThrow(n, "throws", p); - } - } - } - - String *null_attribute = 0; - // Now write code to make the function call - if (!native_function_flag) { - - Swig_director_emit_dynamic_cast(n, f); - String *actioncode = emit_action(n); - - /* Return value if necessary */ - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { - canThrow(n, "out", n); - Replaceall(tm, "$result", "jresult"); - - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "1"); - else - Replaceall(tm, "$owner", "0"); - - Printf(f->code, "%s", tm); - null_attribute = Getattr(n, "tmap:out:null"); - if (Len(tm)) - Printf(f->code, "\n"); - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name")); - } - emit_return_variable(n, t, f); - } - - /* Output argument output code */ - Printv(f->code, outarg, NIL); - - /* Output cleanup code */ - Printv(f->code, cleanup, NIL); - - /* Look to see if there is any newfree cleanup code */ - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - canThrow(n, "newfree", n); - Printf(f->code, "%s\n", tm); - } - } - - /* See if there is any return cleanup code */ - if (!native_function_flag) { - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - canThrow(n, "ret", n); - Printf(f->code, "%s\n", tm); - } - } - - // Complete D im parameter list and emit the declaration/binding code. - Printv(im_dmodule_parameters, ")", NIL); - writeImDModuleFunction(overloaded_name, im_return_type, - im_dmodule_parameters, wname); - Delete(im_dmodule_parameters); - - // Finish C function header. - Printf(f->def, ") {"); - - if (!is_void_return) - Printv(f->code, " return jresult;\n", NIL); - Printf(f->code, "}\n"); - - /* Substitute the cleanup code */ - Replaceall(f->code, "$cleanup", cleanup); - - /* Substitute the function name */ - Replaceall(f->code, "$symname", symname); - - /* Contract macro modification */ - if (Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, ") > 0) { - Setattr(n, "d:canthrow", "1"); - } - - if (!null_attribute) - Replaceall(f->code, "$null", "0"); - else - Replaceall(f->code, "$null", null_attribute); - - /* Dump the function out */ - if (!native_function_flag) { - Wrapper_print(f, f_wrappers); - - // Handle %exception which sets the canthrow attribute. - if (Getattr(n, "feature:except:canthrow")) { - Setattr(n, "d:canthrow", "1"); - } - - // A very simple check (it is not foolproof) to assist typemap writers - // with setting the correct features when the want to throw D exceptions - // from C++ code. It checks for the common methods which set - // a pending D exception and issues a warning if one of them has been found - // in the typemap, but the »canthrow« attribute/feature is not set. - if (!Getattr(n, "d:canthrow")) { - if (Strstr(f->code, "SWIG_exception")) { - Swig_warning(WARN_D_CANTHROW_MISSING, input_file, line_number, - "C code contains a call to SWIG_exception and D code does not handle pending exceptions via the canthrow attribute.\n"); - } else if (Strstr(f->code, "SWIG_DSetPendingException")) { - Swig_warning(WARN_D_CANTHROW_MISSING, input_file, line_number, - "C code contains a call to a SWIG_DSetPendingException method and D code does not handle pending exceptions via the canthrow attribute.\n"); - } - } - } - - // If we are not processing an enum or constant, and we were not generating - // a wrapper function which will be accessed via a proxy class, write a - // function to the proxy D module. - if (!is_wrapping_class()) { - writeProxyDModuleFunction(n); - } - - // If we are processing a public member variable, write the property-style - // member function to the proxy class. - if (wrapping_member_flag) { - Setattr(n, "proxyfuncname", variable_name); - Setattr(n, "imfuncname", symname); - - writeProxyClassFunction(n); - } - - Delete(c_return_type); - Delete(im_return_type); - Delete(cleanup); - Delete(outarg); - Delete(body); - Delete(overloaded_name); - DelWrapper(f); - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::nativeWrapper() - * --------------------------------------------------------------------------- */ - virtual int nativeWrapper(Node *n) { - String *wrapname = Getattr(n, "wrap:name"); - - if (!addSymbol(wrapname, n)) - return SWIG_ERROR; - - if (Getattr(n, "type")) { - Swig_save("nativeWrapper", n, "name", NIL); - Setattr(n, "name", wrapname); - native_function_flag = true; - functionWrapper(n); - Swig_restore(n); - native_function_flag = false; - } else { - Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name")); - } - - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::classDirector() - * --------------------------------------------------------------------------- */ - virtual int classDirector(Node *n) { - String *nspace = Getattr(n, "sym:nspace"); - proxy_class_name = NewString(Getattr(n, "sym:name")); - if (nspace) { - proxy_class_qname = NewStringf("%s.%s", nspace, proxy_class_name); - } else { - proxy_class_qname = Copy(proxy_class_name); - } - - int success = Language::classDirector(n); - - Delete(proxy_class_qname); - proxy_class_qname = NULL; - Delete(proxy_class_name); - proxy_class_name = NULL; - - return success; - } - - - /* --------------------------------------------------------------------------- - * D::classDirectorInit() - * --------------------------------------------------------------------------- */ - virtual int classDirectorInit(Node *n) { - Delete(director_ctor_code); - director_ctor_code = NewString("$director_new"); - - // Write C++ director class declaration, for example: - // class SwigDirector_myclass : public myclass, public Swig::Director { - String *classname = Swig_class_name(n); - String *directorname = directorClassName(n); - String *declaration = Swig_class_declaration(n, directorname); - const String *base = Getattr(n, "classtype"); - - Printf(f_directors_h, - "%s : public %s, public Swig::Director {\n", declaration, base); - Printf(f_directors_h, "\npublic:\n"); - - Delete(declaration); - Delete(directorname); - Delete(classname); - - // Stash for later. - Setattr(n, "director:ctor", NewString("Swig::Director()")); - - // Keep track of the director methods for this class. - first_class_dmethod = curr_class_dmethod = n_dmethods; - - director_callback_typedefs = NewString(""); - director_callback_pointers = NewString(""); - director_dcallbacks_code = NewString(""); - - return Language::classDirectorInit(n); - } - - /* --------------------------------------------------------------------------- - * D::classDirectorMethod() - * - * Emit a virtual director method to pass a method call on to the - * underlying D object. - * --------------------------------------------------------------------------- */ - virtual int classDirectorMethod(Node *n, Node *parent, String *super) { - String *classname = Getattr(parent, "sym:name"); - String *c_classname = Getattr(parent, "name"); - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - SwigType *returntype = Getattr(n, "type"); - String *overloaded_name = getOverloadedName(n); - String *storage = Getattr(n, "storage"); - String *value = Getattr(n, "value"); - String *decl = Getattr(n, "decl"); - String *declaration = NewString(""); - String *tm; - Parm *p; - int i; - Wrapper *w = NewWrapper(); - ParmList *l = Getattr(n, "parms"); - bool is_void = !(Cmp(returntype, "void")); - String *qualified_return = 0; - bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0"))); - int status = SWIG_OK; - bool output_director = true; - String *dirclassname = directorClassName(parent); - String *qualified_name = NewStringf("%s::%s", dirclassname, name); - SwigType *c_ret_type = NULL; - String *dcallback_call_args = NewString(""); - String *imclass_dmethod; - String *callback_typedef_parms = NewString(""); - String *delegate_parms = NewString(""); - String *proxy_method_param_list = NewString(""); - String *proxy_callback_return_type = NewString(""); - String *callback_def = NewString(""); - String *callback_code = NewString(""); - String *imcall_args = NewString(""); - bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; - - // Kludge Alert: functionWrapper sets sym:overload properly, but it - // isn't at this point, so we have to manufacture it ourselves. At least - // we're consistent with the sym:overload name in functionWrapper. (?? when - // does the overloaded method name get set?) - - imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), classname, overloaded_name)); - - qualified_return = SwigType_rcaststr(returntype, "c_result"); - - if (!is_void && (!ignored_method || pure_virtual)) { - if (!SwigType_isclass(returntype)) { - if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { - String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); - Delete(construct_result); - } else { - String *base_typename = SwigType_base(returntype); - String *resolved_typename = SwigType_typedef_resolve_all(base_typename); - Symtab *symtab = Getattr(n, "sym:symtab"); - Node *typenode = Swig_symbol_clookup(resolved_typename, symtab); - - if (SwigType_ispointer(returntype) || (typenode && Getattr(typenode, "abstracts"))) { - /* initialize pointers to something sane. Same for abstract - classes when a reference is returned. */ - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); - } else { - /* If returning a reference, initialize the pointer to a sane - default - if a D exception occurs, then the pointer returns - something other than a NULL-initialized reference. */ - SwigType *noref_type = SwigType_del_reference(Copy(returntype)); - String *noref_ltype = SwigType_lstr(noref_type, 0); - String *return_ltype = SwigType_lstr(returntype, 0); - - Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL); - Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL); - Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype); - Printf(w->code, "c_result = &result_default;\n"); - Delete(return_ltype); - Delete(noref_ltype); - Delete(noref_type); - } - - Delete(base_typename); - Delete(resolved_typename); - } - } else { - SwigType *vt; - - vt = cplus_value_type(returntype); - if (!vt) { - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL); - } else { - Wrapper_add_localv(w, "c_result", SwigType_lstr(vt, "c_result"), NIL); - Delete(vt); - } - } - } - - /* Create the intermediate class wrapper */ - tm = lookupDTypemap(n, "imtype"); - if (tm) { - String *imtypeout = Getattr(n, "tmap:imtype:out"); - if (imtypeout) { - // The type in the imtype typemap's out attribute overrides the type - // in the typemap. - tm = imtypeout; - } - Printf(callback_def, "\nprivate extern(C) %s swigDirectorCallback_%s_%s(void* dObject", tm, classname, overloaded_name); - Printv(proxy_callback_return_type, tm, NIL); - } else { - Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, - "No imtype typemap defined for %s\n", SwigType_str(returntype, 0)); - } - - if ((c_ret_type = Swig_typemap_lookup("ctype", n, "", 0))) { - if (!is_void && !ignored_method) { - String *jretval_decl = NewStringf("%s jresult", c_ret_type); - Wrapper_add_localv(w, "jresult", jretval_decl, "= 0", NIL); - Delete(jretval_decl); - } - } else { - Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number, - "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - Swig_director_parms_fixup(l); - - // Attach the standard typemaps. - Swig_typemap_attach_parms("out", l, 0); - Swig_typemap_attach_parms("ctype", l, 0); - Swig_typemap_attach_parms("imtype", l, 0); - Swig_typemap_attach_parms("dtype", l, 0); - Swig_typemap_attach_parms("directorin", l, w); - Swig_typemap_attach_parms("ddirectorin", l, 0); - Swig_typemap_attach_parms("directorargout", l, w); - - // Preamble code. - if (!ignored_method) - Printf(w->code, "if (!swig_callback_%s) {\n", overloaded_name); - - if (!pure_virtual) { - String *super_call = Swig_method_call(super, l); - if (is_void) { - Printf(w->code, "%s;\n", super_call); - if (!ignored_method) - Printf(w->code, "return;\n"); - } else { - Printf(w->code, "return %s;\n", super_call); - } - Delete(super_call); - } else { - Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"%s::%s\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); - if (!is_void) - Printf(w->code, "return %s;", qualified_return); - else if (!ignored_method) - Printf(w->code, "return;\n"); - } - - if (!ignored_method) - Printf(w->code, "} else {\n"); - - // Go through argument list. - for (i = 0, p = l; p; ++i) { - /* Is this superfluous? */ - while (checkAttribute(p, "tmap:directorin:numinputs", "0")) { - p = Getattr(p, "tmap:directorin:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *ln = makeParameterName(n, p, i, false); - String *c_param_type = NULL; - String *c_decl = NewString(""); - String *arg = NewString(""); - - Printf(arg, "j%s", ln); - - // Add each parameter to the D callback invocation arguments. - Printf(dcallback_call_args, ", %s", arg); - - /* Get parameter's intermediary C type */ - if ((c_param_type = lookupDTypemap(p, "ctype", true))) { - String *ctypeout = Getattr(p, "tmap:ctype:out"); - if (ctypeout) { - // The type in the ctype typemap's out attribute overrides the type - // in the typemap itself. - c_param_type = ctypeout; - } - - /* Add to local variables */ - Printf(c_decl, "%s %s", c_param_type, arg); - if (!ignored_method) - Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL); - - /* Add input marshalling code */ - if ((tm = Getattr(p, "tmap:directorin"))) { - - Setattr(p, "emit:directorinput", arg); - Replaceall(tm, "$input", arg); - Replaceall(tm, "$owner", "0"); - - if (Len(tm)) - if (!ignored_method) - Printf(w->code, "%s\n", tm); - - // Add parameter type to the C typedef for the D callback function. - Printf(callback_typedef_parms, ", %s", c_param_type); - - /* Add parameter to the intermediate class code if generating the - * intermediate's upcall code */ - if ((tm = lookupDTypemap(p, "imtype", true))) { - String *imtypeout = Getattr(p, "tmap:imtype:out"); - if (imtypeout) { - // The type in the imtype typemap's out attribute overrides the - // type in the typemap itself. - tm = imtypeout; - } - const String *im_directorinattributes = Getattr(p, "tmap:imtype:directorinattributes"); - - // TODO: Is this copy really needed? - String *din = Copy(lookupDTypemap(p, "ddirectorin", true)); - - if (din) { - Replaceall(din, "$winput", ln); - - Printf(delegate_parms, ", "); - if (i > 0) { - Printf(proxy_method_param_list, ", "); - Printf(imcall_args, ", "); - } - Printf(delegate_parms, "%s%s %s", im_directorinattributes ? im_directorinattributes : empty_string, tm, ln); - - if (Cmp(din, ln)) { - Printv(imcall_args, din, NIL); - } else { - Printv(imcall_args, ln, NIL); - } - - Delete(din); - - // Get the parameter type in the proxy D class (used later when - // generating the overload checking code for the directorConnect - // function). - if ((tm = lookupDTypemap(p, "dtype", true))) { - Printf(proxy_method_param_list, "%s", tm); - } else { - Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, - "No dtype typemap defined for %s\n", SwigType_str(pt, 0)); - } - } else { - Swig_warning(WARN_D_TYPEMAP_DDIRECTORIN_UNDEF, input_file, line_number, - "No ddirectorin typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - } else { - Swig_warning(WARN_D_TYPEMAP_IMTYPE_UNDEF, input_file, line_number, - "No imtype typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - p = Getattr(p, "tmap:directorin:next"); - } else { - Swig_warning(WARN_D_TYPEMAP_DDIRECTORIN_UNDEF, input_file, line_number, - "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - p = nextSibling(p); - output_director = false; - } - } else { - Swig_warning(WARN_D_TYPEMAP_CTYPE_UNDEF, input_file, line_number, - "No ctype typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - p = nextSibling(p); - } - - Delete(arg); - Delete(c_decl); - Delete(c_param_type); - Delete(ln); - } - - /* header declaration, start wrapper definition */ - String *target; - SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type"); - target = Swig_method_decl(rtype, decl, qualified_name, l, 0); - Printf(w->def, "%s", target); - Delete(qualified_name); - Delete(target); - target = Swig_method_decl(rtype, decl, name, l, 1); - Printf(declaration, " virtual %s", target); - Delete(target); - - // Add any exception specifications to the methods in the director class - if (Getattr(n, "noexcept")) { - Append(w->def, " noexcept"); - Append(declaration, " noexcept"); - } - ParmList *throw_parm_list = NULL; - if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { - int gencomma = 0; - - Append(w->def, " throw("); - Append(declaration, " throw("); - - if (throw_parm_list) - Swig_typemap_attach_parms("throws", throw_parm_list, 0); - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - if (gencomma++) { - Append(w->def, ", "); - Append(declaration, ", "); - } - Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0)); - Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0)); - } - } - - Append(w->def, ")"); - Append(declaration, ")"); - } - - Append(w->def, " {"); - Append(declaration, ";\n"); - - // Finish the callback function declaraction. - Printf(callback_def, "%s)", delegate_parms); - Printf(callback_def, " {\n"); - - /* Emit the intermediate class's upcall to the actual class */ - - String *upcall = NewStringf("(cast(%s)dObject).%s(%s)", classname, symname, imcall_args); - - if (!is_void) { - if ((tm = lookupDTypemap(n, "ddirectorout"))) { - Replaceall(tm, "$dcall", upcall); - Printf(callback_code, " return %s;\n", tm); - } - } else { - Printf(callback_code, " %s;\n", upcall); - } - - Printf(callback_code, "}\n"); - Delete(upcall); - - if (!ignored_method) { - if (!is_void) - Printf(w->code, "jresult = (%s) ", c_ret_type); - - Printf(w->code, "swig_callback_%s(d_object%s);\n", overloaded_name, dcallback_call_args); - - if (!is_void) { - String *jresult_str = NewString("jresult"); - String *result_str = NewString("c_result"); - - /* Copy jresult into c_result... */ - if ((tm = Swig_typemap_lookup("directorout", n, result_str, w))) { - Replaceall(tm, "$input", jresult_str); - Replaceall(tm, "$result", result_str); - Printf(w->code, "%s\n", tm); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, - "Unable to use return type %s used in %s::%s (skipping director method)\n", - SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - Delete(jresult_str); - Delete(result_str); - } - - /* Marshal outputs */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:directorargout"))) { - canThrow(n, "directorargout", p); - Replaceall(tm, "$result", "jresult"); - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NIL); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } - } - - /* Terminate wrapper code */ - Printf(w->code, "}\n"); - if (!is_void) - Printf(w->code, "return %s;", qualified_return); - } - - Printf(w->code, "}"); - - // We expose virtual protected methods via an extra public inline method which makes a straight call to the wrapped class' method - String *inline_extra_method = NewString(""); - if (dirprot_mode() && !is_public(n) && !pure_virtual) { - Printv(inline_extra_method, declaration, NIL); - String *extra_method_name = NewStringf("%sSwigPublic", name); - Replaceall(inline_extra_method, name, extra_method_name); - Replaceall(inline_extra_method, ";\n", " {\n "); - if (!is_void) - Printf(inline_extra_method, "return "); - String *methodcall = Swig_method_call(super, l); - Printv(inline_extra_method, methodcall, ";\n }\n", NIL); - Delete(methodcall); - Delete(extra_method_name); - } - - /* emit the director method */ - if (status == SWIG_OK && output_director) { - if (!is_void) { - Replaceall(w->code, "$null", qualified_return); - } else { - Replaceall(w->code, "$null", ""); - } - if (!ignored_method) - Printv(director_dcallbacks_code, callback_def, callback_code, NIL); - if (!Getattr(n, "defaultargs")) { - Replaceall(w->code, "$symname", symname); - Wrapper_print(w, f_directors); - Printv(f_directors_h, declaration, NIL); - Printv(f_directors_h, inline_extra_method, NIL); - } - } - - if (!ignored_method) { - // Register the upcall method so that the callback registering code can - // be written later. - - // We cannot directly use n here because its »type« attribute does not - // the full return type any longer after Language::functionHandler has - // returned. - String *dp_return_type = lookupDTypemap(n, "dtype"); - if (dp_return_type) { - String *dtypeout = Getattr(n, "tmap:dtype:out"); - if (dtypeout) { - // The type in the dtype typemap's out attribute overrides the type - // in the typemap itself. - dp_return_type = dtypeout; - replaceClassname(dp_return_type, returntype); - } - } else { - Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, - "No dtype typemap defined for %s\n", SwigType_str(returntype, 0)); - dp_return_type = NewString(""); - } - - UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name, dp_return_type, proxy_method_param_list); - Delete(dp_return_type); - - // Write the global callback function pointer on the C code. - String *methid = Getattr(udata, "class_methodidx"); - - Printf(director_callback_typedefs, " typedef %s (* SWIG_Callback%s_t)", c_ret_type, methid); - Printf(director_callback_typedefs, "(void *dobj%s);\n", callback_typedef_parms); - Printf(director_callback_pointers, " SWIG_Callback%s_t swig_callback_%s;\n", methid, overloaded_name); - - // Write the type alias for the callback to the intermediary D module. - String *proxy_callback_type = NewString(""); - String *dirClassName = directorClassName(parent); - Printf(proxy_callback_type, "%s_Callback%s", dirClassName, methid); - Printf(im_dmodule_code, "alias extern(C) %s function(void*%s) %s;\n", proxy_callback_return_type, delegate_parms, proxy_callback_type); - Delete(proxy_callback_type); - Delete(dirClassName); - } - - Delete(qualified_return); - Delete(c_ret_type); - Delete(declaration); - Delete(callback_typedef_parms); - Delete(delegate_parms); - Delete(proxy_method_param_list); - Delete(callback_def); - Delete(callback_code); - DelWrapper(w); - - return status; - } - - /* --------------------------------------------------------------------------- - * D::classDirectorConstructor() - * --------------------------------------------------------------------------- */ - virtual int classDirectorConstructor(Node *n) { - Node *parent = parentNode(n); - String *decl = Getattr(n, "decl");; - String *supername = Swig_class_name(parent); - String *dirclassname = directorClassName(parent); - String *sub = NewString(""); - Parm *p; - ParmList *superparms = Getattr(n, "parms"); - ParmList *parms; - int argidx = 0; - - /* Assign arguments to superclass's parameters, if not already done */ - for (p = superparms; p; p = nextSibling(p)) { - String *pname = Getattr(p, "name"); - - if (!pname) { - pname = NewStringf("arg%d", argidx++); - Setattr(p, "name", pname); - } - } - - // TODO: Is this copy needed? - parms = CopyParmList(superparms); - - if (!Getattr(n, "defaultargs")) { - /* constructor */ - { - String *basetype = Getattr(parent, "classtype"); - String *target = Swig_method_decl(0, decl, dirclassname, parms, 0); - String *call = Swig_csuperclass_call(0, basetype, superparms); - String *classtype = SwigType_namestr(Getattr(n, "name")); - - Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor")); - Printf(f_directors, " swig_init_callbacks();\n"); - Printf(f_directors, "}\n\n"); - - Delete(classtype); - Delete(target); - Delete(call); - } - - /* constructor header */ - { - String *target = Swig_method_decl(0, decl, dirclassname, parms, 1); - Printf(f_directors_h, " %s;\n", target); - Delete(target); - } - } - - Delete(sub); - Delete(supername); - Delete(parms); - Delete(dirclassname); - return Language::classDirectorConstructor(n); - } - - /* --------------------------------------------------------------------------- - * D::classDirectorDefaultConstructor() - * --------------------------------------------------------------------------- */ - virtual int classDirectorDefaultConstructor(Node *n) { - String *dirclassname = directorClassName(n); - String *classtype = SwigType_namestr(Getattr(n, "name")); - Wrapper *w = NewWrapper(); - - Printf(w->def, "%s::%s() : %s {", dirclassname, dirclassname, Getattr(n, "director:ctor")); - Printf(w->code, "}\n"); - Wrapper_print(w, f_directors); - - Printf(f_directors_h, " %s();\n", dirclassname); - DelWrapper(w); - Delete(classtype); - Delete(dirclassname); - return Language::classDirectorDefaultConstructor(n); - } - - /* --------------------------------------------------------------------------- - * D::classDirectorDestructor() - * --------------------------------------------------------------------------- */ - virtual int classDirectorDestructor(Node *n) { - Node *current_class = getCurrentClass(); - String *dirclassname = directorClassName(current_class); - Wrapper *w = NewWrapper(); - - if (Getattr(n, "noexcept")) { - Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirclassname); - Printf(w->def, "%s::~%s() noexcept {\n", dirclassname, dirclassname); - } else if (Getattr(n, "throw")) { - Printf(f_directors_h, " virtual ~%s() throw();\n", dirclassname); - Printf(w->def, "%s::~%s() throw() {\n", dirclassname, dirclassname); - } else { - Printf(f_directors_h, " virtual ~%s();\n", dirclassname); - Printf(w->def, "%s::~%s() {\n", dirclassname, dirclassname); - } - - Printv(w->code, "}\n", NIL); - - Wrapper_print(w, f_directors); - - DelWrapper(w); - Delete(dirclassname); - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::classDirectorEnd() - * --------------------------------------------------------------------------- */ - virtual int classDirectorEnd(Node *n) { - int i; - String *director_classname = directorClassName(n); - - Wrapper *w = NewWrapper(); - - if (Len(director_callback_typedefs) > 0) { - Printf(f_directors_h, "\n%s", director_callback_typedefs); - } - - Printf(f_directors_h, " void swig_connect_director(void* dobj"); - - Printf(w->def, "void %s::swig_connect_director(void* dobj", director_classname); - Printf(w->code, "d_object = dobj;"); - - for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { - UpcallData *udata = Getitem(dmethods_seq, i); - String *methid = Getattr(udata, "class_methodidx"); - String *overname = Getattr(udata, "overname"); - - Printf(f_directors_h, ", SWIG_Callback%s_t callback%s", methid, overname); - Printf(w->def, ", SWIG_Callback%s_t callback_%s", methid, overname); - Printf(w->code, "swig_callback_%s = callback_%s;\n", overname, overname); - } - - Printf(f_directors_h, ");\n"); - Printf(w->def, ") {"); - - Printf(f_directors_h, "\nprivate:\n"); - Printf(f_directors_h, " void swig_init_callbacks();\n"); - Printf(f_directors_h, " void *d_object;\n"); - if (Len(director_callback_pointers) > 0) { - Printf(f_directors_h, "%s", director_callback_pointers); - } - Printf(f_directors_h, "};\n\n"); - Printf(w->code, "}\n\n"); - - Printf(w->code, "void %s::swig_init_callbacks() {\n", director_classname); - for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { - UpcallData *udata = Getitem(dmethods_seq, i); - String *overname = Getattr(udata, "overname"); - Printf(w->code, "swig_callback_%s = 0;\n", overname); - } - Printf(w->code, "}"); - - Wrapper_print(w, f_directors); - - DelWrapper(w); - - return Language::classDirectorEnd(n); - } - - /* --------------------------------------------------------------------------- - * D::classDirectorDisown() - * --------------------------------------------------------------------------- */ - virtual int classDirectorDisown(Node *n) { - (void) n; - return SWIG_OK; - } - - /* --------------------------------------------------------------------------- - * D::replaceSpecialVariables() - * --------------------------------------------------------------------------- */ - virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) { - (void)method; - SwigType *type = Getattr(parm, "type"); - - // Just assume that this goes to the proxy class, we cannot know. - replaceClassname(tm, type); - } - -protected: - /* --------------------------------------------------------------------------- - * D::extraDirectorProtectedCPPMethodsRequired() - * --------------------------------------------------------------------------- */ - virtual bool extraDirectorProtectedCPPMethodsRequired() const { - return false; - } - -private: - /* --------------------------------------------------------------------------- - * D::writeImDModuleFunction() - * - * Writes a function declaration for the given (C) wrapper function to the - * intermediary D module. - * - * d_name - The name the function in the intermediary D module will get. - * return type - The return type of the function in the C wrapper. - * parameters - The parameter list of the C wrapper function. - * wrapper_function_name - The name of the exported function in the C wrapper - * (usually d_name prefixed by »D_«). - * --------------------------------------------------------------------------- */ - void writeImDModuleFunction(const_String_or_char_ptr d_name, - const_String_or_char_ptr return_type, const_String_or_char_ptr parameters, - const_String_or_char_ptr wrapper_function_name) { - - // TODO: Add support for static linking here. - Printf(im_dmodule_code, "SwigExternC!(%s function%s) %s;\n", return_type, - parameters, d_name); - Printv(wrapper_loader_bind_code, wrapper_loader_bind_command, NIL); - Replaceall(wrapper_loader_bind_code, "$function", d_name); - Replaceall(wrapper_loader_bind_code, "$symbol", wrapper_function_name); - } - - /* --------------------------------------------------------------------------- - * D::writeProxyClassFunction() - * - * Creates a D proxy function for a C++ function in the wrapped class. Used - * for both static and non-static C++ class functions. - * - * The Node must contain two extra attributes. - * - "proxyfuncname": The name of the D proxy function. - * - "imfuncname": The corresponding function in the intermediary D module. - * --------------------------------------------------------------------------- */ - void writeProxyClassFunction(Node *n) { - SwigType *t = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - String *intermediary_function_name = Getattr(n, "imfuncname"); - String *proxy_function_name = Getattr(n, "proxyfuncname"); - String *tm; - Parm *p; - int i; - String *imcall = NewString(""); - String *return_type = NewString(""); - String *function_code = NewString(""); - bool setter_flag = false; - String *pre_code = NewString(""); - String *post_code = NewString(""); - String *terminator_code = NewString(""); - - // Wrappers not wanted for some methods where the parameters cannot be - // overloaded in D. - if (Getattr(n, "overload:ignore")) - return; - - // Don't generate proxy method for additional explicitcall method used in - // directors. - if (GetFlag(n, "explicitcall")) - return; - - // RESEARCH: What is this good for? - if (l) { - if (SwigType_type(Getattr(l, "type")) == T_VOID) { - l = nextSibling(l); - } - } - - /* Attach the non-standard typemaps to the parameter list */ - Swig_typemap_attach_parms("in", l, NULL); - Swig_typemap_attach_parms("dtype", l, NULL); - Swig_typemap_attach_parms("din", l, NULL); - - // Get return types. - if ((tm = lookupDTypemap(n, "dtype"))) { - String *dtypeout = Getattr(n, "tmap:dtype:out"); - if (dtypeout) { - // The type in the dtype typemap's out attribute overrides the type in - // the typemap. - tm = dtypeout; - replaceClassname(tm, t); - } - Printf(return_type, "%s", tm); - } else { - Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, - "No dtype typemap defined for %s\n", SwigType_str(t, 0)); - } - - if (wrapping_member_flag) { - // Check if this is a setter method for a public member. - const String *setter_name = Swig_name_set(getNSpace(), - Swig_name_member(0, proxy_class_name, variable_name)); - - if (Cmp(Getattr(n, "sym:name"), setter_name) == 0) { - setter_flag = true; - } - } - - // Write function modifiers. - { - String *modifiers; - - const String *mods_override = Getattr(n, "feature:d:methodmodifiers"); - if (mods_override) { - modifiers = Copy(mods_override); - } else { - modifiers = Copy(is_public(n) ? public_string : protected_string); - - if (Getattr(n, "override")) { - Printf(modifiers, " override"); - } - } - - if (is_smart_pointer()) { - // Smart pointer classes do not mirror the inheritance hierarchy of the - // underlying pointer type, so no override required. - Replaceall(modifiers, "override", ""); - } - - Chop(modifiers); - - if (static_flag) { - Printf(modifiers, " static"); - } - - Printf(function_code, "%s ", modifiers); - Delete(modifiers); - } - - // Complete the function declaration up to the parameter list. - Printf(function_code, "%s %s(", return_type, proxy_function_name); - - // Write the wrapper function call up to the parameter list. - Printv(imcall, im_dmodule_fq_name, ".$imfuncname(", NIL); - if (!static_flag) { - Printf(imcall, "cast(void*)swigCPtr"); - } - - String *proxy_param_types = NewString(""); - - // Write the parameter list for the proxy function declaration and the - // wrapper function call. - emit_mark_varargs(l); - int gencomma = !static_flag; - for (i = 0, p = l; p; i++) { - // Ignored varargs. - if (checkAttribute(p, "varargs:ignore", "1")) { - p = nextSibling(p); - continue; - } - - // Ignored parameters. - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - continue; - } - - // Ignore the 'this' argument for variable wrappers. - if (!(variable_wrapper_flag && i == 0)) { - String *param_name = makeParameterName(n, p, i, setter_flag); - SwigType *pt = Getattr(p, "type"); - - // Write the wrapper function call argument. - { - if (gencomma) { - Printf(imcall, ", "); - } - - if ((tm = lookupDTypemap(p, "din", true))) { - Replaceall(tm, "$dinput", param_name); - String *pre = Getattr(p, "tmap:din:pre"); - if (pre) { - replaceClassname(pre, pt); - Replaceall(pre, "$dinput", param_name); - if (Len(pre_code) > 0) - Printf(pre_code, "\n"); - Printv(pre_code, pre, NIL); - } - String *post = Getattr(p, "tmap:din:post"); - if (post) { - replaceClassname(post, pt); - Replaceall(post, "$dinput", param_name); - if (Len(post_code) > 0) - Printf(post_code, "\n"); - Printv(post_code, post, NIL); - } - String *terminator = Getattr(p, "tmap:din:terminator"); - if (terminator) { - replaceClassname(terminator, pt); - Replaceall(terminator, "$dinput", param_name); - if (Len(terminator_code) > 0) - Insert(terminator_code, 0, "\n"); - Insert(terminator_code, 0, terminator); - } - Printv(imcall, tm, NIL); - } else { - Swig_warning(WARN_D_TYPEMAP_DIN_UNDEF, input_file, line_number, - "No din typemap defined for %s\n", SwigType_str(pt, 0)); - } - } - - // Write the D proxy function parameter. - { - String *proxy_type = NewString(""); - - if ((tm = lookupDTypemap(p, "dtype"))) { - const String *inattributes = Getattr(p, "tmap:dtype:inattributes"); - Printf(proxy_type, "%s%s", inattributes ? inattributes : empty_string, tm); - } else { - Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, - "No dtype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - if (gencomma >= 2) { - Printf(function_code, ", "); - Printf(proxy_param_types, ", "); - } - gencomma = 2; - Printf(function_code, "%s %s", proxy_type, param_name); - Append(proxy_param_types, proxy_type); - - Delete(proxy_type); - } - - Delete(param_name); - } - p = Getattr(p, "tmap:in:next"); - } - - Printf(imcall, ")"); - Printf(function_code, ") "); - - if (d_version > 1 && wrapping_member_flag) { - Printf(function_code, "@property "); - } - - if (wrapMemberFunctionAsDConst(n)) { - Printf(function_code, "const "); - } - - // Lookup the code used to convert the wrapper return value to the proxy - // function return type. - if ((tm = lookupDTypemap(n, "dout"))) { - replaceExcode(n, tm, "dout", n); - bool is_pre_code = Len(pre_code) > 0; - bool is_post_code = Len(post_code) > 0; - bool is_terminator_code = Len(terminator_code) > 0; - if (is_pre_code || is_post_code || is_terminator_code) { - if (is_post_code) { - Insert(tm, 0, "\n try "); - Printv(tm, " finally {\n", post_code, "\n }", NIL); - } else { - Insert(tm, 0, "\n "); - } - if (is_pre_code) { - Insert(tm, 0, pre_code); - Insert(tm, 0, "\n"); - } - if (is_terminator_code) { - Printv(tm, "\n", terminator_code, NIL); - } - Insert(tm, 0, "{"); - Printv(tm, "}", NIL); - } - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "true"); - else - Replaceall(tm, "$owner", "false"); - replaceClassname(tm, t); - - // For director methods: generate code to selectively make a normal - // polymorphic call or an explicit method call. Needed to prevent infinite - // recursion when calling director methods. - Node *explicit_n = Getattr(n, "explicitcallnode"); - if (explicit_n && Swig_directorclass(getCurrentClass())) { - String *ex_overloaded_name = getOverloadedName(explicit_n); - String *ex_intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, ex_overloaded_name); - - String *ex_imcall = Copy(imcall); - Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name); - Replaceall(imcall, "$imfuncname", intermediary_function_name); - - String *excode = NewString(""); - if (!Cmp(return_type, "void")) - Printf(excode, "if (swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) %s; else %s", - return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall); - else - Printf(excode, "((swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) ? %s : %s)", - return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall); - - Clear(imcall); - Printv(imcall, excode, NIL); - Delete(ex_overloaded_name); - Delete(excode); - } else { - Replaceall(imcall, "$imfuncname", intermediary_function_name); - } - Replaceall(tm, "$imfuncname", intermediary_function_name); - Replaceall(tm, "$imcall", imcall); - } else { - Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number, - "No dout typemap defined for %s\n", SwigType_str(t, 0)); - } - - Delete(proxy_param_types); - - // The whole function body is now in stored tm (if there was a matching type - // map, of course), so simply append it to the code buffer. The braces are - // included in the typemap. - Printv(function_code, tm, NIL); - - // Write function code buffer to the class code. - Printv(proxy_class_body_code, "\n", function_code, "\n", NIL); - - Delete(pre_code); - Delete(post_code); - Delete(terminator_code); - Delete(function_code); - Delete(return_type); - Delete(imcall); - } - - /* --------------------------------------------------------------------------- - * D::writeProxyDModuleFunction() - * --------------------------------------------------------------------------- */ - void writeProxyDModuleFunction(Node *n) { - SwigType *t = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - String *tm; - Parm *p; - int i; - String *imcall = NewString(""); - String *return_type = NewString(""); - String *function_code = NewString(""); - int num_arguments = 0; - String *overloaded_name = getOverloadedName(n); - String *func_name = NULL; - String *pre_code = NewString(""); - String *post_code = NewString(""); - String *terminator_code = NewString(""); - - // RESEARCH: What is this good for? - if (l) { - if (SwigType_type(Getattr(l, "type")) == T_VOID) { - l = nextSibling(l); - } - } - - /* Attach the non-standard typemaps to the parameter list */ - Swig_typemap_attach_parms("dtype", l, NULL); - Swig_typemap_attach_parms("din", l, NULL); - - /* Get return types */ - if ((tm = lookupDTypemap(n, "dtype"))) { - String *dtypeout = Getattr(n, "tmap:dtype:out"); - if (dtypeout) { - // The type in the dtype typemap's out attribute overrides the type in - // the typemap. - tm = dtypeout; - replaceClassname(tm, t); - } - Printf(return_type, "%s", tm); - } else { - Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, - "No dtype typemap defined for %s\n", SwigType_str(t, 0)); - } - - /* Change function name for global variables */ - if (global_variable_flag) { - // RESEARCH: Is the Copy() needed here? - func_name = Copy(variable_name); - } else { - func_name = Copy(Getattr(n, "sym:name")); - } - - /* Start generating the function */ - const String *outattributes = Getattr(n, "tmap:dtype:outattributes"); - if (outattributes) - Printf(function_code, " %s\n", outattributes); - - const String *methodmods = Getattr(n, "feature:d:methodmodifiers"); - // TODO: Check if is_public(n) could possibly make any sense here - // (private global functions would be useless anyway?). - methodmods = methodmods ? methodmods : empty_string; - - Printf(function_code, "\n%s%s %s(", methodmods, return_type, func_name); - Printv(imcall, im_dmodule_fq_name, ".", overloaded_name, "(", NIL); - - /* Get number of required and total arguments */ - num_arguments = emit_num_arguments(l); - - int gencomma = 0; - - /* Output each parameter */ - for (i = 0, p = l; i < num_arguments; i++) { - - /* Ignored parameters */ - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *param_type = NewString(""); - - // Get the D parameter type. - if ((tm = lookupDTypemap(p, "dtype", true))) { - const String *inattributes = Getattr(p, "tmap:dtype:inattributes"); - Printf(param_type, "%s%s", inattributes ? inattributes : empty_string, tm); - } else { - Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number, - "No dtype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - if (gencomma) - Printf(imcall, ", "); - - const bool generating_setter = global_variable_flag || wrapping_member_flag; - String *arg = makeParameterName(n, p, i, generating_setter); - - // Get the D code to convert the parameter value to the type used in the - // wrapper D module. - if ((tm = lookupDTypemap(p, "din", true))) { - Replaceall(tm, "$dinput", arg); - String *pre = Getattr(p, "tmap:din:pre"); - if (pre) { - replaceClassname(pre, pt); - Replaceall(pre, "$dinput", arg); - if (Len(pre_code) > 0) - Printf(pre_code, "\n"); - Printv(pre_code, pre, NIL); - } - String *post = Getattr(p, "tmap:din:post"); - if (post) { - replaceClassname(post, pt); - Replaceall(post, "$dinput", arg); - if (Len(post_code) > 0) - Printf(post_code, "\n"); - Printv(post_code, post, NIL); - } - String *terminator = Getattr(p, "tmap:din:terminator"); - if (terminator) { - replaceClassname(terminator, pt); - Replaceall(terminator, "$dinput", arg); - if (Len(terminator_code) > 0) - Insert(terminator_code, 0, "\n"); - Insert(terminator_code, 0, terminator); - } - Printv(imcall, tm, NIL); - } else { - Swig_warning(WARN_D_TYPEMAP_DIN_UNDEF, input_file, line_number, - "No din typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Add parameter to module class function */ - if (gencomma >= 2) - Printf(function_code, ", "); - gencomma = 2; - Printf(function_code, "%s %s", param_type, arg); - - p = Getattr(p, "tmap:in:next"); - Delete(arg); - Delete(param_type); - } - - Printf(imcall, ")"); - Printf(function_code, ") "); - - if (global_variable_flag && (d_version > 1)) { - Printf(function_code, "@property "); - } - - // Lookup the code used to convert the wrapper return value to the proxy - // function return type. - if ((tm = lookupDTypemap(n, "dout"))) { - replaceExcode(n, tm, "dout", n); - bool is_pre_code = Len(pre_code) > 0; - bool is_post_code = Len(post_code) > 0; - bool is_terminator_code = Len(terminator_code) > 0; - if (is_pre_code || is_post_code || is_terminator_code) { - if (is_post_code) { - Insert(tm, 0, "\n try "); - Printv(tm, " finally {\n", post_code, "\n }", NIL); - } else { - Insert(tm, 0, "\n "); - } - if (is_pre_code) { - Insert(tm, 0, pre_code); - Insert(tm, 0, "\n"); - } - if (is_terminator_code) { - Printv(tm, "\n", terminator_code, NIL); - } - Insert(tm, 0, " {"); - Printf(tm, "\n}"); - } - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "true"); - else - Replaceall(tm, "$owner", "false"); - replaceClassname(tm, t); - Replaceall(tm, "$imfuncname", overloaded_name); - Replaceall(tm, "$imcall", imcall); - } else { - Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number, - "No dout typemap defined for %s\n", SwigType_str(t, 0)); - } - - // The whole function code is now stored in tm (if there was a matching - // type map, of course), so simply append it to the code buffer. - Printf(function_code, "%s\n", tm ? (const String *) tm : empty_string); - Printv(proxyCodeBuffer(getNSpace()), function_code, NIL); - - Delete(pre_code); - Delete(post_code); - Delete(terminator_code); - Delete(function_code); - Delete(return_type); - Delete(imcall); - Delete(func_name); - } - - /* --------------------------------------------------------------------------- - * D::writeProxyClassAndUpcasts() - * - * Collects all the code fragments generated by the handler function while - * traversing the tree from the proxy_class_* variables and writes the - * class definition (including any epilogue code) to proxy_class_code. - * - * Also writes the upcast function to the wrapper layer when processing a - * derived class. - * - * Inputs: - * n – The class node currently processed. - * --------------------------------------------------------------------------- */ - void writeProxyClassAndUpcasts(Node *n) { - SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); - - /* - * Handle inheriting from D and C++ classes. - */ - - String *c_classname = Getattr(n, "name"); - String *c_baseclassname = NULL; - Node *basenode = NULL; - String *baseclass = NULL; - - // Inheritance from pure D classes. - Node *attributes = NewHash(); - const String *pure_baseclass = - lookupCodeTypemap(n, "dbase", typemap_lookup_type, WARN_NONE, attributes); - bool purebase_replace = GetFlag(attributes, "tmap:dbase:replace") ? true : false; - bool purebase_notderived = GetFlag(attributes, "tmap:dbase:notderived") ? true : false; - Delete(attributes); - - // C++ inheritance. - if (!purebase_replace) { - List *baselist = Getattr(n, "bases"); - if (baselist) { - Iterator base = First(baselist); - while (base.item) { - if (!GetFlag(base.item, "feature:ignore")) { - SwigType *baseclassname = Getattr(base.item, "name"); - if (!c_baseclassname) { - basenode = base.item; - String *name = createProxyName(baseclassname); - if (name) { - c_baseclassname = baseclassname; - baseclass = name; - } - } else { - /* Warn about multiple inheritance for additional base class(es) */ - String *proxyclassname = Getattr(n, "classtypeobj"); - Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Base %s of class %s ignored: multiple inheritance is not supported in D.\n", SwigType_namestr(baseclassname), SwigType_namestr(proxyclassname)); - } - } - base = Next(base); - } - } - } - - bool derived = baseclass != NULL; - - if (derived && purebase_notderived) { - pure_baseclass = empty_string; - } - const String *wanted_base = baseclass ? baseclass : pure_baseclass; - - if (purebase_replace) { - wanted_base = pure_baseclass; - derived = false; - basenode = NULL; - baseclass = NULL; - if (purebase_notderived) { - Swig_error(Getfile(n), Getline(n), - "The dbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", - typemap_lookup_type); - } - } else if (baseclass && Len(pure_baseclass) > 0) { - Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s, base class %s ignored. Multiple inheritance is not supported in D. " - "Perhaps you need one of the 'replace' or 'notderived' attributes in the dbase typemap?\n", typemap_lookup_type, pure_baseclass); - } - - // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) - if (derived) { - writeClassUpcast(n, proxy_class_name, c_classname, c_baseclassname); - } - - /* - * Write needed imports. - */ - // If this class is derived from a C++ class, we need to have the D class - // generated for it in scope. - if (derived) { - requireDType(Getattr(basenode, "sym:nspace"), Getattr(basenode, "sym:name")); - } - - // Write any custom import statements to the proxy module header. - const String *imports = lookupCodeTypemap(n, "dimports", typemap_lookup_type, WARN_NONE); - if (Len(imports) > 0) { - String* imports_trimmed = Copy(imports); - Chop(imports_trimmed); - replaceImportTypeMacros(imports_trimmed); - Printv(proxy_class_imports, imports_trimmed, "\n", NIL); - Delete(imports_trimmed); - } - - /* - * Write the proxy class header. - */ - // Class modifiers. - const String *modifiers = - lookupCodeTypemap(n, "dclassmodifiers", typemap_lookup_type, WARN_D_TYPEMAP_CLASSMOD_UNDEF); - - // User-defined interfaces. - const String *interfaces = - lookupCodeTypemap(n, derived ? "dinterfaces_derived" : "dinterfaces", typemap_lookup_type, WARN_NONE); - - Printv(proxy_class_code, - "\n", - modifiers, - " $dclassname", - (*Char(wanted_base) || *Char(interfaces)) ? " : " : "", wanted_base, - (*Char(wanted_base) && *Char(interfaces)) ? ", " : "", interfaces, " {", - NIL); - - /* - * Write the proxy class body. - */ - String* body = NewString(""); - - // Default class body. - const String *dbody; - if (derived) { - dbody = lookupCodeTypemap(n, "dbody_derived", typemap_lookup_type, WARN_D_TYPEMAP_DBODY_UNDEF); - } else { - dbody = lookupCodeTypemap(n, "dbody", typemap_lookup_type, WARN_D_TYPEMAP_DBODY_UNDEF); - } - - Printv(body, dbody, NIL); - - // Destructor and dispose(). - // If the C++ destructor is accessible (public), it is wrapped by the - // dispose() method which is also called by the emitted D constructor. If it - // is not accessible, no D destructor is written and the generated dispose() - // method throws an exception. - // This enables C++ classes with protected or private destructors to be used - // in D as it would be used in C++ (GC finalization is a no-op then because - // of the empty D destructor) while preventing usage in »scope« variables. - // The method name for the dispose() method is specified in a typemap - // attribute called »methodname«. - const String *tm = NULL; - - const String *dispose_methodname; - const String *dispose_methodmodifiers; - const String *dispose_parameters; - attributes = NewHash(); - if (derived) { - tm = lookupCodeTypemap(n, "ddispose_derived", typemap_lookup_type, WARN_NONE, attributes); - dispose_methodname = Getattr(attributes, "tmap:ddispose_derived:methodname"); - dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose_derived:methodmodifiers"); - dispose_parameters = Getattr(attributes, "tmap:ddispose_derived:parameters"); - } else { - tm = lookupCodeTypemap(n, "ddispose", typemap_lookup_type, WARN_NONE, attributes); - dispose_methodname = Getattr(attributes, "tmap:ddispose:methodname"); - dispose_methodmodifiers = Getattr(attributes, "tmap:ddispose:methodmodifiers"); - dispose_parameters = Getattr(attributes, "tmap:ddispose:parameters"); - } - - if (tm && *Char(tm)) { - if (!dispose_methodname) { - Swig_error(Getfile(n), Getline(n), - "No methodname attribute defined in the ddispose%s typemap for %s\n", - (derived ? "_derived" : ""), proxy_class_name); - } - if (!dispose_methodmodifiers) { - Swig_error(Getfile(n), Getline(n), - "No methodmodifiers attribute defined in ddispose%s typemap for %s.\n", - (derived ? "_derived" : ""), proxy_class_name); - } - if (!dispose_parameters) - dispose_parameters = empty_string; - } - - if (tm) { - // Write the destructor if the C++ one is accessible. - if (*Char(destructor_call)) { - Printv(body, - lookupCodeTypemap(n, "ddestructor", typemap_lookup_type, WARN_NONE), NIL); - } - - // Write the dispose() method. - String *dispose_code = NewString(""); - Printv(dispose_code, tm, NIL); - - if (*Char(destructor_call)) { - Replaceall(dispose_code, "$imcall", destructor_call); - } else { - Replaceall(dispose_code, "$imcall", "throw new object.Exception(\"C++ destructor does not have public access\")"); - } - - if (*Char(dispose_code)) { - Printv(body, "\n", NIL); - const String *methodmods = Getattr(n, "destructmethodmodifiers"); - if (methodmods) - Printv(body, methodmods, NIL); - else - Printv(body, dispose_methodmodifiers, (derived ? " override" : ""), NIL); - Printv(body, " void ", dispose_methodname, "(", dispose_parameters, ") ", dispose_code, "\n", NIL); - } - } - - if (Swig_directorclass(n)) { - // If directors are enabled for the current class, generate the - // director connect helper function which is called from the constructor - // and write it to the class body. - writeDirectorConnectProxy(n); - } - - // Write all constants and enumerations first to prevent forward reference - // errors. - Printv(body, proxy_class_enums_code, NIL); - - // Write the code generated in other methods to the class body. - Printv(body, proxy_class_body_code, NIL); - - // Append extra user D code to the class body. - Printv(body, - lookupCodeTypemap(n, "dcode", typemap_lookup_type, WARN_NONE), "\n", NIL); - - // Write the class body and the curly bracket closing the class definition - // to the proxy module. - indentCode(body); - Replaceall(body, "$dbaseclass", baseclass); - - Printv(proxy_class_code, body, "\n}\n", NIL); - Delete(body); - - // Write the epilogue code if there is any. - Printv(proxy_class_code, proxy_class_epilogue_code, NIL); - } - - - /* --------------------------------------------------------------------------- - * D::writeClassUpcast() - * --------------------------------------------------------------------------- */ - void writeClassUpcast(Node *n, const String* d_class_name, SwigType* c_classname, SwigType* c_baseclassname) { - - SwigType *smart = Swig_cparse_smartptr(n); - String *upcast_name = Swig_name_member(getNSpace(), d_class_name, (smart != 0 ? "SmartPtrUpcast" : "Upcast")); - String *upcast_wrapper_name = Swig_name_wrapper(upcast_name); - - writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)", - upcast_wrapper_name); - - String *classname = SwigType_namestr(c_classname); - String *baseclassname = SwigType_namestr(c_baseclassname); - if (smart) { - String *smartnamestr = SwigType_namestr(smart); - String *bsmartnamestr = SwigType_namestr(smart); - - // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates - SwigType *rclassname = SwigType_typedef_resolve_all(classname); - SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname); - Replaceall(bsmartnamestr, rclassname, rbaseclassname); - - Printv(upcasts_code, - "SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name, - "(", smartnamestr, " *objectRef) {\n", - " return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n" - "}\n", - "\n", NIL); - - Delete(rbaseclassname); - Delete(rclassname); - Delete(bsmartnamestr); - Delete(smartnamestr); - } else { - Printv(upcasts_code, - "SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name, - "(", classname, " *objectRef) {\n", - " return (", baseclassname, " *)objectRef;\n" - "}\n", - "\n", NIL); - } - - Replaceall(upcasts_code, "$cclass", classname); - Replaceall(upcasts_code, "$cbaseclass", baseclassname); - - Delete(baseclassname); - Delete(classname); - Delete(upcast_name); - Delete(upcast_wrapper_name); - Delete(smart); - } - - /* --------------------------------------------------------------------------- - * D::writeTypeWrapperClass() - * --------------------------------------------------------------------------- */ - void writeTypeWrapperClass(String *classname, SwigType *type) { - Node *n = NewHash(); - Setfile(n, input_file); - Setline(n, line_number); - - assertClassNameValidity(classname); - - String* imports_target; - String* code_target; - File *class_file = NULL; - if (split_proxy_dmodule) { - String *filename = NewStringf("%s%s.d", dmodule_directory, classname); - class_file = NewFile(filename, "w", SWIG_output_files()); - if (!class_file) { - FileErrorDisplay(filename); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filename)); - Delete(filename); - - emitBanner(class_file); - Printf(class_file, "module %s%s;\n", package, classname); - Printf(class_file, "\nstatic import %s;\n", im_dmodule_fq_name); - - imports_target = NewString(""); - code_target = NewString(""); - } else { - imports_target = proxyImportsBuffer(0); - code_target = proxyCodeBuffer(0); - } - - // Import statements. - const String *imports = lookupCodeTypemap(n, "dimports", type, WARN_NONE); - if (Len(imports) > 0) { - String *imports_trimmed = Copy(imports); - Chop(imports_trimmed); - replaceImportTypeMacros(imports_trimmed); - Printv(imports_target, imports_trimmed, "\n", NIL); - Delete(imports_trimmed); - } - - // Pure D baseclass and interfaces (no C++ inheritance possible. - const String *pure_baseclass = lookupCodeTypemap(n, "dbase", type, WARN_NONE); - const String *pure_interfaces = lookupCodeTypemap(n, "dinterfaces", type, WARN_NONE); - - // Emit the class. - Printv(code_target, - "\n", - lookupCodeTypemap(n, "dclassmodifiers", type, WARN_D_TYPEMAP_CLASSMOD_UNDEF), - " $dclassname", - (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass, - ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ? ", " : "", pure_interfaces, - " {", NIL); - - String* body = NewString(""); - Printv(body, lookupCodeTypemap(n, "dbody", type, WARN_D_TYPEMAP_DBODY_UNDEF), - lookupCodeTypemap(n, "dcode", type, WARN_NONE), NIL); - indentCode(body); - Printv(code_target, body, "\n}\n", NIL); - Delete(body); - - Replaceall(code_target, "$dclassname", classname); - - if (split_proxy_dmodule) { - Printv(class_file, imports_target, NIL); - Delete(imports_target); - - replaceModuleVariables(code_target); - Printv(class_file, code_target, NIL); - Delete(code_target); - - Delete(class_file); - } - - Delete(n); - } - - /* --------------------------------------------------------------------------- - * D::writeDirectorConnectProxy(Node *classNode) - * - * Writes the helper method which registers the director callbacks by calling - * the director connect function from the D side to the proxy class. - * --------------------------------------------------------------------------- */ - void writeDirectorConnectProxy(Node* classNode) { - String *dirClassName = directorClassName(classNode); - String *connect_name = Swig_name_member(getNSpace(), - proxy_class_name, "director_connect"); - Printf(proxy_class_body_code, "\nprivate void swigDirectorConnect() {\n"); - - int i; - for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { - UpcallData *udata = Getitem(dmethods_seq, i); - String *method = Getattr(udata, "method"); - String *overloaded_name = Getattr(udata, "overname"); - String *return_type = Getattr(udata, "return_type"); - String *param_list = Getattr(udata, "param_list"); - String *methid = Getattr(udata, "class_methodidx"); - Printf(proxy_class_body_code, " %s.%s_Callback%s callback%s;\n", im_dmodule_fq_name, dirClassName, methid, methid); - Printf(proxy_class_body_code, " if (swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) {\n", return_type, param_list, return_type, param_list, method); - Printf(proxy_class_body_code, " callback%s = &swigDirectorCallback_%s_%s;\n", methid, proxy_class_name, overloaded_name); - Printf(proxy_class_body_code, " }\n\n"); - } - Printf(proxy_class_body_code, " %s.%s(cast(void*)swigCPtr, cast(void*)this", im_dmodule_fq_name, connect_name); - for (i = first_class_dmethod; i < curr_class_dmethod; ++i) { - UpcallData *udata = Getitem(dmethods_seq, i); - String *methid = Getattr(udata, "class_methodidx"); - Printf(proxy_class_body_code, ", callback%s", methid); - } - Printf(proxy_class_body_code, ");\n"); - Printf(proxy_class_body_code, "}\n"); - - // Helper function to determine if a method has been overridden in a - // subclass of the wrapped class. If not, we just pass null to the - // director_connect_function since the method from the C++ class should - // be called as usual (see above). - // Only emit it if the proxy class has at least one method. - if (first_class_dmethod < curr_class_dmethod) { - Printf(proxy_class_body_code, "\n"); - Printf(proxy_class_body_code, "private bool swigIsMethodOverridden(DelegateType, FunctionType, alias fn)() %s{\n", (d_version > 1) ? "const " : ""); - Printf(proxy_class_body_code, " DelegateType dg = &fn;\n"); - Printf(proxy_class_body_code, " return dg.funcptr != SwigNonVirtualAddressOf!(FunctionType, fn);\n"); - Printf(proxy_class_body_code, "}\n"); - Printf(proxy_class_body_code, "\n"); - Printf(proxy_class_body_code, "private static Function SwigNonVirtualAddressOf(Function, alias fn)() {\n"); - Printf(proxy_class_body_code, " return cast(Function) &fn;\n"); - Printf(proxy_class_body_code, "}\n"); - } - - if (Len(director_dcallbacks_code) > 0) { - Printv(proxy_class_epilogue_code, director_dcallbacks_code, NIL); - } - - Delete(director_callback_typedefs); - director_callback_typedefs = NULL; - Delete(director_callback_pointers); - director_callback_pointers = NULL; - Delete(director_dcallbacks_code); - director_dcallbacks_code = NULL; - Delete(dirClassName); - Delete(connect_name); - } - - /* --------------------------------------------------------------------------- - * D::writeDirectorConnectWrapper() - * - * Writes the director connect function and the corresponding declaration to - * the C++ wrapper respectively the D wrapper. - * --------------------------------------------------------------------------- */ - void writeDirectorConnectWrapper(Node *n) { - if (!Swig_directorclass(n)) - return; - - // Output the director connect method. - String *norm_name = SwigType_namestr(Getattr(n, "name")); - String *connect_name = Swig_name_member(getNSpace(), - proxy_class_name, "director_connect"); - String *dirClassName = directorClassName(n); - Wrapper *code_wrap; - - Printv(wrapper_loader_bind_code, wrapper_loader_bind_command, NIL); - Replaceall(wrapper_loader_bind_code, "$function", connect_name); - Replaceall(wrapper_loader_bind_code, "$symbol", Swig_name_wrapper(connect_name)); - - Printf(im_dmodule_code, "extern(C) void function(void* cObject, void* dObject"); - - code_wrap = NewWrapper(); - Printf(code_wrap->def, "SWIGEXPORT void D_%s(void *objarg, void *dobj", connect_name); - - Printf(code_wrap->code, " %s *obj = (%s *)objarg;\n", norm_name, norm_name); - Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName); - - Printf(code_wrap->code, " director->swig_connect_director(dobj"); - - for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) { - UpcallData *udata = Getitem(dmethods_seq, i); - String *methid = Getattr(udata, "class_methodidx"); - - Printf(code_wrap->def, ", %s::SWIG_Callback%s_t callback%s", dirClassName, methid, methid); - Printf(code_wrap->code, ", callback%s", methid); - Printf(im_dmodule_code, ", %s_Callback%s callback%s", dirClassName, methid, methid); - } - - Printf(code_wrap->def, ") {\n"); - Printf(code_wrap->code, ");\n"); - Printf(im_dmodule_code, ") %s;\n", connect_name); - Printf(code_wrap->code, "}\n"); - - Wrapper_print(code_wrap, f_wrappers); - DelWrapper(code_wrap); - - Delete(connect_name); - Delete(dirClassName); - } - - /* --------------------------------------------------------------------------- - * D::requireDType() - * - * If the given type is not already in scope in the current module, adds an - * import statement for it. The name is considered relative to the global root - * package if one is set. - * - * This is only used for dependencies created in generated code, user- - * (i.e. typemap-) specified import statements are handled separately. - * --------------------------------------------------------------------------- */ - void requireDType(const String *nspace, const String *symname) { - String *dmodule = createModuleName(nspace, symname); - - if (!inProxyModule(dmodule)) { - String *import = createImportStatement(dmodule); - Append(import, "\n"); - if (is_wrapping_class()) { - addImportStatement(proxy_class_imports, import); - } else { - addImportStatement(proxyImportsBuffer(getNSpace()), import); - } - Delete(import); - } - Delete(dmodule); - } - - /* --------------------------------------------------------------------------- - * D::addImportStatement() - * - * Adds the given import statement to the given list of import statements if - * there is no statement importing that module present yet. - * --------------------------------------------------------------------------- */ - void addImportStatement(String *target, const String *import) const { - char *position = Strstr(target, import); - if (position) { - // If the import statement has been found in the target string, we have to - // check if the previous import was static, which would lead to problems - // if this import is not. - // Thus, we check if the seven characters in front of the occurrence are - // »static «. If the import string passed is also static, the checks fail - // even if the found statement is also static because the last seven - // characters would be part of the previous import statement then. - - if (position - Char(target) < 7) { - return; - } - if (strncmp(position - 7, "static ", 7)) { - return; - } - } - - Printv(target, import, NIL); - } - - /* --------------------------------------------------------------------------- - * D::createImportStatement() - * - * Creates a string containing an import statement for the given module. - * --------------------------------------------------------------------------- */ - String *createImportStatement(const String *dmodule_name, - bool static_import = true) const { - - if (static_import) { - return NewStringf("static import %s%s;", package, dmodule_name); - } else { - return NewStringf("import %s%s;", package, dmodule_name); - } - } - - /* --------------------------------------------------------------------------- - * D::inProxyModule() - * - * Determines if the specified proxy type is declared in the currently - * processed proxy D module. - * - * This function is used to determine if fully qualified type names have to - * be used (package, module and type name). If the split proxy mode is not - * used, this solely depends on whether the type is in the current namespace. - * --------------------------------------------------------------------------- */ - bool inProxyModule(const String *type_name) const { - if (!split_proxy_dmodule) { - String *nspace = createOuterNamespaceNames(type_name); - - // Check if strings are either both null (no namespace) or are both - // non-null and have the same contents. Cannot use Strcmp for this - // directly because of its strange way of handling the case where only - // one argument is 0 ("<"). - bool result = !nspace && !getNSpace(); - if (nspace && getNSpace()) - result = (Strcmp(nspace, getNSpace()) == 0); - - Delete(nspace); - return result; - } - - if (!is_wrapping_class()) { - return false; - } - - return (Strcmp(proxy_class_qname, type_name) == 0); - } - - /* --------------------------------------------------------------------------- - * D::addUpcallMethod() - * - * Adds new director upcall signature. - * --------------------------------------------------------------------------- */ - UpcallData *addUpcallMethod(String *imclass_method, String *class_method, - String *decl, String *overloaded_name, String *return_type, String *param_list) { - - String *key = NewStringf("%s|%s", imclass_method, decl); - - ++curr_class_dmethod; - - String *class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod); - n_dmethods++; - - Hash *new_udata = NewHash(); - Append(dmethods_seq, new_udata); - Setattr(dmethods_table, key, new_udata); - - Setattr(new_udata, "method", Copy(class_method)); - Setattr(new_udata, "class_methodidx", class_methodidx); - Setattr(new_udata, "decl", Copy(decl)); - Setattr(new_udata, "overname", Copy(overloaded_name)); - Setattr(new_udata, "return_type", Copy(return_type)); - Setattr(new_udata, "param_list", Copy(param_list)); - - Delete(key); - return new_udata; - } - - /* --------------------------------------------------------------------------- - * D::assertClassNameValidity() - * --------------------------------------------------------------------------- */ - void assertClassNameValidity(const String* class_name) const { - // TODO: With nspace support, there could arise problems also when not in - // split proxy mode, warnings for these should be added. - if (split_proxy_dmodule) { - if (Cmp(class_name, im_dmodule_name) == 0) { - Swig_error(input_file, line_number, - "Class name cannot be equal to intermediary D module name: %s\n", - class_name); - Exit(EXIT_FAILURE); - } - - String *nspace = getNSpace(); - if (nspace) { - // Check the root package/outermost namespace (a class A in module - // A.B leads to problems if another module A.C is also imported) - if (Len(package) > 0) { - String *dotless_package = NewStringWithSize(package, Len(package) - 1); - if (Cmp(class_name, dotless_package) == 0) { - Swig_error(input_file, line_number, - "Class name cannot be the same as the root package it is in: %s\n", - class_name); - Exit(EXIT_FAILURE); - } - Delete(dotless_package); - } else { - String *outer = createFirstNamespaceName(nspace); - if (Cmp(class_name, outer) == 0) { - Swig_error(input_file, line_number, - "Class name cannot be the same as the outermost namespace it is in: %s\n", - class_name); - Exit(EXIT_FAILURE); - } - Delete(outer); - } - - // … and the innermost one (because of the conflict with the main proxy - // module named like the namespace). - String *inner = createLastNamespaceName(nspace); - if (Cmp(class_name, inner) == 0) { - Swig_error(input_file, line_number, - "Class name cannot be the same as the innermost namespace it is in: %s\n", - class_name); - Exit(EXIT_FAILURE); - } - Delete(inner); - } else { - if (Cmp(class_name, proxy_dmodule_name) == 0) { - Swig_error(input_file, line_number, - "Class name cannot be equal to proxy D module name: %s\n", - class_name); - Exit(EXIT_FAILURE); - } - } - } - } - - /* --------------------------------------------------------------------------- - * D::getPrimitiveDptype() - * - * Returns the D proxy type for the passed type if it is a primitive type in - * both C and D. - * --------------------------------------------------------------------------- */ - String *getPrimitiveDptype(Node *node, SwigType *type) { - SwigType *stripped_type = SwigType_typedef_resolve_all(type); - - // A reference can only be the »outermost element« of a type. - bool mutable_ref = false; - if (SwigType_isreference(stripped_type)) { - SwigType_del_reference(stripped_type); - - if (SwigType_isconst(stripped_type)) { - SwigType_del_qualifier(stripped_type); - } else { - mutable_ref = true; - } - } - - // Strip all the pointers from the type. - int indirection_count = 0; - while (SwigType_ispointer(stripped_type)) { - ++indirection_count; - SwigType_del_pointer(stripped_type); - } - - // Now that we got rid of the pointers, see if we are dealing with a - // primitive type. - String *dtype = 0; - if (SwigType_isfunction(stripped_type) && indirection_count > 0) { - // type was a function pointer, split it up. - SwigType_add_pointer(stripped_type); - --indirection_count; - - SwigType *return_type = Copy(stripped_type); - SwigType *params_type = SwigType_functionpointer_decompose(return_type); - String *return_dtype = getPrimitiveDptype(node, return_type); - Delete(return_type); - if (!return_dtype) { - return 0; - } - - List *parms = SwigType_parmlist(params_type); - List *param_dtypes = NewList(); - for (Iterator it = First(parms); it.item; it = Next(it)) { - String *current_dtype = getPrimitiveDptype(node, it.item); - if (Cmp(current_dtype, "void") == 0) { - // void somefunc(void) is legal syntax in C, but not in D, so simply - // skip the void parameter. - Delete(current_dtype); - continue; - } - if (!current_dtype) { - Delete(return_dtype); - Delete(param_dtypes); - return 0; - } - Append(param_dtypes, current_dtype); - } - - String *param_list = NewString(""); - { - bool gen_comma = false; - for (Iterator it = First(param_dtypes); it.item; it = Next(it)) { - if (gen_comma) { - Append(param_list, ", "); - } - Append(param_list, it.item); - Delete(it.item); - gen_comma = true; - } - } - - dtype = NewStringf("%s.SwigExternC!(%s function(%s))", im_dmodule_fq_name, - return_dtype, param_list); - Delete(param_list); - Delete(param_dtypes); - Delete(return_dtype); - } else { - Hash *attributes = NewHash(); - const String *tm = - lookupCodeTypemap(node, "dtype", stripped_type, WARN_NONE, attributes); - if(!GetFlag(attributes, "tmap:dtype:cprimitive")) { - dtype = 0; - } else { - dtype = Copy(tm); - - // We need to call replaceClassname here with the stripped type to avoid - // $dclassname in the enum typemaps being replaced later with the full - // type. - replaceClassname(dtype, stripped_type); - } - Delete(attributes); - } - Delete(stripped_type); - - if (!dtype) { - // The type passed is no primitive type. - return 0; - } - - // The type is ultimately a primitive type, now append the right number of - // indirection levels (pointers). - for (int i = 0; i < indirection_count; ++i) { - Append(dtype, "*"); - } - - // Add a level of indirection for a mutable reference since it is wrapped - // as a pointer. - if (mutable_ref) { - Append(dtype, "*"); - } - - return dtype; - } - - /* --------------------------------------------------------------------------- - * D::lookupCodeTypemap() - * - * Looks up a D code fragment for generating the wrapper class for the given - * type. - * - * n - for input only and must contain info for Getfile(n) and Getline(n) to work - * tmap_method - typemap method name - * type - typemap type to lookup - * warning - warning number to issue if no typemaps found - * typemap_attributes - the typemap attributes are attached to this node and will - * also be used for temporary storage if non null - * return is never NULL, unlike Swig_typemap_lookup() - * --------------------------------------------------------------------------- */ - const String *lookupCodeTypemap(Node *n, const_String_or_char_ptr tmap_method, - SwigType *type, int warning, Node *typemap_attributes = 0) const { - - Node *node = !typemap_attributes ? NewHash() : typemap_attributes; - Setattr(node, "type", type); - Setfile(node, Getfile(n)); - Setline(node, Getline(n)); - const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0); - if (!tm) { - tm = empty_string; - if (warning != WARN_NONE) { - Swig_warning(warning, Getfile(n), Getline(n), - "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0)); - } - } - if (!typemap_attributes) { - Delete(node); - } - - return tm; - } - - /* --------------------------------------------------------------------------- - * D::lookupDTypemap() - * - * Looks up a D typemap for the given node, replacing D-specific special - * variables as needed. - * - * The method parameter specifies the typemap method to use. If attached is - * true, the value is just fetched from the tmap:<method> node attribute, - * Swig_typemap_lookup is used otherwise. - * --------------------------------------------------------------------------- */ - String *lookupDTypemap(Node *n, const_String_or_char_ptr method, bool attached = false) { - String *result = 0; - - if (attached) { - String *attr_name = NewStringf("tmap:%s", method); - result = Copy(Getattr(n, attr_name)); - Delete(attr_name); - } else { - // FIXME: As a workaround for a bug so far only surfacing in the - // smart_pointer_const_overload test case, remove the nativepointer - // typemap attribute since it seems to be already there from a dout - // typemap of a different type in that test. - String *np_key = NewStringf("tmap:%s:nativepointer", method); - Delattr(n, np_key); - Delete(np_key); - - result = Swig_typemap_lookup(method, n, "", 0); - } - - if (!result) { - return 0; - } - - // Check if the passed node actually has type information attached. This - // is not the case e.g. in constructorWrapper. - SwigType *type = Getattr(n, "type"); - if (type) { - String *np_key = NewStringf("tmap:%s:nativepointer", method); - String *np_value = Getattr(n, np_key); - Delete(np_key); - String *dtype; - if (np_value && (dtype = getPrimitiveDptype(n, type))) { - // If the typemap in question has a »nativepointer« attribute and we - // are dealing with a primitive type, use it instead. - result = Copy(np_value); - Replaceall(result, "$dtype", dtype); - } - - replaceClassname(result, type); - } - - return result; - } - - /* --------------------------------------------------------------------------- - * D::replaceClassname() - * - * Replaces the special variable $dclassname with the proxy class name for - * classes/structs/unions SWIG knows about. Also substitutes the enumeration - * name for non-anonymous enums. Otherwise, $classname is replaced with a - * $descriptor(type)-like name. - * - * $*dclassname and $&classname work like with descriptors (see manual section - * 10.4.3), they remove a prointer from respectively add a pointer to the type. - * - * Inputs: - * tm - String to perform the substitution at (will usually come from a - * typemap. - * pt - The type to substitute for the variables. - * Outputs: - * tm - String with the variables substituted. - * Return: - * substitution_performed - flag indicating if a substitution was performed - * --------------------------------------------------------------------------- */ - bool replaceClassname(String *tm, SwigType *pt) { - bool substitution_performed = false; - SwigType *type = Copy(SwigType_typedef_resolve_all(pt)); - SwigType *strippedtype = SwigType_strip_qualifiers(type); - - if (Strstr(tm, "$dclassname")) { - SwigType *classnametype = Copy(strippedtype); - replaceClassnameVariable(tm, "$dclassname", classnametype); - substitution_performed = true; - Delete(classnametype); - } - if (Strstr(tm, "$*dclassname")) { - SwigType *classnametype = Copy(strippedtype); - Delete(SwigType_pop(classnametype)); - replaceClassnameVariable(tm, "$*dclassname", classnametype); - substitution_performed = true; - Delete(classnametype); - } - if (Strstr(tm, "$&dclassname")) { - SwigType *classnametype = Copy(strippedtype); - SwigType_add_pointer(classnametype); - replaceClassnameVariable(tm, "$&dclassname", classnametype); - substitution_performed = true; - Delete(classnametype); - } - - Delete(strippedtype); - Delete(type); - - return substitution_performed; - } - - /* --------------------------------------------------------------------------- - * D::replaceClassnameVariable() - * - * See D::replaceClassname(). - * --------------------------------------------------------------------------- */ - void replaceClassnameVariable(String *target, const char *variable, SwigType *type) { - // TODO: Fix const-correctness of methods called in here and make type const. - - // We make use of the fact that this function is called at least once for - // every type encountered which is written to a separate file, which allows - // us to handle imports here. - // When working in split proxy module mode, each generated proxy class/enum - // is written to a separate module. This requires us to add a corresponding - // import when a type is used in another generated module. If we are not - // working in split proxy module mode, this is not relevant and the - // generated module name is discarded. - String *type_name; - - if (SwigType_isenum(type)) { - // RESEARCH: Make sure that we really cannot get here for anonymous enums. - Node *n = enumLookup(type); - if (n) { - String *enum_name = Getattr(n, "sym:name"); - - Node *p = parentNode(n); - if (p && !Strcmp(nodeType(p), "class")) { - // This is a nested enum. - String *parent_name = Getattr(p, "sym:name"); - String *nspace = Getattr(p, "sym:nspace"); - - // An enum nested in a class is not written to a separate module (this - // would not even be possible in D), so just import the parent. - requireDType(nspace, parent_name); - - String *module = createModuleName(nspace, parent_name); - if (inProxyModule(module)) { - type_name = NewStringf("%s.%s", parent_name, enum_name); - } else { - type_name = NewStringf("%s%s.%s.%s", package, module, parent_name, enum_name); - } - } else { - // A non-nested enum is written to a separate module, import it. - String *nspace = Getattr(n, "sym:nspace"); - requireDType(nspace, enum_name); - - String *module = createModuleName(nspace, enum_name); - if (inProxyModule(module)) { - type_name = Copy(enum_name); - } else { - type_name = NewStringf("%s%s.%s", package, module, enum_name); - } - } - } else { - type_name = NewStringf("int"); - } - } else { - Node *n = classLookup(type); - if (n) { - String *class_name = Getattr(n, "sym:name"); - String *nspace = Getattr(n, "sym:nspace"); - requireDType(nspace, class_name); - - String *module = createModuleName(nspace, class_name); - if (inProxyModule(module)) { - type_name = Copy(class_name); - } else { - type_name = NewStringf("%s%s.%s", package, module, class_name); - } - Delete(module); - } else { - // SWIG does not know anything about the type (after resolving typedefs). - // Just mangle the type name string like $descriptor(type) would do. - String *descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type)); - requireDType(NULL, descriptor); - - String *module = createModuleName(NULL, descriptor); - if (inProxyModule(module)) { - type_name = Copy(descriptor); - } else { - type_name = NewStringf("%s%s.%s", package, module, descriptor); - } - Delete(module); - - // Add to hash table so that a type wrapper class can be created later. - Setattr(unknown_types, descriptor, type); - - Delete(descriptor); - } - } - - Replaceall(target, variable, type_name); - Delete(type_name); - } - - /* --------------------------------------------------------------------------- - * D::createModuleName() - * - * Returns a string holding the name of the module to import to bring the - * given type in scope. - * --------------------------------------------------------------------------- */ - String *createModuleName(const String *nspace, const String *type_name) const { - String *module; - if (nspace) { - module = NewStringf("%s.", nspace); - if (split_proxy_dmodule) { - Printv(module, type_name, NIL); - } else { - String *inner = createLastNamespaceName(nspace); - Printv(module, inner, NIL); - Delete(inner); - } - } else { - if (split_proxy_dmodule) { - module = Copy(type_name); - } else { - module = Copy(proxy_dmodule_name); - } - } - return module; - } - - /* --------------------------------------------------------------------------- - * D::replaceModuleVariables() - * - * Replaces the $imdmodule and $module variables with their values in the - * target string. - * --------------------------------------------------------------------------- */ - void replaceModuleVariables(String *target) const { - Replaceall(target, "$imdmodule", im_dmodule_fq_name); - Replaceall(target, "$module", proxy_dmodule_name); - } - - /* --------------------------------------------------------------------------- - * D::replaceExcode() - * - * If a C++ method can throw a exception, additional code is added to the - * proxy method to check if an exception is pending so that it can be - * rethrown on the D side. - * - * This method replaces the $excode variable with the exception handling code - * in the excode typemap attribute if it »canthrow« an exception. - * --------------------------------------------------------------------------- */ - void replaceExcode(Node *n, String *code, const String *typemap, Node *parameter) const { - String *excode_attribute = NewStringf("tmap:%s:excode", typemap); - String *excode = Getattr(parameter, excode_attribute); - if (Getattr(n, "d:canthrow")) { - int count = Replaceall(code, "$excode", excode); - if (count < 1 || !excode) { - Swig_warning(WARN_D_EXCODE_MISSING, input_file, line_number, - "D exception may not be thrown – no $excode or excode attribute in '%s' typemap.\n", - typemap); - } - } else { - Replaceall(code, "$excode", ""); - } - Delete(excode_attribute); - } - - /* --------------------------------------------------------------------------- - * D::replaceImportTypeMacros() - * - * Replaces the $importtype(SomeDClass) macro with an import statement if it - * is required to get SomeDClass in scope for the currently generated proxy - * D module. - * --------------------------------------------------------------------------- */ - void replaceImportTypeMacros(String *target) const { - // Code from replace_embedded_typemap. - char *start = 0; - while ((start = Strstr(target, "$importtype("))) { - char *end = 0; - char *param_start = 0; - char *param_end = 0; - int level = 0; - char *c = start; - while (*c) { - if (*c == '(') { - if (level == 0) { - param_start = c + 1; - } - level++; - } - if (*c == ')') { - level--; - if (level == 0) { - param_end = c; - end = c + 1; - break; - } - } - c++; - } - - if (end) { - String *current_macro = NewStringWithSize(start, (int)(end - start)); - String *current_param = NewStringWithSize(param_start, (int)(param_end - param_start)); - - - if (inProxyModule(current_param)) { - Replace(target, current_macro, "", DOH_REPLACE_ANY); - } else { - String *import = createImportStatement(current_param, false); - Replace(target, current_macro, import, DOH_REPLACE_ANY); - Delete(import); - } - - Delete(current_param); - Delete(current_macro); - } else { - String *current_macro = NewStringWithSize(start, (int)(c - start)); - Swig_error(Getfile(target), Getline(target), "Syntax error in: %s\n", current_macro); - Replace(target, current_macro, "<error in $importtype macro>", DOH_REPLACE_ANY); - Delete(current_macro); - } - } - } - - /* --------------------------------------------------------------------------- - * D::getOverloadedName() - * --------------------------------------------------------------------------- */ - String *getOverloadedName(Node *n) const { - // A void* parameter is used for all wrapped classes in the wrapper code. - // Thus, the wrapper function names for overloaded functions are postfixed - // with a counter string to make them unique. - String *overloaded_name = Copy(Getattr(n, "sym:name")); - - if (Getattr(n, "sym:overloaded")) { - Append(overloaded_name, Getattr(n, "sym:overname")); - } - - return overloaded_name; - } - - /* --------------------------------------------------------------------------- - * D::createProxyName() - * - * Returns the D class name if a type corresponds to something wrapped with a - * proxy class, NULL otherwise. - * --------------------------------------------------------------------------- */ - String *createProxyName(SwigType *t) { - String *proxyname = NULL; - Node *n = classLookup(t); - if (n) { - String *nspace = Getattr(n, "sym:nspace"); - String *symname = Getattr(n, "sym:name"); - - String *module = createModuleName(nspace, symname); - if (inProxyModule(module)) { - proxyname = Copy(symname); - } else { - proxyname = NewStringf("%s%s.%s", package, module, symname); - } - } - return proxyname; - } - - String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter) const { - String *arg = Language::makeParameterName(n, p, arg_num, setter); - - if (split_proxy_dmodule && Strncmp(arg, package, Len(arg)) == 0) { - // If we are in split proxy mode and the argument is named like the target - // package, we append an underscore to its name to avoid clashes. - Append(arg, "_"); - } - - return arg; - } - - /* --------------------------------------------------------------------------- - * D::canThrow() - * - * Determines whether the code in the typemap can throw a D exception. - * If so, note it for later when excodeSubstitute() is called. - * --------------------------------------------------------------------------- */ - void canThrow(Node *n, const String *typemap, Node *parameter) const { - String *canthrow_attribute = NewStringf("tmap:%s:canthrow", typemap); - String *canthrow = Getattr(parameter, canthrow_attribute); - if (canthrow) - Setattr(n, "d:canthrow", "1"); - Delete(canthrow_attribute); - } - - /* --------------------------------------------------------------------------- - * D::wrapMemberFunctionAsDConst() - * - * Determines whether the member function represented by the passed node is - * wrapped as D »const« or not. - * --------------------------------------------------------------------------- */ - bool wrapMemberFunctionAsDConst(Node *n) const { - if (d_version == 1) return false; - if (static_flag) return false; // Never emit »const« for static member functions. - return GetFlag(n, "memberget") || SwigType_isconst(Getattr(n, "decl")); - } - - /* --------------------------------------------------------------------------- - * D::areAllOverloadsOverridden() - * - * Determines whether the class the passed function node belongs to overrides - * all the overlaods for the passed function node defined somewhere up the - * inheritance hierarchy. - * --------------------------------------------------------------------------- */ - bool areAllOverloadsOverridden(Node *n) const { - List *base_list = Getattr(parentNode(n), "bases"); - if (!base_list) { - // If the class which contains n is not derived from any other class, - // there cannot be any not-overridden overloads. - return true; - } - - // In case of multiple base classes, skip to the one which has not been - // ignored. - // RESEARCH: Also emit a warning in case of multiple inheritance here? - Iterator it = First(base_list); - while (it.item && GetFlag(it.item, "feature:ignore")) { - it = Next(it); - } - Node *base_class = it.item; - - if (!base_class) { - // If all base classes have been ignored, there cannot be one either. - return true; - } - - // We try to find at least a single overload which exists in the base class - // so we can progress up the inheritance hierarchy even if there have been - // new overloads introduced after the topmost class. - Node *base_function = NULL; - String *symname = Getattr(n, "sym:name"); - if (symname) { - for (Node *tmp = firstChild(base_class); tmp; tmp = nextSibling(tmp)) { - String *child_symname = Getattr(tmp, "sym:name"); - if (child_symname && (Strcmp(child_symname, symname) == 0)) { - base_function = tmp; - break; - } - } - } - - if (!base_function) { - // If there is no overload which also exists in the super class, there - // cannot be any base class overloads not overridden. - return true; - } - - size_t base_overload_count = 0; - for (Node *tmp = firstSibling(base_function); tmp; tmp = Getattr(tmp, "sym:nextSibling")) { - if (is_protected(base_function) && - !(Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode())) { - // If the base class function is »protected« and were are not in - // director mode, it is not emitted to the base class and thus we do - // not count it. Otherwise, we would run into issues if the visibility - // of some functions was changed from protected to public in a child - // class with the using directive. - continue; - } - ++base_overload_count; - } - - return ((base_overload_count <= overridingOverloadCount(n)) && - areAllOverloadsOverridden(base_function)); - } - - /* --------------------------------------------------------------------------- - * D::overridingOverloadCount() - * - * Given a member function node, this function counts how many of the - * overloads of the function (including itself) override a function in the - * base class. - * --------------------------------------------------------------------------- */ - size_t overridingOverloadCount(Node *n) const { - size_t result = 0; - - Node *tmp = firstSibling(n); - do { - // KLUDGE: We also have to count the function if the access attribute is - // not present, since this means that it has been promoted into another - // protection level in the base class with the C++ »using« directive, and - // is thus taken into account when counting the base class overloads, even - // if it is not marked as »override« by the SWIG parser. - if (Getattr(n, "override") || !Getattr(n, "access")) { - ++result; - } - } while((tmp = Getattr(tmp, "sym:nextSibling"))); - - return result; - } - - /* --------------------------------------------------------------------------- - * D::firstSibling() - * - * Returns the first sibling of the passed node. - * --------------------------------------------------------------------------- */ - Node *firstSibling(Node *n) const { - Node *result = n; - while (Node *tmp = Getattr(result, "sym:previousSibling")) { - result = tmp; - } - return result; - } - - /* --------------------------------------------------------------------------- - * D::indentCode() - * - * Helper function to indent a code (string) by one level. - * --------------------------------------------------------------------------- */ - void indentCode(String* code) const { - Replaceall(code, "\n", "\n "); - Replaceall(code, " \n", "\n"); - Chop(code); - } - - /* --------------------------------------------------------------------------- - * D::emitBanner() - * --------------------------------------------------------------------------- */ - void emitBanner(File *f) const { - Printf(f, "/* ----------------------------------------------------------------------------\n"); - Swig_banner_target_lang(f, " *"); - Printf(f, " * ----------------------------------------------------------------------------- */\n\n"); - } - - /* --------------------------------------------------------------------------- - * D::outputDirectory() - * - * Returns the directory to write the D modules for the given namespace to and - * and creates the subdirectory if it doesn't exist. - * --------------------------------------------------------------------------- */ - String *outputDirectory(String *nspace) { - String *output_directory = Copy(dmodule_directory); - if (nspace) { - String *nspace_subdirectory = Copy(nspace); - Replaceall(nspace_subdirectory, ".", SWIG_FILE_DELIMITER); - String *newdir_error = Swig_new_subdirectory(output_directory, nspace_subdirectory); - if (newdir_error) { - Printf(stderr, "%s\n", newdir_error); - Delete(newdir_error); - Exit(EXIT_FAILURE); - } - Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0); - Delete(nspace_subdirectory); - } - return output_directory; - } - - /* --------------------------------------------------------------------------- - * D::proxyCodeBuffer() - * - * Returns the buffer to write proxy code for the given namespace to. - * --------------------------------------------------------------------------- */ - String *proxyCodeBuffer(String *nspace) { - if (!nspace) { - return proxy_dmodule_code; - } - - Hash *hash = Getattr(nspace_proxy_dmodules, nspace); - if (!hash) { - hash = NewHash(); - Setattr(hash, "code", NewString("")); - Setattr(hash, "imports", NewString("")); - Setattr(nspace_proxy_dmodules, nspace, hash); - } - return Getattr(hash, "code"); - } - - /* --------------------------------------------------------------------------- - * D::proxyCodeBuffer() - * - * Returns the buffer to write imports for the proxy code for the given - * namespace to. - * --------------------------------------------------------------------------- */ - String *proxyImportsBuffer(String *nspace) { - if (!nspace) { - return proxy_dmodule_imports; - } - - Hash *hash = Getattr(nspace_proxy_dmodules, nspace); - if (!hash) { - hash = NewHash(); - Setattr(hash, "code", NewString("")); - Setattr(hash, "imports", NewString("")); - Setattr(nspace_proxy_dmodules, nspace, hash); - } - return Getattr(hash, "imports"); - } - - /* --------------------------------------------------------------------------- - * D::createFirstNamespaceName() - * - * Returns a new string containing the name of the outermost namespace, e.g. - * »A« for the argument »A.B.C«. - * --------------------------------------------------------------------------- */ - String *createFirstNamespaceName(const String *nspace) const { - char *tmp = Char(nspace); - char *c = tmp; - char *co = 0; - if (!strstr(c, ".")) - return 0; - - co = c + Len(nspace); - - while (*c && (c != co)) { - if (*c == '.') { - break; - } - c++; - } - if (!*c || (c == tmp)) { - return NULL; - } - return NewStringWithSize(tmp, (int)(c - tmp)); - } - - /* --------------------------------------------------------------------------- - * D::createLastNamespaceName() - * - * Returns a new string containing the name of the innermost namespace, e.g. - * »C« for the argument »A.B.C«. - * --------------------------------------------------------------------------- */ - String *createLastNamespaceName(const String *nspace) const { - if (!nspace) return NULL; - char *c = Char(nspace); - char *cc = c; - if (!strstr(c, ".")) - return NewString(nspace); - - while (*c) { - if (*c == '.') { - cc = c; - } - ++c; - } - return NewString(cc + 1); - } - - /* --------------------------------------------------------------------------- - * D::createOuterNamespaceNames() - * - * Returns a new string containing the name of the outer namespace, e.g. - * »A.B« for the argument »A.B.C«. - * --------------------------------------------------------------------------- */ - String *createOuterNamespaceNames(const String *nspace) const { - if (!nspace) return NULL; - char *tmp = Char(nspace); - char *c = tmp; - char *cc = c; - if (!strstr(c, ".")) - return NULL; - - while (*c) { - if (*c == '.') { - cc = c; - } - ++c; - } - if (cc == tmp) { - return NULL; - } - return NewStringWithSize(tmp, (int)(cc - tmp)); - } -}; - -static Language *new_swig_d() { - return new D(); -} - -/* ----------------------------------------------------------------------------- - * swig_d() - Instantiate module - * ----------------------------------------------------------------------------- */ -extern "C" Language *swig_d(void) { - return new_swig_d(); -} - -/* ----------------------------------------------------------------------------- - * Usage information displayed at the command line. - * ----------------------------------------------------------------------------- */ -const char *D::usage = "\ -D Options (available with -d)\n\ - -d2 - Generate code for D2/Phobos (default: D1/Tango)\n\ - -package <pkg> - Write generated D modules into package <pkg>\n\ - -splitproxy - Write each D type to a dedicated file instead of\n\ - generating a single proxy D module.\n\ - -wrapperlibrary <wl> - Set the name of the wrapper library to <wl>\n\ -\n"; diff --git a/contrib/tools/swig/Source/Modules/directors.cxx b/contrib/tools/swig/Source/Modules/directors.cxx deleted file mode 100644 index 14e2e846619..00000000000 --- a/contrib/tools/swig/Source/Modules/directors.cxx +++ /dev/null @@ -1,270 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * directors.cxx - * - * Director support functions. - * Not all of these may be necessary, and some may duplicate existing functionality - * in SWIG. --MR - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" - -/* ----------------------------------------------------------------------------- - * Swig_csuperclass_call() - * - * Generates a fully qualified method call, including the full parameter list. - * e.g. "base::method(i, j)" - * ----------------------------------------------------------------------------- */ - -String *Swig_csuperclass_call(String *base, String *method, ParmList *l) { - String *call = NewString(""); - int arg_idx = 0; - Parm *p; - if (base) { - Printf(call, "%s::", base); - } - Printf(call, "%s(", method); - for (p = l; p; p = nextSibling(p)) { - String *pname = Getattr(p, "name"); - if (!pname && Cmp(Getattr(p, "type"), "void")) { - pname = NewString(""); - Printf(pname, "arg%d", arg_idx++); - } - if (p != l) - Printf(call, ", "); - Printv(call, pname, NIL); - } - Printf(call, ")"); - return call; -} - -/* ----------------------------------------------------------------------------- - * Swig_class_declaration() - * - * Generate the start of a class/struct declaration. - * e.g. "class myclass" - * ----------------------------------------------------------------------------- */ - -String *Swig_class_declaration(Node *n, String *name) { - if (!name) { - name = Getattr(n, "sym:name"); - } - String *result = NewString(""); - String *kind = Getattr(n, "kind"); - Printf(result, "%s %s", kind, name); - return result; -} - -/* ----------------------------------------------------------------------------- - * Swig_class_name() - * ----------------------------------------------------------------------------- */ - -String *Swig_class_name(Node *n) { - String *name; - name = Copy(Getattr(n, "sym:name")); - return name; -} - -/* ----------------------------------------------------------------------------- - * Swig_director_declaration() - * - * Generate the full director class declaration, complete with base classes. - * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {" - * ----------------------------------------------------------------------------- */ - -String *Swig_director_declaration(Node *n) { - String *classname = Swig_class_name(n); - String *directorname = Language::instance()->directorClassName(n); - String *base = Getattr(n, "classtype"); - String *declaration = Swig_class_declaration(n, directorname); - - Printf(declaration, " : public %s, public Swig::Director {\n", base); - Delete(classname); - Delete(directorname); - return declaration; -} - - -/* ----------------------------------------------------------------------------- - * Swig_method_call() - * ----------------------------------------------------------------------------- */ - -String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) { - String *func; - int comma = 0; - Parm *p = parms; - SwigType *pt; - String *nname; - - func = NewString(""); - nname = SwigType_namestr(name); - Printf(func, "%s(", nname); - while (p) { - String *pname; - pt = Getattr(p, "type"); - if ((SwigType_type(pt) != T_VOID)) { - if (comma) - Printf(func, ","); - pname = Getattr(p, "name"); - Printf(func, "%s", pname); - comma = 1; - } - p = nextSibling(p); - } - Printf(func, ")"); - return func; -} - -/* ----------------------------------------------------------------------------- - * Swig_method_decl() - * - * Return a stringified version of a C/C++ declaration. - * ----------------------------------------------------------------------------- */ - -String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_String_or_char_ptr id, List *args, int default_args) { - String *result = NewString(""); - bool conversion_operator = Strstr(id, "operator ") != 0 && !return_base_type; - - Parm *parm = args; - int arg_idx = 0; - while (parm) { - String *type = Getattr(parm, "type"); - String *name = Getattr(parm, "name"); - if (!name && Cmp(type, "void")) { - name = NewString(""); - Printf(name, "arg%d", arg_idx++); - Setattr(parm, "name", name); - } - parm = nextSibling(parm); - } - - String *rettype = Copy(decl); - String *quals = SwigType_pop_function_qualifiers(rettype); - String *qualifiers = 0; - if (quals) - qualifiers = SwigType_str(quals, 0); - - String *popped_decl = SwigType_pop_function(rettype); - if (return_base_type) - Append(rettype, return_base_type); - - if (!conversion_operator) { - SwigType *rettype_stripped = SwigType_strip_qualifiers(rettype); - String *rtype = SwigType_str(rettype, 0); - Append(result, rtype); - if ((SwigType_issimple(rettype_stripped) && return_base_type) || SwigType_isqualifier(rettype)) - Append(result, " "); - Delete(rtype); - Delete(rettype_stripped); - } - - if (id) - Append(result, id); - - String *args_string = default_args ? ParmList_str_defaultargs(args) : ParmList_str(args); - Printv(result, "(", args_string, ")", NIL); - - if (qualifiers) - Printv(result, " ", qualifiers, NIL); - - Delete(args_string); - Delete(popped_decl); - Delete(qualifiers); - Delete(quals); - Delete(rettype); - return result; -} - -/* ----------------------------------------------------------------------------- - * Swig_director_emit_dynamic_cast() - * - * In order to call protected virtual director methods from the target language, we need - * to add an extra dynamic_cast to call the public C++ wrapper in the director class. - * Also for non-static protected members when the allprotected option is on. - * ----------------------------------------------------------------------------- */ - -void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) { - // TODO: why is the storage element removed in staticmemberfunctionHandler ?? - if ((!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) || - (is_non_virtual_protected_access(n) && !(Swig_storage_isstatic_custom(n, "staticmemberfunctionHandler:storage") || - Swig_storage_isstatic(n)) - && !Equal(nodeType(n), "constructor"))) { - Node *parent = Getattr(n, "parentNode"); - String *dirname; - String *dirdecl; - dirname = Language::instance()->directorClassName(parent); - dirdecl = NewStringf("%s *darg = 0", dirname); - Wrapper_add_local(f, "darg", dirdecl); - Printf(f->code, "darg = dynamic_cast<%s *>(arg1);\n", dirname); - Delete(dirname); - Delete(dirdecl); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_director_parms_fixup() - * - * For each parameter in the C++ member function, copy the parameter name - * to its "lname"; this ensures that Swig_typemap_attach_parms() will do - * the right thing when it sees strings like "$1" in "directorin" typemaps. - * ----------------------------------------------------------------------------- */ - -void Swig_director_parms_fixup(ParmList *parms) { - Parm *p; - int i; - for (i = 0, p = parms; p; p = nextSibling(p), ++i) { - String *arg = Getattr(p, "name"); - String *lname = 0; - - if (!arg && !Equal(Getattr(p, "type"), "void")) { - lname = NewStringf("arg%d", i); - Setattr(p, "name", lname); - } else - lname = Copy(arg); - - Setattr(p, "lname", lname); - Delete(lname); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_director_can_unwrap() - * - * Determine whether a function's return type can be returned as an existing - * target language object instead of creating a new target language object. - * Must be a director class and only for return by pointer or reference only - * (not by value or by pointer to pointer etc). - * ----------------------------------------------------------------------------- */ - -bool Swig_director_can_unwrap(Node *n) { - - // FIXME: this will not try to unwrap directors returned as non-director - // base class pointers! - - bool unwrap = false; - - String *type = Getattr(n, "type"); - SwigType *t = SwigType_typedef_resolve_all(type); - SwigType *t1 = SwigType_strip_qualifiers(t); - SwigType *prefix = SwigType_prefix(t1); - - if (Strcmp(prefix, "p.") == 0 || Strcmp(prefix, "r.") == 0) { - Node *parent = Swig_methodclass(n); - Node *module = Getattr(parent, "module"); - Node *target = Swig_directormap(module, t1); - if (target) - unwrap = true; - } - - Delete(prefix); - Delete(t1); - Delete(t); - - return unwrap; -} diff --git a/contrib/tools/swig/Source/Modules/emit.cxx b/contrib/tools/swig/Source/Modules/emit.cxx deleted file mode 100644 index 74adc540096..00000000000 --- a/contrib/tools/swig/Source/Modules/emit.cxx +++ /dev/null @@ -1,556 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * emit.cxx - * - * Useful functions for emitting various pieces of code. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" - -/* ----------------------------------------------------------------------------- - * emit_return_variable() - * - * Emits a variable declaration for a function return value. - * The variable name is always called result. - * n => Node of the method being wrapped - * rt => the return type - * f => the wrapper to generate code into - * ----------------------------------------------------------------------------- */ - -void emit_return_variable(Node *n, SwigType *rt, Wrapper *f) { - - if (!GetFlag(n, "tmap:out:optimal")) { - if (rt && (SwigType_type(rt) != T_VOID)) { - SwigType *vt = cplus_value_type(rt); - SwigType *tt = vt ? vt : rt; - SwigType *lt = SwigType_ltype(tt); - String *lstr = SwigType_str(lt, Swig_cresult_name()); - if (SwigType_ispointer(lt)) { - Wrapper_add_localv(f, Swig_cresult_name(), lstr, "= 0", NULL); - } else { - Wrapper_add_local(f, Swig_cresult_name(), lstr); - } - if (vt) { - Delete(vt); - } - Delete(lt); - Delete(lstr); - } - } -} - -/* ----------------------------------------------------------------------------- - * emit_parameter_variables() - * - * Emits a list of variable declarations for function parameters. - * The variable names are always called arg1, arg2, etc... - * l => the parameter list - * f => the wrapper to generate code into - * ----------------------------------------------------------------------------- */ - -void emit_parameter_variables(ParmList *l, Wrapper *f) { - - Parm *p; - String *tm; - - /* Emit function arguments */ - Swig_cargs(f, l); - - /* Attach typemaps to parameters */ - /* Swig_typemap_attach_parms("ignore",l,f); */ - - Swig_typemap_attach_parms("default", l, f); - Swig_typemap_attach_parms("arginit", l, f); - - /* Apply the arginit and default */ - p = l; - while (p) { - tm = Getattr(p, "tmap:arginit"); - if (tm) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:arginit:next"); - } else { - p = nextSibling(p); - } - } - - /* Apply the default typemap */ - p = l; - while (p) { - tm = Getattr(p, "tmap:default"); - if (tm) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:default:next"); - } else { - p = nextSibling(p); - } - } -} - -/* ----------------------------------------------------------------------------- - * emit_attach_parmmaps() - * - * Attach the standard parameter related typemaps. - * ----------------------------------------------------------------------------- */ - -void emit_attach_parmmaps(ParmList *l, Wrapper *f) { - Swig_typemap_attach_parms("in", l, f); - Swig_typemap_attach_parms("typecheck", l, 0); - Swig_typemap_attach_parms("argout", l, f); - Swig_typemap_attach_parms("check", l, f); - Swig_typemap_attach_parms("freearg", l, f); - - { - /* This is compatibility code to deal with the deprecated "ignore" typemap */ - Parm *p = l; - Parm *np; - while (p) { - String *tm = Getattr(p, "tmap:in"); - if (tm && checkAttribute(p, "tmap:in:numinputs", "0")) { - Printv(f->code, tm, "\n", NIL); - np = Getattr(p, "tmap:in:next"); - while (p && (p != np)) { - /* Setattr(p,"ignore","1"); Deprecate */ - p = nextSibling(p); - } - } else if (tm) { - p = Getattr(p, "tmap:in:next"); - } else { - p = nextSibling(p); - } - } - } - - /* Perform a sanity check on "in" and "freearg" typemaps. These - must exactly match to avoid chaos. If a mismatch occurs, we - nuke the freearg typemap */ - { - Parm *p = l; - Parm *npin, *npfreearg; - while (p) { - npin = Getattr(p, "tmap:in:next"); - - /* - if (Getattr(p,"tmap:ignore")) { - npin = Getattr(p,"tmap:ignore:next"); - } else if (Getattr(p,"tmap:in")) { - npin = Getattr(p,"tmap:in:next"); - } - */ - - if (Getattr(p, "tmap:freearg")) { - npfreearg = Getattr(p, "tmap:freearg:next"); - if (npin != npfreearg) { - while (p != npin) { - Delattr(p, "tmap:freearg"); - Delattr(p, "tmap:freearg:next"); - p = nextSibling(p); - } - } - } - p = npin; - } - } - - /* Check for variable length arguments with no input typemap. - If no input is defined, we set this to ignore and print a - message. - */ - { - Parm *p = l; - Parm *lp = 0; - while (p) { - if (!checkAttribute(p, "tmap:in:numinputs", "0")) { - lp = p; - p = Getattr(p, "tmap:in:next"); - continue; - } - if (SwigType_isvarargs(Getattr(p, "type"))) { - Swig_warning(WARN_LANG_VARARGS, input_file, line_number, "Variable length arguments discarded.\n"); - Setattr(p, "tmap:in", ""); - } - lp = 0; - p = nextSibling(p); - } - - /* Check if last input argument is variable length argument */ - if (lp) { - p = lp; - while (p) { - if (SwigType_isvarargs(Getattr(p, "type"))) { - // Mark the head of the ParmList that it has varargs - Setattr(l, "emit:varargs", lp); -//Printf(stdout, "setting emit:varargs %s ... %s +++ %s\n", Getattr(l, "emit:varargs"), Getattr(l, "type"), Getattr(p, "type")); - break; - } - p = nextSibling(p); - } - } - } - - /* - * An equivalent type can be used in the typecheck typemap for SWIG to detect the overloading of equivalent - * target language types. This is primarily for the smartptr feature, where a pointer and a smart pointer - * are seen as equivalent types in the target language. - */ - { - Parm *p = l; - while (p) { - String *tm = Getattr(p, "tmap:typecheck"); - if (tm) { - String *equivalent = Getattr(p, "tmap:typecheck:equivalent"); - if (equivalent) { - String *precedence = Getattr(p, "tmap:typecheck:precedence"); - if (precedence && Strcmp(precedence, "0") != 0) - Swig_error(Getfile(tm), Getline(tm), "The 'typecheck' typemap for %s contains an 'equivalent' attribute for a 'precedence' that is not set to SWIG_TYPECHECK_POINTER or 0.\n", SwigType_str(Getattr(p, "type"), 0)); - SwigType *cpt = Swig_cparse_type(equivalent); - if (cpt) { - Setattr(p, "equivtype", cpt); - Delete(cpt); - } else { - Swig_error(Getfile(tm), Getline(tm), "Invalid type (%s) in 'equivalent' attribute in 'typecheck' typemap for type %s.\n", equivalent, SwigType_str(Getattr(p, "type"), 0)); - } - } - p = Getattr(p, "tmap:typecheck:next"); - } else { - p = nextSibling(p); - } - } - } -} - -/* ----------------------------------------------------------------------------- - * emit_num_arguments() - * - * Calculate the total number of arguments. This function is safe for use - * with multi-argument typemaps which may change the number of arguments in - * strange ways. - * ----------------------------------------------------------------------------- */ - -int emit_num_arguments(ParmList *parms) { - Parm *p = parms; - int nargs = 0; - - while (p) { - if (Getattr(p, "tmap:in")) { - nargs += GetInt(p, "tmap:in:numinputs"); - p = Getattr(p, "tmap:in:next"); - } else { - p = nextSibling(p); - } - } - - /* DB 04/02/2003: Not sure this is necessary with tmap:in:numinputs */ - /* - if (parms && (p = Getattr(parms,"emit:varargs"))) { - if (!nextSibling(p)) { - nargs--; - } - } - */ - return nargs; -} - -/* ----------------------------------------------------------------------------- - * emit_num_required() - * - * Computes the number of required arguments. This function is safe for - * use with multi-argument typemaps and knows how to skip over everything - * properly. Note that parameters with default values are counted unless - * the compact default args option is on. - * ----------------------------------------------------------------------------- */ - -int emit_num_required(ParmList *parms) { - Parm *p = parms; - int nargs = 0; - Parm *first_default_arg = 0; - int compactdefargs = ParmList_is_compactdefargs(p); - - while (p) { - if (Getattr(p, "tmap:in") && checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } else { - if (Getattr(p, "tmap:default")) - break; - if (Getattr(p, "value")) { - if (!first_default_arg) - first_default_arg = p; - if (compactdefargs) - break; - } - nargs += GetInt(p, "tmap:in:numinputs"); - if (Getattr(p, "tmap:in")) { - p = Getattr(p, "tmap:in:next"); - } else { - p = nextSibling(p); - } - } - } - - /* Print error message for non-default arguments following default arguments */ - /* The error message is printed more than once with most language modules, this ought to be fixed */ - if (first_default_arg) { - p = first_default_arg; - while (p) { - if (Getattr(p, "tmap:in") && checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } else { - if (!Getattr(p, "value") && (!Getattr(p, "tmap:default"))) { - Swig_error(Getfile(p), Getline(p), "Non-optional argument '%s' follows an optional argument.\n", Getattr(p, "name")); - } - if (Getattr(p, "tmap:in")) { - p = Getattr(p, "tmap:in:next"); - } else { - p = nextSibling(p); - } - } - } - } - - /* DB 04/02/2003: Not sure this is necessary with tmap:in:numinputs */ - /* - if (parms && (p = Getattr(parms,"emit:varargs"))) { - if (!nextSibling(p)) { - nargs--; - } - } - */ - return nargs; -} - -/* ----------------------------------------------------------------------------- - * emit_isvarargs() - * - * Checks if a ParmList is a parameter list containing varargs. - * This function requires emit_attach_parmmaps to have been called beforehand. - * ----------------------------------------------------------------------------- */ - -int emit_isvarargs(ParmList *p) { - if (!p) - return 0; - if (Getattr(p, "emit:varargs")) - return 1; - return 0; -} - -/* ----------------------------------------------------------------------------- - * emit_isvarargs_function() - * - * Checks for varargs in a function/constructor (can be overloaded) - * ----------------------------------------------------------------------------- */ - -bool emit_isvarargs_function(Node *n) { - bool has_varargs = false; - Node *over = Getattr(n, "sym:overloaded"); - if (over) { - for (Node *sibling = over; sibling; sibling = Getattr(sibling, "sym:nextSibling")) { - if (ParmList_has_varargs(Getattr(sibling, "parms"))) { - has_varargs = true; - break; - } - } - } else { - has_varargs = ParmList_has_varargs(Getattr(n, "parms")) ? true : false; - } - return has_varargs; -} - -/* ----------------------------------------------------------------------------- - * void emit_mark_vararg_parms() - * - * Marks the vararg parameters which are to be ignored. - * Vararg parameters are marked as ignored if there is no 'in' varargs (...) - * typemap. - * ----------------------------------------------------------------------------- */ - -void emit_mark_varargs(ParmList *l) { - Parm *p = l; - while (p) { - if (SwigType_isvarargs(Getattr(p, "type"))) - if (!Getattr(p, "tmap:in")) - Setattr(p, "varargs:ignore", "1"); - p = nextSibling(p); - } -} - -#if 0 -/* replace_contract_args. This function replaces argument names in contract - specifications. Used in conjunction with the %contract directive. */ - -static void replace_contract_args(Parm *cp, Parm *rp, String *s) { - while (cp && rp) { - String *n = Getattr(cp, "name"); - if (n) { - Replace(s, n, Getattr(rp, "lname"), DOH_REPLACE_ID); - } - cp = nextSibling(cp); - rp = nextSibling(rp); - } -} -#endif - -/* ----------------------------------------------------------------------------- - * int emit_action_code() - * - * Emits action code for a wrapper. Adds in exception handling code (%exception). - * eaction -> the action code to emit - * wrappercode -> the emitted code (output) - * ----------------------------------------------------------------------------- */ -int emit_action_code(Node *n, String *wrappercode, String *eaction) { - assert(Getattr(n, "wrap:name")); - - /* Look for except feature (%exception) */ - String *tm = GetFlagAttr(n, "feature:except"); - if (tm) - tm = Copy(tm); - if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { - if (Strstr(tm, "$")) { - Swig_replace_special_variables(n, parentNode(n), tm); - Replaceall(tm, "$function", eaction); // deprecated - Replaceall(tm, "$action", eaction); - } - Printv(wrappercode, tm, "\n", NIL); - Delete(tm); - return 1; - } else { - Printv(wrappercode, eaction, "\n", NIL); - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * int emit_action() - * - * Emits the call to the wrapped function. - * Adds in exception specification exception handling and %exception code. - * ----------------------------------------------------------------------------- */ -String *emit_action(Node *n) { - String *actioncode = NewStringEmpty(); - String *tm; - String *action; - String *wrap; - ParmList *catchlist = Getattr(n, "catchlist"); - - /* Look for fragments */ - { - String *fragment = Getattr(n, "feature:fragment"); - if (fragment) { - char *c, *tok; - String *t = Copy(fragment); - c = Char(t); - tok = strtok(c, ","); - while (tok) { - String *fname = NewString(tok); - Setfile(fname, Getfile(n)); - Setline(fname, Getline(n)); - Swig_fragment_emit(fname); - Delete(fname); - tok = strtok(NULL, ","); - } - Delete(t); - } - } - - /* Emit wrapper code (if any) */ - wrap = Getattr(n, "wrap:code"); - if (wrap && Swig_filebyname("header") != Getattr(n, "wrap:code:done")) { - File *f_code = Swig_filebyname("header"); - if (f_code) { - Printv(f_code, wrap, NIL); - } - Setattr(n, "wrap:code:done", f_code); - } - - action = Getattr(n, "feature:action"); - if (!action) - action = Getattr(n, "wrap:action"); - assert(action != 0); - - /* Emit contract code (if any) */ - if (Swig_contract_mode_get()) { - /* Preassertion */ - tm = Getattr(n, "contract:preassert"); - if (Len(tm)) { - Printv(actioncode, tm, "\n", NIL); - } - } - /* Exception handling code */ - - /* saves action -> eaction for postcatching exception */ - String *eaction = NewString(""); - - /* If we are in C++ mode and there is an exception specification. We're going to - enclose the block in a try block */ - if (catchlist) { - Printf(eaction, "try {\n"); - } - - String *preaction = Getattr(n, "wrap:preaction"); - if (preaction) - Printv(eaction, preaction, NIL); - - Printv(eaction, action, NIL); - - String *postaction = Getattr(n, "wrap:postaction"); - if (postaction) - Printv(eaction, postaction, NIL); - - if (catchlist) { - int unknown_catch = 0; - int has_varargs = 0; - Printf(eaction, "}"); - for (Parm *ep = catchlist; ep; ep = nextSibling(ep)) { - String *em = Swig_typemap_lookup("throws", ep, "_e", 0); - if (em) { - SwigType *et = Getattr(ep, "type"); - SwigType *etr = SwigType_typedef_resolve_all(et); - if (SwigType_isreference(etr) || SwigType_ispointer(etr) || SwigType_isarray(etr)) { - Printf(eaction, " catch(%s) {", SwigType_str(et, "_e")); - } else if (SwigType_isvarargs(etr)) { - Printf(eaction, " catch(...) {"); - has_varargs = 1; - } else { - Printf(eaction, " catch(%s) {", SwigType_str(et, "&_e")); - } - Printv(eaction, em, "\n", NIL); - Printf(eaction, "}"); - } else { - Swig_warning(WARN_TYPEMAP_THROW, Getfile(n), Getline(n), "No 'throws' typemap defined for exception type '%s'\n", SwigType_str(Getattr(ep, "type"), 0)); - unknown_catch = 1; - } - } - if (unknown_catch && !has_varargs) { - Printf(eaction, " catch(...) {\nthrow;\n}"); - } - } - - /* Look for except typemap (Deprecated) */ - tm = Swig_typemap_lookup("except", n, Swig_cresult_name(), 0); - if (tm) { - Setattr(n, "feature:except", tm); - tm = 0; - } - - /* emit the except feature code */ - emit_action_code(n, actioncode, eaction); - - Delete(eaction); - - /* Emit contract code (if any) */ - if (Swig_contract_mode_get()) { - /* Postassertion */ - tm = Getattr(n, "contract:postassert"); - if (Len(tm)) { - Printv(actioncode, tm, "\n", NIL); - } - } - - return actioncode; -} diff --git a/contrib/tools/swig/Source/Modules/go.cxx b/contrib/tools/swig/Source/Modules/go.cxx deleted file mode 100644 index bf63bec6390..00000000000 --- a/contrib/tools/swig/Source/Modules/go.cxx +++ /dev/null @@ -1,5708 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * go.cxx - * - * Go language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" -#include <ctype.h> - -/* ---------------------------------------------------------------------- - * siphash() - * - * 64-bit SipHash-2-4 to generate unique id for each module - * ---------------------------------------------------------------------- */ - -// An unsigned 64-bit integer that works on a 32-bit host. -typedef struct { - // Assume unsigned long is at least 32 bits. - unsigned long hi; - unsigned long lo; -} swig_uint64; - -// Rotate v left by bits, which must be <= 32. -static inline void _rotl(swig_uint64 *v, int bits) { - assert(bits <= 32); - unsigned long tmp = v->hi; - if (bits == 32) { - v->hi = v->lo; - v->lo = tmp; - } else { - v->hi = (tmp << bits) | ((0xfffffffful & v->lo) >> (32 - bits)); - v->lo = (v->lo << bits) | ((0xfffffffful & tmp) >> (32 - bits)); - } -} - -// dst ^= src -static inline void _xor(swig_uint64 *dst, swig_uint64 *src) { - dst->lo ^= src->lo; - dst->hi ^= src->hi; -} - -// dst += src -static inline void _add(swig_uint64 *dst, swig_uint64 *src) { - dst->lo += src->lo; - dst->hi += src->hi + ((dst->lo & 0xfffffffful) < (src->lo&0xfffffffful) ? 1 : 0); -} -#define SIPROUND \ - do { \ - _add(&v0, &v1); _rotl(&v1, 13); _xor(&v1, &v0); _rotl(&v0, 32); \ - _add(&v2, &v3); _rotl(&v3, 16); _xor(&v3, &v2); \ - _add(&v0, &v3); _rotl(&v3, 21); _xor(&v3, &v0); \ - _add(&v2, &v1); _rotl(&v1, 17); _xor(&v1, &v2); _rotl(&v2, 32); \ - } while(0) - -// Set out to the hash of inc/inlen. -static void siphash(swig_uint64 *out, const char *inc, unsigned long inlen) { - /* "somepseudorandomlygeneratedbytes" */ - swig_uint64 v0 = {0x736f6d65UL, 0x70736575UL}; - swig_uint64 v1 = {0x646f7261UL, 0x6e646f6dUL}; - swig_uint64 v2 = {0x6c796765UL, 0x6e657261UL}; - swig_uint64 v3 = {0x74656462UL, 0x79746573UL}; - swig_uint64 b; - /* hard-coded k. */ - swig_uint64 k0 = {0x07060504UL, 0x03020100UL}; - swig_uint64 k1 = {0x0F0E0D0CUL, 0x0B0A0908UL}; - int i; - const int cROUNDS = 2, dROUNDS = 4; - const unsigned char *in = (const unsigned char *)inc; - const unsigned char *end = in + inlen - (inlen % 8); - int left = inlen & 7; - _xor(&v3, &k1); _xor(&v2, &k0); _xor(&v1, &k1); _xor(&v0, &k0); - for (; in != end; in += 8) { - b.hi = 0; b.lo = 0; - for (i = 0; i < 4; i++) { - b.lo |= ((unsigned long)in[i]) << (8*i); - } - for (i = 0; i < 4; i++) { - b.hi |= ((unsigned long)in[i+4]) << (8*i); - } - _xor(&v3, &b); - for (i = 0; i < cROUNDS; i++) { - SIPROUND; - } - _xor(&v0, &b); - } - b.hi = (inlen & 0xff)<<24; b.lo = 0; - for (; left; left--) { - if (left > 4) { - b.hi |= ((unsigned long)in[left-1]) << (8*left-8-32); - } else { - b.lo |= ((unsigned long)in[left-1]) << (8*left-8); - } - } - _xor(&v3, &b); - for(i=0; i<cROUNDS; i++) { - SIPROUND; - } - _xor(&v0, &b); v2.lo ^= 0xff; - for(i=0; i<dROUNDS; i++) { - SIPROUND; - } - out->lo = 0; out->hi = 0; - _xor(out, &v0); _xor(out, &v1); _xor(out, &v2); _xor(out, &v3); -} -#undef SIPROUND - -class GO:public Language { - static const char *const usage; - - // Go package name. - String *package; - // SWIG module name. - String *module; - // Flag for generating gccgo output. - bool gccgo_flag; - // Prefix to use with gccgo. - String *go_prefix; - // -fgo-prefix option. - String *prefix_option; - // -fgo-pkgpath option. - String *pkgpath_option; - // Prefix for translating %import directive to import statements. - String *import_prefix; - // Whether to use a shared library. - bool use_shlib; - // Name of shared library to import. - String *soname; - // Size in bits of the Go type "int". 0 if not specified. - int intgo_type_size; - - /* Output files */ - File *f_c_begin; - File *f_go_begin; - - /* Output fragments */ - File *f_c_runtime; - File *f_c_header; - File *f_c_wrappers; - File *f_c_init; - File *f_c_directors; - File *f_c_directors_h; - File *f_go_imports; - File *f_go_runtime; - File *f_go_header; - File *f_go_wrappers; - File *f_go_directors; - File *f_cgo_comment; - File *f_cgo_comment_typedefs; - - // True if we imported a module. - bool saw_import; - // If not NULL, name of import package being processed. - String *imported_package; - // Build interface methods while handling a class. This is only - // non-NULL when we are handling methods. - String *interfaces; - // The class node while handling a class. This is only non-NULL - // when we are handling methods. - Node *class_node; - // The class name while handling a class. This is only non-NULL - // when we are handling methods. This is the name of the class as - // SWIG sees it. - String *class_name; - // The receiver name while handling a class. This is only non-NULL - // when we are handling methods. This is the name of the class - // as run through goCPointerType. - String *class_receiver; - // A hash table of method names that we have seen when processing a - // class. This lets us detect base class methods that we don't want - // to use. - Hash *class_methods; - // True when we are generating the wrapper functions for a variable. - bool making_variable_wrappers; - // True when working with a static member function. - bool is_static_member_function; - // A hash table of enum types that we have seen but which may not have - // been defined. The index is a SwigType. - Hash *undefined_enum_types; - // A hash table of types that we have seen but which may not have - // been defined. The index is a SwigType. - Hash *undefined_types; - // A hash table of classes which were defined. The index is a Go - // type name. - Hash *defined_types; - // A hash table of all the go_imports already imported. The index is a full - // import name e.g. '"runtime"' or '_ "runtime/cgo"' or 'sc "syscall"'. - Hash *go_imports; - // A unique ID used to make public symbols unique. - String *unique_id; - -public: - GO():package(NULL), - module(NULL), - gccgo_flag(false), - go_prefix(NULL), - prefix_option(NULL), - pkgpath_option(NULL), - import_prefix(NULL), - use_shlib(false), - soname(NULL), - intgo_type_size(0), - f_c_begin(NULL), - f_go_begin(NULL), - f_c_runtime(NULL), - f_c_header(NULL), - f_c_wrappers(NULL), - f_c_init(NULL), - f_c_directors(NULL), - f_c_directors_h(NULL), - f_go_imports(NULL), - f_go_runtime(NULL), - f_go_header(NULL), - f_go_wrappers(NULL), - f_go_directors(NULL), - f_cgo_comment(NULL), - f_cgo_comment_typedefs(NULL), - saw_import(false), - imported_package(NULL), - interfaces(NULL), - class_node(NULL), - class_name(NULL), - class_receiver(NULL), - class_methods(NULL), - making_variable_wrappers(false), - is_static_member_function(false), - undefined_enum_types(NULL), - undefined_types(NULL), - defined_types(NULL), - go_imports(NULL), - unique_id(NULL) { - director_multiple_inheritance = 1; - director_language = 1; - director_prot_ctor_code = NewString("_swig_gopanic(\"accessing abstract class or protected constructor\");"); - } - -private: - /* ------------------------------------------------------------ - * main() - * ------------------------------------------------------------ */ - virtual void main(int argc, char *argv[]) { - - SWIG_library_directory("go"); - bool saw_nocgo_flag = false; - - // Process command line options. - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-package") == 0) { - if (argv[i + 1]) { - package = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-cgo") == 0) { - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-no-cgo") == 0) { - Swig_mark_arg(i); - saw_nocgo_flag = true; - } else if (strcmp(argv[i], "-gccgo") == 0) { - Swig_mark_arg(i); - gccgo_flag = true; - } else if (strcmp(argv[i], "-go-prefix") == 0) { - if (argv[i + 1]) { - prefix_option = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-go-pkgpath") == 0) { - if (argv[i + 1]) { - pkgpath_option = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-import-prefix") == 0) { - if (argv[i + 1]) { - import_prefix = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-use-shlib") == 0) { - Swig_mark_arg(i); - use_shlib = true; - } else if (strcmp(argv[i], "-soname") == 0) { - if (argv[i + 1]) { - soname = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-longsize") == 0) { - // Ignore for backward compatibility. - if (argv[i + 1]) { - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - ++i; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-intgosize") == 0) { - if (argv[i + 1]) { - intgo_type_size = atoi(argv[i + 1]); - if (intgo_type_size != 32 && intgo_type_size != 64) { - Printf(stderr, "-intgosize not 32 or 64\n"); - Swig_arg_error(); - } - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - ++i; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-help") == 0) { - Printf(stdout, "%s\n", usage); - } - } - } - - if (saw_nocgo_flag) { - Printf(stderr, "SWIG -go: -no-cgo option is no longer supported\n"); - Exit(EXIT_FAILURE); - } - - if (gccgo_flag && !pkgpath_option && !prefix_option) { - prefix_option = NewString("go"); - } - - // Add preprocessor symbol to parser. - Preprocessor_define("SWIGGO 1", 0); - - if (gccgo_flag) { - Preprocessor_define("SWIGGO_GCCGO 1", 0); - } - - if (intgo_type_size == 32) { - Preprocessor_define("SWIGGO_INTGO_SIZE 32", 0); - } else if (intgo_type_size == 64) { - Preprocessor_define("SWIGGO_INTGO_SIZE 64", 0); - } else { - Preprocessor_define("SWIGGO_INTGO_SIZE 0", 0); - } - - // Add typemap definitions. - SWIG_typemap_lang("go"); - SWIG_config_file("go.swg"); - - allow_overloading(); - } - - /* --------------------------------------------------------------------- - * top() - * - * For gc, we are going to create the following files: - * - * 1) A .c or .cxx file compiled with gcc. This file will contain - * function wrappers. Each wrapper will take a pointer to a - * struct holding the arguments, unpack them, and call the real - * function. - * - * 2) A .go file which defines the Go form of all types, and which - * defines Go function wrappers. Each wrapper will call the C - * function wrapper in the second file. - * - * 3) A .c file compiled with 6c/8c. This file will define - * Go-callable C function wrappers. Each wrapper will use - * cgocall to call the function wrappers in the first file. - * - * When generating code for gccgo, we don't need the third file, and - * the function wrappers in the first file have a different form. - * - * --------------------------------------------------------------------- */ - - virtual int top(Node *n) { - Node *optionsnode = Getattr(Getattr(n, "module"), "options"); - if (optionsnode) { - if (Getattr(optionsnode, "directors")) { - allow_directors(); - } - if (Getattr(optionsnode, "dirprot")) { - allow_dirprot(); - } - allow_allprotected(GetFlag(optionsnode, "allprotected")); - } - - module = Getattr(n, "name"); - if (!package) { - package = Copy(module); - } - if (!soname && use_shlib) { - soname = Copy(package); - Append(soname, ".so"); - } - - if (gccgo_flag) { - String *pref; - if (pkgpath_option) { - pref = pkgpath_option; - } else { - pref = prefix_option; - } - go_prefix = NewString(""); - for (char *p = Char(pref); *p != '\0'; p++) { - if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || *p == '.' || *p == '$') { - Putc(*p, go_prefix); - } else { - Putc('_', go_prefix); - } - } - if (!pkgpath_option) { - Append(go_prefix, "."); - Append(go_prefix, getModuleName(package)); - } - } - - // Get filenames. - - String *swig_filename = Getattr(n, "infile"); - String *c_filename = Getattr(n, "outfile"); - String *c_filename_h = Getattr(n, "outfile_h"); - - String *go_filename = NewString(""); - Printf(go_filename, "%s%s.go", SWIG_output_directory(), module); - - // Generate a unique ID based on a hash of the SWIG input. - swig_uint64 hash = {0, 0}; - FILE *swig_input = Swig_open(swig_filename); - if (swig_input == NULL) { - FileErrorDisplay(swig_filename); - Exit(EXIT_FAILURE); - } - String *swig_input_content = Swig_read_file(swig_input); - siphash(&hash, Char(swig_input_content), Len(swig_input_content)); - Delete(swig_input_content); - fclose(swig_input); - unique_id = NewString(""); - Printf(unique_id, "_%s_%08x%08x", getModuleName(package), hash.hi, hash.lo); - - // Open files. - - f_c_begin = NewFile(c_filename, "w", SWIG_output_files()); - if (!f_c_begin) { - FileErrorDisplay(c_filename); - Exit(EXIT_FAILURE); - } - - if (directorsEnabled()) { - if (!c_filename_h) { - Printf(stderr, "Unable to determine outfile_h\n"); - Exit(EXIT_FAILURE); - } - f_c_directors_h = NewFile(c_filename_h, "w", SWIG_output_files()); - if (!f_c_directors_h) { - FileErrorDisplay(c_filename_h); - Exit(EXIT_FAILURE); - } - } - - f_go_begin = NewFile(go_filename, "w", SWIG_output_files()); - if (!f_go_begin) { - FileErrorDisplay(go_filename); - Exit(EXIT_FAILURE); - } - - f_c_runtime = NewString(""); - f_c_header = NewString(""); - f_c_wrappers = NewString(""); - f_c_init = NewString(""); - f_c_directors = NewString(""); - f_go_imports = NewString(""); - f_go_runtime = NewString(""); - f_go_header = NewString(""); - f_go_wrappers = NewString(""); - f_go_directors = NewString(""); - f_cgo_comment = NewString(""); - f_cgo_comment_typedefs = NewString(""); - - Swig_register_filebyname("begin", f_c_begin); - Swig_register_filebyname("runtime", f_c_runtime); - Swig_register_filebyname("header", f_c_header); - Swig_register_filebyname("wrapper", f_c_wrappers); - Swig_register_filebyname("init", f_c_init); - Swig_register_filebyname("director", f_c_directors); - Swig_register_filebyname("director_h", f_c_directors_h); - Swig_register_filebyname("go_begin", f_go_begin); - Swig_register_filebyname("go_imports", f_go_imports); - Swig_register_filebyname("go_runtime", f_go_runtime); - Swig_register_filebyname("go_header", f_go_header); - Swig_register_filebyname("go_wrapper", f_go_wrappers); - Swig_register_filebyname("go_director", f_go_directors); - Swig_register_filebyname("cgo_comment", f_cgo_comment); - Swig_register_filebyname("cgo_comment_typedefs", f_cgo_comment_typedefs); - - Swig_banner(f_c_begin); - - Swig_obligatory_macros(f_c_runtime, "GO"); - - if (CPlusPlus) { - Printf(f_c_begin, "\n// source: %s\n\n", swig_filename); - } else { - Printf(f_c_begin, "\n/* source: %s */\n\n", swig_filename); - } - - Printf(f_c_runtime, "#define SWIGMODULE %s\n", module); - - if (gccgo_flag) { - Printf(f_c_runtime, "#define SWIGGO_PREFIX %s\n", go_prefix); - } - - if (directorsEnabled()) { - Printf(f_c_runtime, "#define SWIG_DIRECTORS\n"); - - Swig_banner(f_c_directors_h); - Printf(f_c_directors_h, "\n// source: %s\n\n", swig_filename); - - Printf(f_c_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module); - Printf(f_c_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module); - Printf(f_c_directors_h, "class Swig_memory;\n\n"); - - Printf(f_c_directors, "\n// C++ director class methods.\n"); - String *filename = Swig_file_filename(c_filename_h); - Printf(f_c_directors, "#include \"%s\"\n\n", filename); - Delete(filename); - } - - Swig_banner(f_go_begin); - Printf(f_go_begin, "\n// source: %s\n", swig_filename); - - Printv(f_cgo_comment_typedefs, "/*\n", NULL); - - // The cgo program defines the intgo type after our function - // definitions, but we want those definitions to be able to use - // intgo also. - Printv(f_cgo_comment_typedefs, "#define intgo swig_intgo\n", NULL); - Printv(f_cgo_comment_typedefs, "typedef void *swig_voidp;\n", NULL); - - // Output module initialization code. - - Printf(f_go_begin, "\npackage %s\n\n", getModuleName(package)); - - // All the C++ wrappers should be extern "C". - - Printv(f_c_wrappers, "#ifdef __cplusplus\n", "extern \"C\" {\n", "#endif\n\n", NULL); - - // Set up the hash table for types not defined by SWIG. - - undefined_enum_types = NewHash(); - undefined_types = NewHash(); - defined_types = NewHash(); - go_imports = NewHash(); - - // Emit code. - - Language::top(n); - - if (directorsEnabled()) { - // Insert director runtime into the f_runtime file (make it occur before %header section) - Swig_insert_file("director_common.swg", f_c_runtime); - Swig_insert_file("director.swg", f_c_runtime); - } - - Delete(go_imports); - - // Write out definitions for the types not defined by SWIG. - - if (Len(undefined_enum_types) > 0) - Printv(f_go_wrappers, "\n", NULL); - for (Iterator p = First(undefined_enum_types); p.key; p = Next(p)) { - String *name = p.item; - Printv(f_go_wrappers, "type ", name, " int\n", NULL); - } - - Printv(f_go_wrappers, "\n", NULL); - for (Iterator p = First(undefined_types); p.key; p = Next(p)) { - String *ty = goType(NULL, p.key); - if (!Getattr(defined_types, ty)) { - String *cp = goCPointerType(p.key, false); - if (!Getattr(defined_types, cp)) { - Printv(f_go_wrappers, "type ", cp, " uintptr\n", NULL); - Printv(f_go_wrappers, "type ", ty, " interface {\n", NULL); - Printv(f_go_wrappers, "\tSwigcptr() uintptr;\n", NULL); - Printv(f_go_wrappers, "}\n", NULL); - Printv(f_go_wrappers, "func (p ", cp, ") Swigcptr() uintptr {\n", NULL); - Printv(f_go_wrappers, "\treturn uintptr(p)\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - } - Delete(cp); - } - Delete(ty); - } - Delete(undefined_enum_types); - Delete(undefined_types); - Delete(defined_types); - - /* Write and cleanup */ - - Dump(f_c_header, f_c_runtime); - - if (directorsEnabled()) { - Printf(f_c_directors_h, "#endif\n"); - Delete(f_c_directors_h); - f_c_directors_h = NULL; - - Dump(f_c_directors, f_c_runtime); - Delete(f_c_directors); - f_c_directors = NULL; - } - - // End the extern "C". - Printv(f_c_wrappers, "#ifdef __cplusplus\n", "}\n", "#endif\n\n", NULL); - - // End the cgo comment. - Printv(f_cgo_comment, "#undef intgo\n", NULL); - Printv(f_cgo_comment, "*/\n", NULL); - Printv(f_cgo_comment, "import \"C\"\n", NULL); - Printv(f_cgo_comment, "\n", NULL); - - bool need_panic = false; - if (Strstr(f_c_runtime, "SWIG_contract_assert(") != 0 || Strstr(f_c_wrappers, "SWIG_contract_assert(") != 0) { - Printv(f_c_begin, "\n#define SWIG_contract_assert(expr, msg) if (!(expr)) { _swig_gopanic(msg); } else\n\n", NULL); - need_panic = true; - } - - if (!gccgo_flag && (need_panic || Strstr(f_c_runtime, "_swig_gopanic") != 0 || Strstr(f_c_wrappers, "_swig_gopanic") != 0)) { - Printv(f_go_header, "//export cgo_panic_", unique_id, "\n", NULL); - Printv(f_go_header, "func cgo_panic_", unique_id, "(p *byte) {\n", NULL); - Printv(f_go_header, "\ts := (*[1024]byte)(unsafe.Pointer(p))[:]\n", NULL); - Printv(f_go_header, "\tfor i, b := range s {\n", NULL); - Printv(f_go_header, "\t\tif b == 0 {\n", NULL); - Printv(f_go_header, "\t\t\tpanic(string(s[:i]))\n", NULL); - Printv(f_go_header, "\t\t}\n", NULL); - Printv(f_go_header, "\t}\n", NULL); - Printv(f_go_header, "\tpanic(string(s))\n", NULL); - Printv(f_go_header, "}\n\n", NULL); - - Printv(f_c_begin, "\nextern\n", NULL); - Printv(f_c_begin, "#ifdef __cplusplus\n", NULL); - Printv(f_c_begin, " \"C\"\n", NULL); - Printv(f_c_begin, "#endif\n", NULL); - Printv(f_c_begin, " void cgo_panic_", unique_id, "(const char*);\n", NULL); - Printv(f_c_begin, "static void _swig_gopanic(const char *p) {\n", NULL); - Printv(f_c_begin, " cgo_panic_", unique_id, "(p);\n", NULL); - Printv(f_c_begin, "}\n\n", NULL); - } - - Dump(f_c_runtime, f_c_begin); - Dump(f_c_wrappers, f_c_begin); - Dump(f_c_init, f_c_begin); - Dump(f_cgo_comment_typedefs, f_go_begin); - Dump(f_cgo_comment, f_go_begin); - Dump(f_go_imports, f_go_begin); - Dump(f_go_header, f_go_begin); - Dump(f_go_runtime, f_go_begin); - Dump(f_go_wrappers, f_go_begin); - if (directorsEnabled()) { - Dump(f_go_directors, f_go_begin); - } - Delete(f_c_runtime); - Delete(f_c_header); - Delete(f_c_wrappers); - Delete(f_c_init); - Delete(f_go_imports); - Delete(f_go_runtime); - Delete(f_go_header); - Delete(f_go_wrappers); - Delete(f_go_directors); - Delete(f_cgo_comment); - Delete(f_cgo_comment_typedefs); - Delete(f_c_begin); - Delete(f_go_begin); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * importDirective() - * - * Handle a SWIG import statement by generating a Go import - * statement. - * ------------------------------------------------------------ */ - - virtual int importDirective(Node *n) { - String *hold_import = imported_package; - String *modname = Getattr(n, "module"); - if (modname) { - if (!Getattr(go_imports, modname)) { - Setattr(go_imports, modname, modname); - Printv(f_go_imports, "import \"", NULL); - if (import_prefix) { - Printv(f_go_imports, import_prefix, "/", NULL); - } - Printv(f_go_imports, modname, "\"\n", NULL); - } - imported_package = modname; - saw_import = true; - } - int r = Language::importDirective(n); - imported_package = hold_import; - return r; - } - - /* ---------------------------------------------------------------------- - * Language::insertDirective() - * - * If the section is go_imports, store them for later. - * ---------------------------------------------------------------------- */ - virtual int insertDirective(Node *n) { - char *section = Char(Getattr(n, "section")); - if ((ImportMode && !Getattr(n, "generated")) || - !section || (strcmp(section, "go_imports") != 0)) { - return Language::insertDirective(n); - } - - char *code = Char(Getattr(n, "code")); - char *pch = strtok(code, ","); - while (pch != NULL) { - // Do not import same thing more than once. - if (!Getattr(go_imports, pch)) { - Setattr(go_imports, pch, pch); - Printv(f_go_imports, "import ", pch, "\n", NULL); - } - pch = strtok(NULL, ","); - } - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * functionWrapper() - * - * Implement a function. - * ---------------------------------------------------------------------- */ - - virtual int functionWrapper(Node *n) { - if (GetFlag(n, "feature:ignore")) { - return SWIG_OK; - } - - // We don't need explicit calls. - if (GetFlag(n, "explicitcall")) { - return SWIG_OK; - } - - // Don't emit constructors for abstract director classes. They - // will never succeed anyhow. - if (Swig_methodclass(n) && Swig_directorclass(n) - && Strcmp(Char(Getattr(n, "wrap:action")), director_prot_ctor_code) == 0) { - return SWIG_OK; - } - - String *name = Getattr(n, "sym:name"); - String *nodetype = Getattr(n, "nodeType"); - bool is_static = is_static_member_function || isStatic(n); - bool is_friend = isFriend(n); - bool is_ctor_dtor = false; - - SwigType *result = Getattr(n, "type"); - - // For some reason SWIG changs the "type" value during the call to - // functionWrapper. We need to remember the type for possible - // overload processing. - Setattr(n, "go:type", Copy(result)); - - String *go_name; - - String *r1 = NULL; - if (making_variable_wrappers) { - // Change the name of the variable setter and getter functions - // to be more Go like. - - bool is_set = Strcmp(Char(name) + Len(name) - 4, "_set") == 0; - assert(is_set || Strcmp(Char(name) + Len(name) - 4, "_get") == 0); - - // Start with Set or Get. - go_name = NewString(is_set ? "Set" : "Get"); - - // If this is a static variable, put in the class name, - // capitalized. - if (is_static && class_name) { - String *ccn = exportedName(class_name); - Append(go_name, ccn); - Delete(ccn); - } - - // Add the rest of the name, capitalized, dropping the _set or - // _get. - String *c1 = removeClassname(name); - String *c2 = exportedName(c1); - char *p = Char(c2); - int len = Len(p); - for (int i = 0; i < len - 4; ++i) { - Putc(p[i], go_name); - } - Delete(c2); - Delete(c1); - - if (!checkIgnoredParameters(n, go_name)) { - Delete(go_name); - return SWIG_NOWRAP; - } - } else if (Cmp(nodetype, "constructor") == 0) { - is_ctor_dtor = true; - - // Change the name of a constructor to be more Go like. Change - // new_ to New, and capitalize the class name. - assert(Strncmp(name, "new_", 4) == 0); - String *c1 = NewString(Char(name) + 4); - String *c2 = exportedName(c1); - go_name = NewString("New"); - Append(go_name, c2); - Delete(c2); - Delete(c1); - - if (Swig_methodclass(n) && Swig_directorclass(n)) { - // The core SWIG code skips the first parameter when - // generating the $nondirector_new string. Recreate the - // action in this case. But don't it if we are using the - // special code for an abstract class. - String *call = Swig_cppconstructor_call(getClassType(), - Getattr(n, "parms")); - SwigType *type = Copy(getClassType()); - SwigType_add_pointer(type); - String *cres = Swig_cresult(type, Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); - } - } else if (Cmp(nodetype, "destructor") == 0) { - // No need to emit protected destructors. - if (!is_public(n)) { - return SWIG_OK; - } - - is_ctor_dtor = true; - - // Change the name of a destructor to be more Go like. Change - // delete_ to Delete and capitalize the class name. - assert(Strncmp(name, "delete_", 7) == 0); - String *c1 = NewString(Char(name) + 7); - String *c2 = exportedName(c1); - go_name = NewString("Delete"); - Append(go_name, c2); - Delete(c2); - Delete(c1); - - result = NewString("void"); - r1 = result; - } else { - if (!checkFunctionVisibility(n, NULL)) { - return SWIG_OK; - } - - go_name = buildGoName(name, is_static, is_friend); - - if (!checkIgnoredParameters(n, go_name)) { - Delete(go_name); - return SWIG_NOWRAP; - } - } - - String *overname = NULL; - if (Getattr(n, "sym:overloaded")) { - overname = Getattr(n, "sym:overname"); - } else { - String *scope; - if (!class_name || is_static || is_ctor_dtor) { - scope = NULL; - } else { - scope = NewString("swiggoscope."); - Append(scope, class_name); - } - if (!checkNameConflict(go_name, n, scope)) { - Delete(go_name); - return SWIG_NOWRAP; - } - } - - String *wname = Swig_name_wrapper(name); - if (overname) { - Append(wname, overname); - } - Append(wname, unique_id); - Setattr(n, "wrap:name", wname); - - ParmList *parms = Getattr(n, "parms"); - Setattr(n, "wrap:parms", parms); - - int r = makeWrappers(n, go_name, overname, wname, NULL, parms, result, is_static); - if (r != SWIG_OK) { - return r; - } - - if (Getattr(n, "sym:overloaded") && !Getattr(n, "sym:nextSibling")) { - String *scope ; - if (!class_name || is_static || is_ctor_dtor) { - scope = NULL; - } else { - scope = NewString("swiggoscope."); - Append(scope, class_name); - } - if (!checkNameConflict(go_name, n, scope)) { - Delete(go_name); - return SWIG_NOWRAP; - } - - String *receiver = class_receiver; - if (is_static || is_ctor_dtor) { - receiver = NULL; - } - r = makeDispatchFunction(n, go_name, receiver, is_static, NULL, false); - if (r != SWIG_OK) { - return r; - } - } - - Delete(wname); - Delete(go_name); - Delete(r1); - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * staticmemberfunctionHandler() - * - * For some reason the language code removes the "storage" attribute - * for a static function before calling functionWrapper, which means - * that we have no way of knowing whether a function is static or - * not. That makes no sense in the Go context. Here we note that a - * function is static. - * ---------------------------------------------------------------------- */ - - int staticmemberfunctionHandler(Node *n) { - assert(!is_static_member_function); - is_static_member_function = true; - int r = Language::staticmemberfunctionHandler(n); - is_static_member_function = false; - return r; - } - - /* ---------------------------------------------------------------------- - * makeWrappers() - * - * Write out the various function wrappers. - * n: The function we are emitting. - * go_name: The name of the function in Go. - * overname: The overload string for overloaded function. - * wname: The SWIG wrapped name--the name of the C function. - * base: A list of the names of base classes, in the case where this - * is a virtual method not defined in the current class. - * parms: The parameters. - * result: The result type. - * is_static: Whether this is a static method or member. - * ---------------------------------------------------------------------- */ - - int makeWrappers(Node *n, String *go_name, String *overname, String *wname, List *base, ParmList *parms, SwigType *result, bool is_static) { - - assert(result); - - int ret = SWIG_OK; - - int r = makeCgoWrappers(n, go_name, overname, wname, base, parms, result, is_static); - if (r != SWIG_OK) { - ret = r; - } - - if (class_methods) { - Setattr(class_methods, Getattr(n, "name"), NewString("")); - } - - return ret; - } - - /* ---------------------------------------------------------------------- - * struct cgoWrapperInfo - * - * Information needed by the CGO wrapper functions. - * ---------------------------------------------------------------------- */ - - struct cgoWrapperInfo { - // The function we are generating code for. - Node *n; - // The name of the Go function. - String *go_name; - // The overload string for an overloaded function. - String *overname; - // The name of the C wrapper function. - String *wname; - // The base classes. - List *base; - // The parameters. - ParmList *parms; - // The result type. - SwigType *result; - // Whether this is a static function, not a class method. - bool is_static; - // The Go receiver type. - String *receiver; - // Whether this is a class constructor. - bool is_constructor; - // Whether this is a class destructor. - bool is_destructor; - }; - - /* ---------------------------------------------------------------------- - * makeCgoWrappers() - * - * Write out the wrappers for a function when producing cgo input - * files. - * ---------------------------------------------------------------------- */ - - int makeCgoWrappers(Node *n, String *go_name, String *overname, String *wname, List *base, ParmList *parms, SwigType *result, bool is_static) { - Swig_save("makeCgoWrappers", n, "emit:cgotype", "emit:cgotypestruct", NULL); - - cgoWrapperInfo info; - - info.n = n; - info.go_name = go_name; - info.overname = overname; - info.wname = wname; - info.base = base; - info.parms = parms; - info.result = result; - info.is_static = is_static; - - info.receiver = class_receiver; - if (is_static) { - info.receiver = NULL; - } - - String *nodetype = Getattr(n, "nodeType"); - info.is_constructor = Cmp(nodetype, "constructor") == 0; - info.is_destructor = Cmp(nodetype, "destructor") == 0; - if (info.is_constructor || info.is_destructor) { - assert(class_receiver); - assert(!base); - info.receiver = NULL; - } - - int ret = SWIG_OK; - - int r = cgoGoWrapper(&info); - if (r != SWIG_OK) { - ret = r; - } - - r = cgoCommentWrapper(&info); - if (r != SWIG_OK) { - ret = r; - } - - r = cgoGccWrapper(&info); - if (r != SWIG_OK) { - ret = r; - } - - Swig_restore(n); - - return ret; - } - - /* ---------------------------------------------------------------------- - * cgoGoWrapper() - * - * Write out Go code to call a cgo function. This code will go into - * the generated Go output file. - * ---------------------------------------------------------------------- */ - int cgoGoWrapper(const cgoWrapperInfo *info) { - - Wrapper *dummy = initGoTypemaps(info->parms); - - bool add_to_interface = interfaces && !info->is_constructor && !info->is_destructor && !info->is_static && !info->overname && checkFunctionVisibility(info->n, NULL); - - Printv(f_go_wrappers, "func ", NULL); - - Parm *p = info->parms; - int pi = 0; - - // Add the receiver first if this is a method. - if (info->receiver) { - Printv(f_go_wrappers, "(", NULL); - if (info->base && info->receiver) { - Printv(f_go_wrappers, "_swig_base", NULL); - } else { - Printv(f_go_wrappers, Getattr(p, "lname"), NULL); - p = nextParm(p); - ++pi; - } - Printv(f_go_wrappers, " ", info->receiver, ") ", NULL); - } - - Printv(f_go_wrappers, info->go_name, NULL); - if (info->overname) { - Printv(f_go_wrappers, info->overname, NULL); - } - Printv(f_go_wrappers, "(", NULL); - - // If we are doing methods, add this method to the interface. - if (add_to_interface) { - Printv(interfaces, "\t", info->go_name, "(", NULL); - } - - // Write out the parameters to both the function definition and - // the interface. - - String *parm_print = NewString(""); - - int parm_count = emit_num_arguments(info->parms); - int required_count = emit_num_required(info->parms); - int args = 0; - - for (; pi < parm_count; ++pi) { - p = getParm(p); - if (pi == 0 && info->is_destructor) { - String *cl = exportedName(class_name); - Printv(parm_print, Getattr(p, "lname"), " ", cl, NULL); - Delete(cl); - ++args; - } else { - if (args > 0) { - Printv(parm_print, ", ", NULL); - } - ++args; - if (pi >= required_count) { - Printv(parm_print, "_swig_args ...interface{}", NULL); - break; - } - Printv(parm_print, Getattr(p, "lname"), " ", NULL); - String *tm = goType(p, Getattr(p, "type")); - Printv(parm_print, tm, NULL); - Delete(tm); - } - p = nextParm(p); - } - - Printv(parm_print, ")", NULL); - - // Write out the result type. - if (info->is_constructor) { - String *cl = exportedName(class_name); - Printv(parm_print, " (_swig_ret ", cl, ")", NULL); - Delete(cl); - } else { - if (SwigType_type(info->result) != T_VOID) { - String *tm = goType(info->n, info->result); - Printv(parm_print, " (_swig_ret ", tm, ")", NULL); - Delete(tm); - } - } - - Printv(f_go_wrappers, parm_print, NULL); - if (add_to_interface) { - Printv(interfaces, parm_print, "\n", NULL); - } - - // Write out the function body. - - Printv(f_go_wrappers, " {\n", NULL); - - if (parm_count > required_count) { - Parm *p = info->parms; - int i; - for (i = 0; i < required_count; ++i) { - p = getParm(p); - p = nextParm(p); - } - for (; i < parm_count; ++i) { - p = getParm(p); - String *tm = goType(p, Getattr(p, "type")); - Printv(f_go_wrappers, "\tvar ", Getattr(p, "lname"), " ", tm, "\n", NULL); - Printf(f_go_wrappers, "\tif len(_swig_args) > %d {\n", i - required_count); - Printf(f_go_wrappers, "\t\t%s = _swig_args[%d].(%s)\n", Getattr(p, "lname"), i - required_count, tm); - Printv(f_go_wrappers, "\t}\n", NULL); - Delete(tm); - p = nextParm(p); - } - } - - String *call = NewString("\t"); - - String *ret_type = NULL; - bool memcpy_ret = false; - String *wt = NULL; - if (SwigType_type(info->result) != T_VOID) { - if (info->is_constructor) { - ret_type = exportedName(class_name); - } else { - ret_type = goImType(info->n, info->result); - } - Printv(f_go_wrappers, "\tvar swig_r ", ret_type, "\n", NULL); - - bool c_struct_type; - Delete(cgoTypeForGoValue(info->n, info->result, &c_struct_type)); - if (c_struct_type) { - memcpy_ret = true; - } - - if (memcpy_ret) { - Printv(call, "swig_r_p := ", NULL); - } else { - Printv(call, "swig_r = (", ret_type, ")(", NULL); - } - - if (info->is_constructor || goTypeIsInterface(info->n, info->result)) { - if (info->is_constructor) { - wt = Copy(class_receiver); - } else { - wt = goWrapperType(info->n, info->result, true); - } - Printv(call, wt, "(", NULL); - } - } - - Printv(call, "C.", info->wname, "(", NULL); - - args = 0; - - if (parm_count > required_count) { - Printv(call, "C.swig_intgo(len(_swig_args))", NULL); - ++args; - } - - if (info->base && info->receiver) { - if (args > 0) { - Printv(call, ", ", NULL); - } - ++args; - Printv(call, "C.uintptr_t(_swig_base)", NULL); - } - - p = info->parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - if (args > 0) { - Printv(call, ", ", NULL); - } - ++args; - - SwigType *pt = Getattr(p, "type"); - String *ln = Getattr(p, "lname"); - - String *ivar = NewStringf("_swig_i_%d", i); - - String *goin = goGetattr(p, "tmap:goin"); - if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", NULL); - bool need_close = false; - if ((i == 0 && info->is_destructor) || ((i > 0 || !info->receiver || info->base || info->is_constructor) && goTypeIsInterface(p, pt))) { - Printv(f_go_wrappers, "getSwigcptr(", NULL); - need_close = true; - } - Printv(f_go_wrappers, ln, NULL); - if (need_close) { - Printv(f_go_wrappers, ")", NULL); - } - Printv(f_go_wrappers, "\n", NULL); - Setattr(p, "emit:goinput", ln); - } else { - String *itm = goImType(p, pt); - Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL); - goin = Copy(goin); - Replaceall(goin, "$input", ln); - Replaceall(goin, "$result", ivar); - Printv(f_go_wrappers, goin, "\n", NULL); - Delete(goin); - Setattr(p, "emit:goinput", ivar); - } - - bool c_struct_type; - String *ct = cgoTypeForGoValue(p, pt, &c_struct_type); - if (c_struct_type) { - Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL); - } else { - Printv(call, "C.", ct, "(", ivar, ")", NULL); - } - Delete(ct); - - p = nextParm(p); - } - - Printv(f_go_wrappers, call, ")", NULL); - Delete(call); - - if (wt) { - // Close the type conversion to the wrapper type. - Printv(f_go_wrappers, ")", NULL); - } - if (SwigType_type(info->result) != T_VOID && !memcpy_ret) { - // Close the type conversion of the return value. - Printv(f_go_wrappers, ")", NULL); - } - - Printv(f_go_wrappers, "\n", NULL); - - if (memcpy_ret) { - Printv(f_go_wrappers, "\tswig_r = *(*", ret_type, ")(unsafe.Pointer(&swig_r_p))\n", NULL); - } - if (ret_type) { - Delete(ret_type); - } - - goargout(info->parms); - - if (SwigType_type(info->result) != T_VOID) { - - Swig_save("cgoGoWrapper", info->n, "type", "tmap:goout", NULL); - Setattr(info->n, "type", info->result); - - String *goout = goTypemapLookup("goout", info->n, "swig_r"); - if (goout == NULL) { - Printv(f_go_wrappers, "\treturn swig_r\n", NULL); - } else { - String *tm = goType(info->n, info->result); - Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL); - goout = Copy(goout); - Replaceall(goout, "$input", "swig_r"); - Replaceall(goout, "$result", "swig_r_1"); - Printv(f_go_wrappers, goout, "\n", NULL); - Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL); - } - - Swig_restore(info->n); - } - - Printv(f_go_wrappers, "}\n\n", NULL); - - DelWrapper(dummy); - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * cgoCommentWrapper() - * - * Write out a cgo function to call a C/C++ function. This code - * will go into the cgo comment in the generated Go output file. - * ---------------------------------------------------------------------- */ - int cgoCommentWrapper(const cgoWrapperInfo *info) { - String *ret_type; - if (SwigType_type(info->result) == T_VOID) { - ret_type = NewString("void"); - } else { - bool c_struct_type; - ret_type = cgoTypeForGoValue(info->n, info->result, &c_struct_type); - } - - Printv(f_cgo_comment, "extern ", ret_type, " ", info->wname, "(", NULL); - - Delete(ret_type); - - int parm_count = emit_num_arguments(info->parms); - int required_count = emit_num_required(info->parms); - int args = 0; - - if (parm_count > required_count) { - Printv(f_cgo_comment, "intgo _swig_args", NULL); - ++args; - } - - if (info->base && info->receiver) { - if (args > 0) { - Printv(f_cgo_comment, ", ", NULL); - } - ++args; - Printv(f_cgo_comment, "uintptr_t _swig_base", NULL); - } - - Parm *p = info->parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - if (args > 0) { - Printv(f_cgo_comment, ", ", NULL); - } - ++args; - - SwigType *pt = Getattr(p, "type"); - String *ln = Getattr(p, "lname"); - - bool c_struct_type; - String *ct = cgoTypeForGoValue(p, pt, &c_struct_type); - Printv(f_cgo_comment, ct, " ", ln, NULL); - Delete(ct); - - p = nextParm(p); - } - - if (args == 0) { - Printv(f_cgo_comment, "void", NULL); - } - - Printv(f_cgo_comment, ");\n", NULL); - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * cgoGccWrapper() - * - * Write out code to the C/C++ wrapper file. This code will be - * called by the code generated by cgoCommentWrapper. - * ---------------------------------------------------------------------- */ - int cgoGccWrapper(const cgoWrapperInfo *info) { - Wrapper *f = NewWrapper(); - - Swig_save("cgoGccWrapper", info->n, "parms", NULL); - - ParmList *parms = info->parms; - - Parm *base_parm = NULL; - if (info->base && !isStatic(info->n)) { - SwigType *base_type = Copy(getClassType()); - SwigType_add_pointer(base_type); - base_parm = NewParm(base_type, NewString("arg1"), info->n); - set_nextSibling(base_parm, parms); - parms = base_parm; - } - - emit_parameter_variables(parms, f); - emit_attach_parmmaps(parms, f); - int parm_count = emit_num_arguments(parms); - int required_count = emit_num_required(parms); - - emit_return_variable(info->n, info->result, f); - - // Start the function definition. - - String *fnname = NewString(""); - Printv(fnname, info->wname, "(", NULL); - - int args = 0; - - if (parm_count > required_count) { - Printv(fnname, "intgo _swig_optargc", NULL); - ++args; - } - - Parm *p = parms; - for (int i = 0; i < parm_count; ++i) { - if (args > 0) { - Printv(fnname, ", ", NULL); - } - ++args; - - p = getParm(p); - - SwigType *pt = Copy(Getattr(p, "type")); - if (SwigType_isarray(pt) && Getattr(p, "tmap:gotype") == NULL) { - SwigType_del_array(pt); - SwigType_add_pointer(pt); - } - String *pn = NewStringf("_swig_go_%d", i); - String *ct = gcCTypeForGoValue(p, pt, pn); - Printv(fnname, ct, NULL); - Delete(ct); - Delete(pn); - Delete(pt); - - p = nextParm(p); - } - - Printv(fnname, ")", NULL); - - if (SwigType_type(info->result) == T_VOID) { - Printv(f->def, "void ", fnname, NULL); - } else { - String *ct = gcCTypeForGoValue(info->n, info->result, fnname); - Printv(f->def, ct, NULL); - Delete(ct); - - String *ln = NewString("_swig_go_result"); - ct = gcCTypeForGoValue(info->n, info->result, ln); - Wrapper_add_local(f, "_swig_go_result", ct); - Delete(ct); - Delete(ln); - } - - Delete(fnname); - - Printv(f->def, " {\n", NULL); - - // Apply the in typemaps. - - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - String *tm = Getattr(p, "tmap:in"); - if (!tm) { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "unable to use type %s as a function argument\n", SwigType_str(Getattr(p, "type"), 0)); - } else { - tm = Copy(tm); - String *pn = NewStringf("_swig_go_%d", i); - Replaceall(tm, "$input", pn); - if (i < required_count) { - Printv(f->code, "\t", tm, "\n", NULL); - } else { - Printf(f->code, "\tif (_swig_optargc > %d) {\n", i - required_count); - Printv(f->code, "\t\t", tm, "\n", NULL); - Printv(f->code, "\t}\n", NULL); - } - Delete(tm); - Setattr(p, "emit:input", pn); - } - p = nextParm(p); - } - - Printv(f->code, "\n", NULL); - - // Do the real work of the function. - - checkConstraints(parms, f); - - emitGoAction(info->n, info->base, parms, info->result, f); - - argout(parms, f); - - cleanupFunction(info->n, f, parms); - - if (SwigType_type(info->result) != T_VOID) { - Printv(f->code, "\treturn _swig_go_result;\n", NULL); - } - - Printv(f->code, "}\n", NULL); - - Wrapper_print(f, f_c_wrappers); - - Swig_restore(info->n); - - DelWrapper(f); - if (base_parm) { - Delete(base_parm); - } - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * initGoTypemaps() - * - * Initialize the typenames for a Go wrapper, returning a dummy - * Wrapper*. Also set consistent names for the parameters. - * ---------------------------------------------------------------------- */ - - Wrapper* initGoTypemaps(ParmList *parms) { - Wrapper *dummy = NewWrapper(); - emit_attach_parmmaps(parms, dummy); - - Parm *p = parms; - int parm_count = emit_num_arguments(parms); - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - Swig_cparm_name(p, i); - p = nextParm(p); - } - - Swig_typemap_attach_parms("default", parms, dummy); - Swig_typemap_attach_parms("gotype", parms, dummy); - Swig_typemap_attach_parms("goin", parms, dummy); - Swig_typemap_attach_parms("goargout", parms, dummy); - Swig_typemap_attach_parms("imtype", parms, dummy); - - return dummy; - } - - /* ----------------------------------------------------------------------- - * checkConstraints() - * - * Check parameter constraints if any. This is used for the C/C++ - * function. This assumes that each parameter has an "emit:input" - * property with the name to use to refer to that parameter. - * ----------------------------------------------------------------------- */ - - void checkConstraints(ParmList *parms, Wrapper *f) { - Parm *p = parms; - while (p) { - String *tm = Getattr(p, "tmap:check"); - if (!tm) { - p = nextSibling(p); - } else { - tm = Copy(tm); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(f->code, tm, "\n\n", NULL); - Delete(tm); - p = Getattr(p, "tmap:check:next"); - } - } - } - - /* ----------------------------------------------------------------------- - * emitGoAction() - * - * Emit the action of the function. This is used for the C/C++ function. - * ----------------------------------------------------------------------- */ - - void emitGoAction(Node *n, List *base, ParmList *parms, SwigType *result, Wrapper *f) { - String *actioncode; - if (!base || isStatic(n)) { - Swig_director_emit_dynamic_cast(n, f); - actioncode = emit_action(n); - } else { - // Call the base class method. - actioncode = NewString(""); - - String *current = NewString(""); - Printv(current, Getattr(parms, "lname"), NULL); - - int vc = 0; - for (Iterator bi = First(base); bi.item; bi = Next(bi)) { - Printf(actioncode, " %s *swig_b%d = (%s *)%s;\n", bi.item, vc, bi.item, current); - Delete(current); - current = NewString(""); - Printf(current, "swig_b%d", vc); - ++vc; - } - - String *code = Copy(Getattr(n, "wrap:action")); - Replace(code, Getattr(parms, "lname"), current, DOH_REPLACE_ANY | DOH_REPLACE_ID); - Delete(current); - Printv(actioncode, code, "\n", NULL); - } - - Swig_save("emitGoAction", n, "type", "tmap:out", NULL); - - Setattr(n, "type", result); - - String *tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode); - if (!tm) { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s\n", SwigType_str(result, 0)); - } else { - Replaceall(tm, "$result", "_swig_go_result"); - if (GetFlag(n, "feature:new")) { - Replaceall(tm, "$owner", "1"); - } else { - Replaceall(tm, "$owner", "0"); - } - Printv(f->code, tm, "\n", NULL); - Delete(tm); - } - - Swig_restore(n); - } - - /* ----------------------------------------------------------------------- - * argout() - * - * Handle argument output code if any. This is used for the C/C++ - * function. This assumes that each parameter has an "emit:input" - * property with the name to use to refer to that parameter. - * ----------------------------------------------------------------------- */ - - void argout(ParmList *parms, Wrapper *f) { - Parm *p = parms; - while (p) { - String *tm = Getattr(p, "tmap:argout"); - if (!tm) { - p = nextSibling(p); - } else { - tm = Copy(tm); - Replaceall(tm, "$result", Swig_cresult_name()); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(f->code, tm, "\n", NULL); - Delete(tm); - p = Getattr(p, "tmap:argout:next"); - } - } - } - - /* ----------------------------------------------------------------------- - * goargout() - * - * Handle Go argument output code if any. This is used for the Go - * function. This assumes that each parameter has an "emit:goinput" - * property with the name to use to refer to that parameter. - * ----------------------------------------------------------------------- */ - - void goargout(ParmList *parms) { - Parm *p = parms; - while (p) { - String *tm = Getattr(p, "tmap:goargout"); - if (!tm) { - p = nextSibling(p); - } else { - tm = Copy(tm); - Replaceall(tm, "$result", "swig_r"); - Replaceall(tm, "$input", Getattr(p, "emit:goinput")); - Printv(f_go_wrappers, tm, "\n", NULL); - Delete(tm); - p = Getattr(p, "tmap:goargout:next"); - } - } - - // If we need to memcpy a parameter to pass it to the C code, the - // compiler may think that the parameter is not live during the - // function call. If the garbage collector runs while the C/C++ - // function is running, the parameter may be freed. Force the - // compiler to see the parameter as live across the C/C++ function. - int parm_count = emit_num_arguments(parms); - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - bool c_struct_type; - Delete(cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type)); - if (c_struct_type) { - Printv(f_go_wrappers, "\tif Swig_escape_always_false {\n", NULL); - Printv(f_go_wrappers, "\t\tSwig_escape_val = ", Getattr(p, "emit:goinput"), "\n", NULL); - Printv(f_go_wrappers, "\t}\n", NULL); - } - p = nextParm(p); - } - } - - /* ----------------------------------------------------------------------- - * freearg() - * - * Handle argument cleanup code if any. This is used for the C/C++ - * function. This assumes that each parameter has an "emit:input" - * property with the name to use to refer to that parameter. - * ----------------------------------------------------------------------- */ - - String *freearg(ParmList *parms) { - String *ret = NewString(""); - Parm *p = parms; - while (p) { - String *tm = Getattr(p, "tmap:freearg"); - if (!tm) { - p = nextSibling(p); - } else { - tm = Copy(tm); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(ret, tm, "\n", NULL); - Delete(tm); - p = Getattr(p, "tmap:freearg:next"); - } - } - return ret; - } - - /* ----------------------------------------------------------------------- - * cleanupFunction() - * - * Final function cleanup code. - * ----------------------------------------------------------------------- */ - - void cleanupFunction(Node *n, Wrapper *f, ParmList *parms) { - String *cleanup = freearg(parms); - Printv(f->code, cleanup, NULL); - - if (GetFlag(n, "feature:new")) { - String *tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0); - if (tm) { - Printv(f->code, tm, "\n", NULL); - Delete(tm); - } - } - - Replaceall(f->code, "$cleanup", cleanup); - Delete(cleanup); - - /* See if there is any return cleanup code */ - String *tm; - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - Delete(tm); - } - - Replaceall(f->code, "$symname", Getattr(n, "sym:name")); - } - - /* ----------------------------------------------------------------------- - * variableHandler() - * - * This exists just to set the making_variable_wrappers flag. - * ----------------------------------------------------------------------- */ - - virtual int variableHandler(Node *n) { - assert(!making_variable_wrappers); - making_variable_wrappers = true; - int r = Language::variableHandler(n); - making_variable_wrappers = false; - return r; - } - - /* ----------------------------------------------------------------------- - * constantWrapper() - * - * Product a const declaration. - * ------------------------------------------------------------------------ */ - - virtual int constantWrapper(Node *n) { - SwigType *type = Getattr(n, "type"); - - if (!SwigType_issimple(type) && SwigType_type(type) != T_STRING) { - return goComplexConstant(n, type); - } - - if (Swig_storage_isstatic(n)) { - return goComplexConstant(n, type); - } - - String *go_name = buildGoName(Getattr(n, "sym:name"), false, false); - - String *tm = goType(n, type); - String *value = Getattr(n, "value"); - - String *copy = NULL; - if (SwigType_type(type) == T_BOOL) { - if (Cmp(value, "true") != 0 && Cmp(value, "false") != 0) { - return goComplexConstant(n, type); - } - } else if (SwigType_type(type) == T_STRING || SwigType_type(type) == T_CHAR) { - // Backslash sequences are somewhat different in Go and C/C++. - if (Strchr(value, '\\') != 0) { - return goComplexConstant(n, type); - } - } else { - // Accept a 0x prefix, and strip combinations of u and l - // suffixes. Otherwise accept digits, decimal point, and - // exponentiation. Treat anything else as too complicated to - // handle as a Go constant. - char *p = Char(value); - int len = (int)strlen(p); - bool need_copy = false; - while (len > 0) { - char c = p[len - 1]; - if (c != 'l' && c != 'L' && c != 'u' && c != 'U') { - break; - } - --len; - need_copy = true; - } - bool is_hex = false; - int i = 0; - if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { - i = 2; - is_hex = true; - } - for (; i < len; ++i) { - switch (p[i]) { - case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - break; - case 'a': case 'b': case 'c': case 'd': case 'f': case 'A': case 'B': case 'C': case 'D': case 'F': - if (!is_hex) { - return goComplexConstant(n, type); - } - break; - case '.': case 'e': case 'E': case '+': case '-': - break; - default: - return goComplexConstant(n, type); - } - } - if (need_copy) { - copy = Copy(value); - Replaceall(copy, p + len, ""); - value = copy; - } - } - - if (!checkNameConflict(go_name, n, NULL)) { - Delete(tm); - Delete(go_name); - Delete(copy); - return SWIG_NOWRAP; - } - - Printv(f_go_wrappers, "const ", go_name, " ", tm, " = ", NULL); - if (SwigType_type(type) == T_STRING) { - Printv(f_go_wrappers, "\"", value, "\"", NULL); - } else if (SwigType_type(type) == T_CHAR) { - Printv(f_go_wrappers, "'", value, "'", NULL); - } else { - Printv(f_go_wrappers, value, NULL); - } - - Printv(f_go_wrappers, "\n", NULL); - - Delete(tm); - Delete(go_name); - Delete(copy); - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * enumDeclaration() - * - * A C++ enum type turns into a Named go int type. - * ---------------------------------------------------------------------- */ - - virtual int enumDeclaration(Node *n) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - String *name = goEnumName(n); - if (Strcmp(name, "int") != 0) { - if (!ImportMode || !imported_package) { - if (!checkNameConflict(name, n, NULL)) { - Delete(name); - return SWIG_NOWRAP; - } - Printv(f_go_wrappers, "type ", name, " int\n", NULL); - } else { - String *nw = NewString(""); - Printv(nw, getModuleName(imported_package), ".", name, NULL); - Setattr(n, "go:enumname", nw); - } - } - Delete(name); - - return Language::enumDeclaration(n); - } - - /* ----------------------------------------------------------------------- - * enumvalueDeclaration() - * - * Declare a single value of an enum type. We fetch the value by - * calling a C/C++ function. - * ------------------------------------------------------------------------ */ - - virtual int enumvalueDeclaration(Node *n) { - if (!is_public(n)) { - return SWIG_OK; - } - - Swig_require("enumvalueDeclaration", n, "*sym:name", NIL); - Node *parent = parentNode(n); - - if (Getattr(parent, "unnamed")) { - Setattr(n, "type", NewString("int")); - } else { - Setattr(n, "type", Getattr(parent, "enumtype")); - } - - if (GetFlag(parent, "scopedenum")) { - String *symname = Getattr(n, "sym:name"); - symname = Swig_name_member(0, Getattr(parent, "sym:name"), symname); - Setattr(n, "sym:name", symname); - Delete(symname); - } - - int ret = goComplexConstant(n, Getattr(n, "type")); - Swig_restore(n); - return ret; - } - - /* ----------------------------------------------------------------------- - * goComplexConstant() - * - * Handle a const declaration for something which is not a Go constant. - * ------------------------------------------------------------------------ */ - - int goComplexConstant(Node *n, SwigType *type) { - String *symname = Getattr(n, "sym:name"); - if (!symname) { - symname = Getattr(n, "name"); - } - - String *varname = buildGoName(symname, true, false); - - if (!checkNameConflict(varname, n, NULL)) { - Delete(varname); - return SWIG_NOWRAP; - } - - String *rawval = Getattr(n, "rawval"); - if (rawval && Len(rawval)) { - // Based on Swig_VargetToFunction - String *nname = NewStringf("(%s)", rawval); - String *call; - if (SwigType_isclass(type)) { - call = NewStringf("%s", nname); - } else { - call = SwigType_lcaststr(type, nname); - } - String *cres = Swig_cresult(type, Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); - Delete(nname); - Delete(call); - Delete(cres); - } else { - String *get = NewString(""); - Printv(get, Swig_cresult_name(), " = ", NULL); - - char quote; - if (Getattr(n, "wrappedasconstant")) { - quote = '\0'; - } else if (SwigType_type(type) == T_CHAR) { - quote = '\''; - } else if (SwigType_type(type) == T_STRING) { - Printv(get, "(char *)", NULL); - quote = '"'; - } else { - quote = '\0'; - } - - if (quote != '\0') { - Printf(get, "%c", quote); - } - - Printv(get, Getattr(n, "value"), NULL); - - if (quote != '\0') { - Printf(get, "%c", quote); - } - - Printv(get, ";\n", NULL); - - Setattr(n, "wrap:action", get); - Delete(get); - } - - String *sname = Copy(symname); - if (class_name) { - Append(sname, "_"); - Append(sname, class_name); - } - - String *go_name = NewString("_swig_get"); - if (class_name) { - Append(go_name, class_name); - Append(go_name, "_"); - } - Append(go_name, sname); - - String *wname = Swig_name_wrapper(sname); - Append(wname, unique_id); - Setattr(n, "wrap:name", wname); - - int r = makeWrappers(n, go_name, NULL, wname, NULL, NULL, type, true); - - if (r != SWIG_OK) { - return r; - } - - String *t = goType(n, type); - Printv(f_go_wrappers, "var ", varname, " ", t, " = ", go_name, "()\n", NULL); - - Delete(varname); - Delete(t); - Delete(go_name); - Delete(sname); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * classHandler() - * - * For a C++ class, in Go we generate both a struct and an - * interface. The interface will declare all the class public - * methods. We will define all the methods on the struct, so that - * the struct meets the interface. We then expect users of the - * class to use the interface. - * ------------------------------------------------------------ */ - - virtual int classHandler(Node *n) { - class_node = n; - - List *baselist = Getattr(n, "bases"); - bool has_base_classes = baselist && Len(baselist) > 0; - - String *name = Getattr(n, "sym:name"); - - String *go_name = exportedName(name); - - if (!checkNameConflict(go_name, n, NULL)) { - Delete(go_name); - SetFlag(n, "go:conflict"); - return SWIG_NOWRAP; - } - - String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true); - - class_name = name; - class_receiver = go_type_name; - class_methods = NewHash(); - - int isdir = GetFlag(n, "feature:director"); - int isnodir = GetFlag(n, "feature:nodirector"); - bool is_director = isdir && !isnodir; - - Printv(f_go_wrappers, "type ", go_type_name, " uintptr\n\n", NULL); - - // A method to return the pointer to the C++ class. This is used - // by generated code to convert between the interface and the C++ - // value. - Printv(f_go_wrappers, "func (p ", go_type_name, ") Swigcptr() uintptr {\n", NULL); - Printv(f_go_wrappers, "\treturn (uintptr)(p)\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - // A method used as a marker for the class, to avoid invalid - // interface conversions when using multiple inheritance. - Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigIs", go_name, "() {\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - if (is_director) { - // Return the interface passed to the NewDirector function. - Printv(f_go_wrappers, "func (p ", go_type_name, ") DirectorInterface() interface{} {\n", NULL); - Printv(f_go_wrappers, "\treturn nil\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - } - - // We have seen a definition for this type. - Setattr(defined_types, go_name, go_name); - Setattr(defined_types, go_type_name, go_type_name); - - interfaces = NewString(""); - - int r = Language::classHandler(n); - if (r != SWIG_OK) { - return r; - } - - if (has_base_classes) { - // For each method defined in a base class but not defined in - // this class, we need to define the method in this class. We - // can't use anonymous field inheritance because it works - // differently in Go and in C++. - - Hash *local = NewHash(); - for (Node *ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) { - - if (!is_public(ni)) { - continue; - } - - String *type = Getattr(ni, "nodeType"); - if (Cmp(type, "constructor") == 0 || Cmp(type, "destructor") == 0) { - continue; - } - - String *cname = Getattr(ni, "sym:name"); - if (!cname) { - cname = Getattr(ni, "name"); - } - if (cname) { - Setattr(local, cname, NewString("")); - } - } - - for (Iterator b = First(baselist); b.item; b = Next(b)) { - List *bases = NewList(); - Append(bases, Getattr(b.item, "classtype")); - int r = addBase(n, b.item, bases, local); - if (r != SWIG_OK) { - return r; - } - Delete(bases); - } - - Delete(local); - - Hash *parents = NewHash(); - addFirstBaseInterface(n, parents, baselist); - int r = addExtraBaseInterfaces(n, parents, baselist); - Delete(parents); - if (r != SWIG_OK) { - return r; - } - } - - Printv(f_go_wrappers, "type ", go_name, " interface {\n", NULL); - Printv(f_go_wrappers, "\tSwigcptr() uintptr\n", NULL); - Printv(f_go_wrappers, "\tSwigIs", go_name, "()\n", NULL); - - if (is_director) { - Printv(f_go_wrappers, "\tDirectorInterface() interface{}\n", NULL); - } - - Append(f_go_wrappers, interfaces); - Printv(f_go_wrappers, "}\n\n", NULL); - Delete(interfaces); - - interfaces = NULL; - class_name = NULL; - class_receiver = NULL; - class_node = NULL; - Delete(class_methods); - class_methods = NULL; - - Delete(go_type_name); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * addBase() - * - * Implement methods and members defined in a parent class for a - * child class. - * ------------------------------------------------------------ */ - - int addBase(Node *n, Node *base, List *bases, Hash *local) { - if (GetFlag(base, "feature:ignore")) { - return SWIG_OK; - } - - for (Node *ni = Getattr(base, "firstChild"); ni; ni = nextSibling(ni)) { - int r = goBaseEntry(n, bases, local, ni); - if (r != SWIG_OK) { - return r; - } - } - - List *baselist = Getattr(base, "bases"); - if (baselist && Len(baselist) > 0) { - for (Iterator b = First(baselist); b.item; b = Next(b)) { - List *nb = Copy(bases); - Append(nb, Getattr(b.item, "classtype")); - int r = addBase(n, b.item, nb, local); - Delete(nb); - if (r != SWIG_OK) { - return r; - } - } - } - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * goBaseEntry() - * - * Implement one entry defined in a parent class for a child class. - * n is the child class. - * ------------------------------------------------------------ */ - - int goBaseEntry(Node* n, List* bases, Hash *local, Node* entry) { - if (GetFlag(entry, "feature:ignore")) { - return SWIG_OK; - } - - if (!is_public(entry)) { - return SWIG_OK; - } - - String *type = Getattr(entry, "nodeType"); - if (Strcmp(type, "constructor") == 0 || Strcmp(type, "destructor") == 0 || Strcmp(type, "enum") == 0 || Strcmp(type, "using") == 0 || Strcmp(type, "classforward") == 0 || Strcmp(type, "template") == 0) { - return SWIG_OK; - } - - if (Strcmp(type, "extend") == 0) { - for (Node* extend = firstChild(entry); extend; extend = nextSibling(extend)) { - if (isStatic(extend)) { - // If we don't do this, the extend_default test case fails. - continue; - } - - int r = goBaseEntry(n, bases, local, extend); - if (r != SWIG_OK) { - return r; - } - } - return SWIG_OK; - } - - String *storage = Getattr(entry, "storage"); - if (storage && (Strcmp(storage, "typedef") == 0 || Strcmp(storage, "friend") == 0)) { - return SWIG_OK; - } - - String *mname = Getattr(entry, "sym:name"); - if (!mname) { - return SWIG_OK; - } - - String *lname = Getattr(entry, "name"); - if (Getattr(class_methods, lname)) { - return SWIG_OK; - } - if (Getattr(local, lname)) { - return SWIG_OK; - } - Setattr(local, lname, NewString("")); - - String *ty = NewString(Getattr(entry, "type")); - SwigType_push(ty, Getattr(entry, "decl")); - String *fullty = SwigType_typedef_resolve_all(ty); - bool is_function = SwigType_isfunction(fullty) ? true : false; - Delete(ty); - Delete(fullty); - - if (is_function) { - int r = goBaseMethod(n, bases, entry); - if (r != SWIG_OK) { - return r; - } - - if (Getattr(entry, "sym:overloaded")) { - for (Node *on = Getattr(entry, "sym:nextSibling"); on; on = Getattr(on, "sym:nextSibling")) { - r = goBaseMethod(n, bases, on); - if (r != SWIG_OK) { - return r; - } - } - - String *receiver = class_receiver; - bool is_static = isStatic(entry); - if (is_static) { - receiver = NULL; - } - String *go_name = buildGoName(Getattr(entry, "sym:name"), is_static, false); - r = makeDispatchFunction(entry, go_name, receiver, is_static, NULL, false); - Delete(go_name); - if (r != SWIG_OK) { - return r; - } - } - } else { - int r = goBaseVariable(n, bases, entry); - if (r != SWIG_OK) { - return r; - } - } - - return SWIG_OK; - } - - - /* ------------------------------------------------------------ - * goBaseMethod() - * - * Implement a method defined in a parent class for a child class. - * ------------------------------------------------------------ */ - - int goBaseMethod(Node *method_class, List *bases, Node *method) { - String *symname = Getattr(method, "sym:name"); - if (!validIdentifier(symname)) { - return SWIG_OK; - } - - String *name = NewString(""); - Printv(name, Getattr(method_class, "sym:name"), "_", symname, NULL); - - bool is_static = isStatic(method); - - String *go_name = buildGoName(name, is_static, false); - - String *overname = NULL; - if (Getattr(method, "sym:overloaded")) { - overname = Getattr(method, "sym:overname"); - } - String *wname = Swig_name_wrapper(name); - if (overname) { - Append(wname, overname); - } - Append(wname, unique_id); - - String *result = NewString(Getattr(method, "type")); - SwigType_push(result, Getattr(method, "decl")); - if (SwigType_isqualifier(result)) { - Delete(SwigType_pop(result)); - } - Delete(SwigType_pop_function(result)); - - // If the base method is imported, wrap:action may not be set. - Swig_save("goBaseMethod", method, "wrap:name", "wrap:action", "parms", NULL); - Setattr(method, "wrap:name", wname); - if (!Getattr(method, "wrap:action")) { - if (!is_static) { - Swig_MethodToFunction(method, getNSpace(), getClassType(), (Getattr(method, "template") ? SmartPointer : Extend | SmartPointer), NULL, false); - // Remove any self parameter that was just added. - ParmList *parms = Getattr(method, "parms"); - if (parms && Getattr(parms, "self")) { - parms = CopyParmList(nextSibling(parms)); - Setattr(method, "parms", parms); - } - } else { - String *call = Swig_cfunction_call(Getattr(method, "name"), Getattr(method, "parms")); - Setattr(method, "wrap:action", Swig_cresult(Getattr(method, "type"), Swig_cresult_name(), call)); - } - } - - // A method added by %extend in a base class may have void parms. - ParmList* parms = Getattr(method, "parms"); - if (parms != NULL && SwigType_type(Getattr(parms, "type")) == T_VOID) { - parms = NULL; - } - - int r = makeWrappers(method, go_name, overname, wname, bases, parms, result, is_static); - - Swig_restore(method); - - Delete(result); - Delete(go_name); - Delete(name); - - return r; - } - - /* ------------------------------------------------------------ - * goBaseVariable() - * - * Add accessors for a member variable defined in a parent class for - * a child class. - * ------------------------------------------------------------ */ - - int goBaseVariable(Node *var_class, List *bases, Node *var) { - if (isStatic(var)) { - return SWIG_OK; - } - - String *var_name = buildGoName(Getattr(var, "sym:name"), false, false); - - Swig_save("goBaseVariable", var, "type", "wrap:action", NULL); - - // For a pointer type we apparently have to wrap in the decl. - SwigType *var_type = NewString(Getattr(var, "type")); - SwigType_push(var_type, Getattr(var, "decl")); - Setattr(var, "type", var_type); - - SwigType *vt = Copy(var_type); - - int flags = Extend | SmartPointer | use_naturalvar_mode(var); - if (isNonVirtualProtectedAccess(var)) { - flags |= CWRAP_ALL_PROTECTED_ACCESS; - } - - // Copied from Swig_wrapped_member_var_type. - if (SwigType_isclass(vt)) { - if (flags & CWRAP_NATURAL_VAR) { - if (CPlusPlus) { - if (!SwigType_isconst(vt)) { - SwigType_add_qualifier(vt, "const"); - } - SwigType_add_reference(vt); - } - } else { - SwigType_add_pointer(vt); - } - } - - String *mname = Swig_name_member(getNSpace(), Getattr(var_class, "sym:name"), var_name); - - if (is_assignable(var)) { - for (Iterator ki = First(var); ki.key; ki = Next(ki)) { - if (Strncmp(ki.key, "tmap:", 5) == 0) { - Delattr(var, ki.key); - } - } - Swig_save("goBaseVariableSet", var, "name", "sym:name", "type", NULL); - - String *mname_set = NewString("Set"); - Append(mname_set, mname); - - String *go_name = NewString("Set"); - Append(go_name, var_name); - - Swig_MembersetToFunction(var, class_name, flags); - - String *wname = Swig_name_wrapper(mname_set); - Append(wname, unique_id); - ParmList *parms = NewParm(vt, var_name, var); - String *result = NewString("void"); - int r = makeWrappers(var, go_name, NULL, wname, bases, parms, result, false); - if (r != SWIG_OK) { - return r; - } - Delete(wname); - Delete(parms); - Delete(result); - Delete(go_name); - Delete(mname_set); - - Swig_restore(var); - for (Iterator ki = First(var); ki.key; ki = Next(ki)) { - if (Strncmp(ki.key, "tmap:", 5) == 0) { - Delattr(var, ki.key); - } - } - } - - Swig_MembergetToFunction(var, class_name, flags); - - String *mname_get = NewString("Get"); - Append(mname_get, mname); - - String *go_name = NewString("Get"); - Append(go_name, var_name); - - String *wname = Swig_name_wrapper(mname_get); - Append(wname, unique_id); - - int r = makeWrappers(var, go_name, NULL, wname, bases, NULL, vt, false); - if (r != SWIG_OK) { - return r; - } - - Delete(wname); - Delete(mname_get); - Delete(go_name); - Delete(mname); - Delete(var_name); - Delete(var_type); - Delete(vt); - - Swig_restore(var); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * addFirstBaseInterface() - * - * When a C++ class uses multiple inheritance, we can use the C++ - * pointer for the first base class but not for any subsequent base - * classes. However, the Go interface will match the interface for - * all the base classes. To avoid accidentally treating a class as - * a pointer to a base class other than the first one, we use an - * isClassname method. This function adds those methods as - * required. - * - * For convenience when using multiple inheritance, we also add - * functions to retrieve the base class pointers. - * ------------------------------------------------------------ */ - - void addFirstBaseInterface(Node *n, Hash *parents, List *bases) { - if (!bases || Len(bases) == 0) { - return; - } - Iterator b = First(bases); - if (!GetFlag(b.item, "feature:ignore")) { - String *go_name = buildGoName(Getattr(n, "sym:name"), false, false); - String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true); - String *go_base_name = exportedName(Getattr(b.item, "sym:name")); - String *go_base_type = goType(n, Getattr(b.item, "classtypeobj")); - String *go_base_type_name = goCPointerType(Getattr(b.item, "classtypeobj"), true); - - Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigIs", go_base_name, "() {\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - Printv(interfaces, "\tSwigIs", go_base_name, "()\n", NULL); - - Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigGet", go_base_name, "() ", go_base_type, " {\n", NULL); - Printv(f_go_wrappers, "\treturn ", go_base_type_name, "(getSwigcptr(p))\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - Printv(interfaces, "\tSwigGet", go_base_name, "() ", go_base_type, "\n", NULL); - - Setattr(parents, go_base_name, NewString("")); - - Delete(go_name); - Delete(go_type_name); - Delete(go_base_type); - Delete(go_base_type_name); - } - - addFirstBaseInterface(n, parents, Getattr(b.item, "bases")); - } - - /* ------------------------------------------------------------ - * addExtraBaseInterfaces() - * - * Add functions to retrieve the base class pointers for all base - * classes other than the first. - * ------------------------------------------------------------ */ - - int addExtraBaseInterfaces(Node *n, Hash *parents, List *bases) { - Iterator b = First(bases); - - Node *fb = b.item; - - for (b = Next(b); b.item; b = Next(b)) { - if (GetFlag(b.item, "feature:ignore")) { - continue; - } - - String *go_base_name = exportedName(Getattr(b.item, "sym:name")); - - Swig_save("addExtraBaseInterface", n, "wrap:action", "wrap:name", "wrap:parms", NULL); - - SwigType *type = Copy(Getattr(n, "classtypeobj")); - SwigType_add_pointer(type); - Parm *parm = NewParm(type, "self", n); - Setattr(n, "wrap:parms", parm); - - String *pn = Swig_cparm_name(parm, 0); - String *action = NewString(""); - Printv(action, Swig_cresult_name(), " = (", Getattr(b.item, "classtype"), "*)", pn, ";", NULL); - Delete(pn); - - Setattr(n, "wrap:action", action); - - String *name = Copy(class_name); - Append(name, "_SwigGet"); - Append(name, go_base_name); - - String *go_name = NewString("SwigGet"); - String *c1 = exportedName(go_base_name); - Append(go_name, c1); - Delete(c1); - - String *wname = Swig_name_wrapper(name); - Append(wname, unique_id); - Setattr(n, "wrap:name", wname); - - SwigType *result = Copy(Getattr(b.item, "classtypeobj")); - SwigType_add_pointer(result); - - int r = makeWrappers(n, go_name, NULL, wname, NULL, parm, result, false); - if (r != SWIG_OK) { - return r; - } - - Swig_restore(n); - - Setattr(parents, go_base_name, NewString("")); - - Delete(go_name); - Delete(type); - Delete(parm); - Delete(action); - Delete(result); - - String *ns = NewString(""); - addParentExtraBaseInterfaces(n, parents, b.item, false, ns); - Delete(ns); - } - - if (!GetFlag(fb, "feature:ignore")) { - String *ns = NewString(""); - addParentExtraBaseInterfaces(n, parents, fb, true, ns); - Delete(ns); - } - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * addParentExtraBaseInterfaces() - * - * Add functions to retrieve the base class pointers for all base - * classes of parents other than the first base class at each level. - * ------------------------------------------------------------ */ - - void addParentExtraBaseInterfaces(Node *n, Hash *parents, Node *base, bool is_base_first, String *sofar) { - List *baselist = Getattr(base, "bases"); - if (!baselist || Len(baselist) == 0) { - return; - } - - String *go_this_base_name = exportedName(Getattr(base, "sym:name")); - - String *sf = NewString(""); - Printv(sf, sofar, ".SwigGet", go_this_base_name, "()", NULL); - - Iterator b = First(baselist); - - if (is_base_first) { - if (!b.item) { - return; - } - if (!GetFlag(b.item, "feature:ignore")) { - addParentExtraBaseInterfaces(n, parents, b.item, true, sf); - } - - b = Next(b); - } - - String *go_name = buildGoName(Getattr(n, "sym:name"), false, false); - String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true); - - for (; b.item; b = Next(b)) { - if (GetFlag(b.item, "feature:ignore")) { - continue; - } - - String *go_base_name = exportedName(Getattr(b.item, "sym:name")); - - if (!Getattr(parents, go_base_name)) { - Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigGet", go_base_name, "() ", go_base_name, " {\n", NULL); - Printv(f_go_wrappers, "\treturn p", sf, ".SwigGet", go_base_name, "()\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - Printv(interfaces, "\tSwigGet", go_base_name, "() ", go_base_name, "\n", NULL); - - addParentExtraBaseInterfaces(n, parents, b.item, false, sf); - - Setattr(parents, go_base_name, NewString("")); - } - } - - Delete(go_name); - Delete(go_type_name); - Delete(go_this_base_name); - Delete(sf); - } - - /* ------------------------------------------------------------ - * classDirectorInit - * - * Add support for a director class. - * - * Virtual inheritance is different in Go and C++. We implement - * director classes by defining a new function in Go, - * NewDirectorClassname, which takes a empty interface value and - * creates an instance of a new child class. The new child class - * refers all methods back to Go. The Go code checks whether the - * value passed to NewDirectorClassname implements that method; if - * it does, it calls it, otherwise it calls back into C++. - * ------------------------------------------------------------ */ - - int classDirectorInit(Node *n) { - // Because we use a different function to handle inheritance in - // Go, ordinary creations of the object should not create a - // director object. - Delete(director_ctor_code); - director_ctor_code = NewString("$nondirector_new"); - - class_node = n; - - String *name = Getattr(n, "sym:name"); - - assert(!class_name); - class_name = name; - - String *go_name = exportedName(name); - - String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true); - - assert(!class_receiver); - class_receiver = go_type_name; - - String *director_struct_name = NewString("_swig_Director"); - Append(director_struct_name, go_name); - - String *cxx_director_name = NewString("SwigDirector_"); - Append(cxx_director_name, name); - - // The Go type of the director class. - Printv(f_go_wrappers, "type ", director_struct_name, " struct {\n", NULL); - Printv(f_go_wrappers, "\t", go_type_name, "\n", NULL); - Printv(f_go_wrappers, "\tv interface{}\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - Printv(f_go_wrappers, "func (p *", director_struct_name, ") Swigcptr() uintptr {\n", NULL); - Printv(f_go_wrappers, "\treturn getSwigcptr(p.", go_type_name, ")\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - Printv(f_go_wrappers, "func (p *", director_struct_name, ") SwigIs", go_name, "() {\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - Printv(f_go_wrappers, "func (p *", director_struct_name, ") DirectorInterface() interface{} {\n", NULL); - Printv(f_go_wrappers, "\treturn p.v\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - // Start defining the director class. - Printv(f_c_directors_h, "class ", cxx_director_name, " : public ", Getattr(n, "classtype"), "\n", NULL); - Printv(f_c_directors_h, "{\n", NULL); - Printv(f_c_directors_h, " public:\n", NULL); - - Delete(director_struct_name); - Delete(cxx_director_name); - - class_methods = NewHash(); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * classDirectorConstructor - * - * Emit a constructor for a director class. - * ------------------------------------------------------------ */ - - int classDirectorConstructor(Node *n) { - bool is_ignored = GetFlag(n, "feature:ignore") ? true : false; - - String *name = Getattr(n, "sym:name"); - if (!name) { - assert(is_ignored); - name = Getattr(n, "name"); - } - - String *overname = NULL; - if (Getattr(n, "sym:overloaded")) { - overname = Getattr(n, "sym:overname"); - } - - String *go_name = exportedName(name); - - ParmList *parms = Getattr(n, "parms"); - Setattr(n, "wrap:parms", parms); - - String *cn = exportedName(Getattr(parentNode(n), "sym:name")); - - String *go_type_name = goCPointerType(Getattr(parentNode(n), "classtypeobj"), true); - - String *director_struct_name = NewString("_swig_Director"); - Append(director_struct_name, cn); - - String *fn_name = NewString("_swig_NewDirector"); - Append(fn_name, cn); - Append(fn_name, go_name); - - if (!overname && !is_ignored) { - if (!checkNameConflict(fn_name, n, NULL)) { - return SWIG_NOWRAP; - } - } - - String *fn_with_over_name = Copy(fn_name); - if (overname) { - Append(fn_with_over_name, overname); - } - - String *wname = Swig_name_wrapper(fn_name); - - if (overname) { - Append(wname, overname); - } - Append(wname, unique_id); - Setattr(n, "wrap:name", wname); - - bool is_static = isStatic(n); - - Wrapper *dummy = NewWrapper(); - emit_attach_parmmaps(parms, dummy); - DelWrapper(dummy); - - Swig_typemap_attach_parms("gotype", parms, NULL); - Swig_typemap_attach_parms("goin", parms, NULL); - Swig_typemap_attach_parms("goargout", parms, NULL); - Swig_typemap_attach_parms("imtype", parms, NULL); - int parm_count = emit_num_arguments(parms); - - String *func_name = NewString("NewDirector"); - Append(func_name, go_name); - - String *func_with_over_name = Copy(func_name); - if (overname) { - Append(func_with_over_name, overname); - } - - SwigType *first_type = NewString("int"); - Parm *first_parm = NewParm(first_type, "swig_p", n); - set_nextSibling(first_parm, parms); - Setattr(first_parm, "lname", "p"); - - Parm *p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - Swig_cparm_name(p, i); - p = nextParm(p); - } - - if (!is_ignored) { - Printv(f_cgo_comment, "extern uintptr_t ", wname, "(int", NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - bool c_struct_type; - String *ct = cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type); - Printv(f_cgo_comment, ", ", ct, " ", Getattr(p, "lname"), NULL); - p = nextParm(p); - } - Printv(f_cgo_comment, ");\n", NULL); - - // Write out the Go function that calls the wrapper. - - Printv(f_go_wrappers, "func ", func_with_over_name, "(v interface{}", NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL); - String *tm = goType(p, Getattr(p, "type")); - Printv(f_go_wrappers, tm, NULL); - Delete(tm); - p = nextParm(p); - } - - Printv(f_go_wrappers, ") ", cn, " {\n", NULL); - - Printv(f_go_wrappers, "\tp := &", director_struct_name, "{0, v}\n", NULL); - - String *call = NewString(""); - - Printv(call, "\tp.", class_receiver, " = ", NULL); - Printv(call, go_type_name, "(C.", wname, "(C.int(swigDirectorAdd(p))", NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - Printv(call, ", ", NULL); - - p = getParm(p); - String *pt = Getattr(p, "type"); - String *ln = Getattr(p, "lname"); - - String *ivar = NewStringf("_swig_i_%d", i); - - String *goin = goGetattr(p, "tmap:goin"); - if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", NULL); - bool need_close = false; - if (goTypeIsInterface(p, pt)) { - Printv(f_go_wrappers, "getSwigcptr(", NULL); - need_close = true; - } - Printv(f_go_wrappers, ln, NULL); - if (need_close) { - Printv(f_go_wrappers, ")", NULL); - } - Printv(f_go_wrappers, "\n", NULL); - } else { - String *itm = goImType(p, pt); - Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL); - goin = Copy(goin); - Replaceall(goin, "$input", ln); - Replaceall(goin, "$result", ivar); - Printv(f_go_wrappers, goin, "\n", NULL); - Delete(goin); - } - - Setattr(p, "emit:goinput", ivar); - - bool c_struct_type; - String *ct = cgoTypeForGoValue(p, pt, &c_struct_type); - if (c_struct_type) { - Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL); - } else { - Printv(call, "C.", ct, "(", ivar, ")", NULL); - } - Delete(ct); - - p = nextParm(p); - } - - Printv(call, "))", NULL); - - Printv(f_go_wrappers, call, "\n", NULL); - - goargout(parms); - - Printv(f_go_wrappers, "\treturn p\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - SwigType *result = Copy(Getattr(parentNode(n), "classtypeobj")); - SwigType_add_pointer(result); - - Swig_save("classDirectorConstructor", n, "wrap:name", "wrap:action", NULL); - - String *dwname = Swig_name_wrapper(name); - Append(dwname, unique_id); - Setattr(n, "wrap:name", dwname); - - String *action = NewString(""); - Printv(action, Swig_cresult_name(), " = new SwigDirector_", class_name, "(", NULL); - String *pname = Swig_cparm_name(NULL, 0); - Printv(action, pname, NULL); - Delete(pname); - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - String *pname = Swig_cparm_name(NULL, i + 1); - Printv(action, ", ", NULL); - if (SwigType_isreference(Getattr(p, "type"))) { - Printv(action, "*", NULL); - } - Printv(action, pname, NULL); - Delete(pname); - p = nextParm(p); - } - Printv(action, ");", NULL); - Setattr(n, "wrap:action", action); - - cgoWrapperInfo info; - - info.n = n; - info.go_name = func_name; - info.overname = overname; - info.wname = wname; - info.base = NULL; - info.parms = first_parm; - info.result = result; - info.is_static = false; - info.receiver = NULL; - info.is_constructor = true; - info.is_destructor = false; - - int r = cgoGccWrapper(&info); - if (r != SWIG_OK) { - return r; - } - - Swig_restore(n); - - Delete(result); - } - - String *cxx_director_name = NewString("SwigDirector_"); - Append(cxx_director_name, class_name); - - String *decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0); - Printv(f_c_directors_h, " ", decl, ";\n", NULL); - Delete(decl); - - decl = Swig_method_decl(NULL, Getattr(n, "decl"), cxx_director_name, first_parm, 0); - Printv(f_c_directors, cxx_director_name, "::", decl, "\n", NULL); - Delete(decl); - - Printv(f_c_directors, " : ", Getattr(parentNode(n), "classtype"), "(", NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - if (i > 0) { - Printv(f_c_directors, ", ", NULL); - } - String *pn = Getattr(p, "name"); - assert(pn); - Printv(f_c_directors, pn, NULL); - p = nextParm(p); - } - Printv(f_c_directors, "),\n", NULL); - Printv(f_c_directors, " go_val(swig_p), swig_mem(0)\n", NULL); - Printv(f_c_directors, "{ }\n\n", NULL); - - if (Getattr(n, "sym:overloaded") && !Getattr(n, "sym:nextSibling")) { - int r = makeDispatchFunction(n, func_name, cn, is_static, Getattr(parentNode(n), "classtypeobj"), false); - if (r != SWIG_OK) { - return r; - } - } - - Delete(cxx_director_name); - Delete(go_name); - Delete(cn); - Delete(go_type_name); - Delete(director_struct_name); - Delete(fn_name); - Delete(fn_with_over_name); - Delete(func_name); - Delete(func_with_over_name); - Delete(wname); - Delete(first_type); - Delete(first_parm); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * classDirectorDestructor - * - * Emit a destructor for a director class. - * ------------------------------------------------------------ */ - - int classDirectorDestructor(Node *n) { - if (!is_public(n)) { - return SWIG_OK; - } - - bool is_ignored = GetFlag(n, "feature:ignore") ? true : false; - - if (!is_ignored) { - String *fnname = NewString("DeleteDirector"); - String *c1 = exportedName(class_name); - Append(fnname, c1); - Delete(c1); - - String *wname = Swig_name_wrapper(fnname); - Append(wname, unique_id); - - Setattr(n, "wrap:name", fnname); - - Swig_DestructorToFunction(n, getNSpace(), getClassType(), CPlusPlus, Extend); - - ParmList *parms = Getattr(n, "parms"); - Setattr(n, "wrap:parms", parms); - - String *result = NewString("void"); - int r = makeWrappers(n, fnname, NULL, wname, NULL, parms, result, isStatic(n)); - if (r != SWIG_OK) { - return r; - } - - Delete(result); - Delete(fnname); - Delete(wname); - } - - // Generate the destructor for the C++ director class. Since the - // Go code is keeping a pointer to the C++ object, we need to call - // back to the Go code to let it know that the C++ object is gone. - - String *go_name = NewString("Swiggo_DeleteDirector_"); - Append(go_name, class_name); - - String *cn = exportedName(class_name); - - String *director_struct_name = NewString("_swig_Director"); - Append(director_struct_name, cn); - - Printv(f_c_directors_h, " virtual ~SwigDirector_", class_name, "()", NULL); - - String *throws = buildThrow(n); - if (throws) { - Printv(f_c_directors_h, " ", throws, NULL); - } - - Printv(f_c_directors_h, ";\n", NULL); - - String *director_sig = NewString(""); - - Printv(director_sig, "SwigDirector_", class_name, "::~SwigDirector_", class_name, "()", NULL); - - if (throws) { - Printv(director_sig, " ", throws, NULL); - Delete(throws); - } - - Printv(director_sig, "\n", NULL); - Printv(director_sig, "{\n", NULL); - - if (is_ignored) { - Printv(f_c_directors, director_sig, NULL); - } else { - makeDirectorDestructorWrapper(go_name, director_struct_name, director_sig); - } - - Printv(f_c_directors, " delete swig_mem;\n", NULL); - - Printv(f_c_directors, "}\n\n", NULL); - - Delete(director_sig); - Delete(go_name); - Delete(cn); - Delete(director_struct_name); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * makeDirectorDestructorWrapper - * - * Emit the function wrapper for the destructor of a director class. - * ------------------------------------------------------------ */ - - void makeDirectorDestructorWrapper(String *go_name, String *director_struct_name, String *director_sig) { - String *wname = Copy(go_name); - Append(wname, unique_id); - - Printv(f_go_wrappers, "//export ", wname, "\n", NULL); - Printv(f_go_wrappers, "func ", wname, "(c int) {\n", NULL); - Printv(f_go_wrappers, "\tswigDirectorLookup(c).(*", director_struct_name, ").", class_receiver, " = 0\n", NULL); - Printv(f_go_wrappers, "\tswigDirectorDelete(c)\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - Printv(f_c_directors, "extern \"C\" void ", wname, "(intgo);\n", NULL); - Printv(f_c_directors, director_sig, NULL); - Printv(f_c_directors, " ", wname, "(go_val);\n", NULL); - } - - /* ------------------------------------------------------------ - * classDirectorMethod - * - * Emit a method for a director class, plus its overloads. - * ------------------------------------------------------------ */ - - int classDirectorMethod(Node *n, Node *parent, String *super) { - bool is_ignored = GetFlag(n, "feature:ignore") ? true : false; - - // We don't need explicit calls. - if (GetFlag(n, "explicitcall")) { - return SWIG_OK; - } - - String *name = Getattr(n, "sym:name"); - if (!name) { - assert(is_ignored); - (void)is_ignored; - name = Getattr(n, "name"); - } - - bool overloaded = Getattr(n, "sym:overloaded") && !Getattr(n, "explicitcallnode"); - if (!overloaded) { - int r = oneClassDirectorMethod(n, parent, super); - if (r != SWIG_OK) { - return r; - } - } else { - // Handle overloaded methods here, because otherwise we will - // reject them in the class_methods hash table. We need to use - // class_methods so that we correctly handle cases where a - // function in one class hides a function of the same name in a - // parent class. - if (!Getattr(class_methods, name)) { - for (Node *on = Getattr(n, "sym:overloaded"); on; on = Getattr(on, "sym:nextSibling")) { - // Swig_overload_rank expects wrap:name and wrap:parms to be - // set. - String *wn = Swig_name_wrapper(Getattr(on, "sym:name")); - Append(wn, Getattr(on, "sym:overname")); - Append(wn, unique_id); - Setattr(on, "wrap:name", wn); - Delete(wn); - Setattr(on, "wrap:parms", Getattr(on, "parms")); - } - } - - int r = oneClassDirectorMethod(n, parent, super); - if (r != SWIG_OK) { - return r; - } - - if (!Getattr(n, "sym:nextSibling")) - { - // Last overloaded function - Node *on = Getattr(n, "sym:overloaded"); - bool is_static = isStatic(on); - - String *cn = exportedName(Getattr(parent, "sym:name")); - String *go_name = buildGoName(name, is_static, false); - - String *director_struct_name = NewString("_swig_Director"); - Append(director_struct_name, cn); - - int r = makeDispatchFunction(on, go_name, director_struct_name, is_static, director_struct_name, false); - if (r != SWIG_OK) { - return r; - } - - if (!GetFlag(n, "abstract")) { - String *go_upcall = NewString("Director"); - Append(go_upcall, cn); - Append(go_upcall, go_name); - r = makeDispatchFunction(on, go_upcall, director_struct_name, is_static, director_struct_name, true); - if (r != SWIG_OK) { - return r; - } - Delete(go_upcall); - } - - Delete(director_struct_name); - Delete(go_name); - Delete(cn); - } - } - Setattr(class_methods, name, NewString("")); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * oneClassDirectorMethod - * - * Emit a method for a director class. - * ------------------------------------------------------------ */ - - int oneClassDirectorMethod(Node *n, Node *parent, String *super) { - String *symname = Getattr(n, "sym:name"); - if (!checkFunctionVisibility(n, parent)) { - return SWIG_OK; - } - - bool is_ignored = GetFlag(n, "feature:ignore") ? true : false; - bool is_pure_virtual = (Cmp(Getattr(n, "storage"), "virtual") == 0 && Cmp(Getattr(n, "value"), "0") == 0); - - String *name = Getattr(n, "sym:name"); - if (!name) { - assert(is_ignored); - name = Getattr(n, "name"); - } - - String *overname = NULL; - if (Getattr(n, "sym:overloaded")) { - overname = Getattr(n, "sym:overname"); - } - - String *cn = exportedName(Getattr(parent, "sym:name")); - - String *go_type_name = goCPointerType(Getattr(parent, "classtypeobj"), true); - - String *director_struct_name = NewString("_swig_Director"); - Append(director_struct_name, cn); - - bool is_static = isStatic(n); - - String *go_name = buildGoName(name, is_static, false); - - ParmList *parms = Getattr(n, "parms"); - Setattr(n, "wrap:parms", parms); - - Wrapper *dummy = NewWrapper(); - emit_attach_parmmaps(parms, dummy); - - Swig_typemap_attach_parms("gotype", parms, NULL); - Swig_typemap_attach_parms("imtype", parms, NULL); - int parm_count = emit_num_arguments(parms); - - SwigType *result = Getattr(n, "type"); - - // Save the type for overload processing. - Setattr(n, "go:type", result); - - String *interface_name = NewString("_swig_DirectorInterface"); - Append(interface_name, cn); - Append(interface_name, go_name); - if (overname) { - Append(interface_name, overname); - } - - String *callback_name = Copy(director_struct_name); - Append(callback_name, "_callback_"); - Append(callback_name, name); - Replace(callback_name, "_swig", "Swig", DOH_REPLACE_FIRST); - if (overname) { - Append(callback_name, overname); - } - Append(callback_name, unique_id); - - String *upcall_name = Copy(director_struct_name); - Append(upcall_name, "_upcall_"); - Append(upcall_name, go_name); - - String *upcall_wname = Swig_name_wrapper(upcall_name); - if (overname) { - Append(upcall_wname, overname); - } - Append(upcall_wname, unique_id); - - String *upcall_gc_name = buildGoWrapperName(upcall_name, overname); - - String *go_with_over_name = Copy(go_name); - if (overname) { - Append(go_with_over_name, overname); - } - - Parm *p = 0; - Wrapper *w = NewWrapper(); - - Swig_director_parms_fixup(parms); - - Swig_typemap_attach_parms("directorin", parms, w); - Swig_typemap_attach_parms("directorargout", parms, w); - Swig_typemap_attach_parms("godirectorin", parms, w); - Swig_typemap_attach_parms("goin", parms, dummy); - Swig_typemap_attach_parms("goargout", parms, dummy); - - DelWrapper(dummy); - - if (!is_ignored) { - // We use an interface to see if this method is defined in Go. - Printv(f_go_wrappers, "type ", interface_name, " interface {\n", NULL); - Printv(f_go_wrappers, "\t", go_with_over_name, "(", NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - if (i > 0) { - Printv(f_go_wrappers, ", ", NULL); - } - String *tm = goType(p, Getattr(p, "type")); - Printv(f_go_wrappers, tm, NULL); - Delete(tm); - p = nextParm(p); - } - - Printv(f_go_wrappers, ")", NULL); - - if (SwigType_type(result) != T_VOID) { - String *tm = goType(n, result); - Printv(f_go_wrappers, " ", tm, NULL); - Delete(tm); - } - - Printv(f_go_wrappers, "\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - if (!GetFlag(n, "abstract")) { - Printv(f_cgo_comment, "extern ", NULL); - - if (SwigType_type(result) == T_VOID) { - Printv(f_cgo_comment, "void", NULL); - } else { - bool c_struct_type; - String *ret_type = cgoTypeForGoValue(n, result, &c_struct_type); - Printv(f_cgo_comment, ret_type, NULL); - Delete(ret_type); - } - - Printv(f_cgo_comment, " ", upcall_wname, "(uintptr_t", NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - bool c_struct_type; - String *ct = cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type); - Printv(f_cgo_comment, ", ", ct, " ", Getattr(p, "lname"), NULL); - p = nextParm(p); - } - Printv(f_cgo_comment, ");\n", NULL); - } - - // Define the method on the director class in Go. - - Printv(f_go_wrappers, "func (swig_p *", director_struct_name, ") ", go_with_over_name, "(", NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - if (i > 0) { - Printv(f_go_wrappers, ", ", NULL); - } - Printv(f_go_wrappers, Getattr(p, "lname"), " ", NULL); - String *tm = goType(p, Getattr(p, "type")); - Printv(f_go_wrappers, tm, NULL); - Delete(tm); - p = nextParm(p); - } - - Printv(f_go_wrappers, ")", NULL); - - if (SwigType_type(result) != T_VOID) { - String *tm = goType(n, result); - Printv(f_go_wrappers, " ", tm, NULL); - Delete(tm); - } - - Printv(f_go_wrappers, " {\n", NULL); - - Printv(f_go_wrappers, "\tif swig_g, swig_ok := swig_p.v.(", interface_name, "); swig_ok {\n", NULL); - Printv(f_go_wrappers, "\t\t", NULL); - if (SwigType_type(result) != T_VOID) { - Printv(f_go_wrappers, "return ", NULL); - } - Printv(f_go_wrappers, "swig_g.", go_with_over_name, "(", NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - if (i > 0) { - Printv(f_go_wrappers, ", ", NULL); - } - Printv(f_go_wrappers, Getattr(p, "lname"), NULL); - p = nextParm(p); - } - - Printv(f_go_wrappers, ")\n", NULL); - if (SwigType_type(result) == T_VOID) { - Printv(f_go_wrappers, "\t\treturn\n", NULL); - } - Printv(f_go_wrappers, "\t}\n", NULL); - - if (GetFlag(n, "abstract")) { - Printv(f_go_wrappers, "\tpanic(\"call to pure virtual method\")\n", NULL); - } else { - String *ret_type = NULL; - bool memcpy_ret = false; - String *wt = NULL; - String *goout = NULL; - if (SwigType_type(result) != T_VOID) { - ret_type = goImType(n, result); - Printv(f_go_wrappers, "\tvar swig_r ", ret_type, "\n", NULL); - goout = goTypemapLookup("goout", n, "swig_r"); - - bool c_struct_type; - Delete(cgoTypeForGoValue(n, result, &c_struct_type)); - if (c_struct_type) { - memcpy_ret = true; - } - } - - String *call = NewString(""); - - Printv(call, "\t", NULL); - if (SwigType_type(result) != T_VOID) { - if (memcpy_ret) { - Printv(call, "swig_r_p := ", NULL); - } else { - Printv(call, "swig_r = (", ret_type, ")(", NULL); - } - if (goTypeIsInterface(n, result)) { - wt = goWrapperType(n, result, true); - Printv(call, "(", wt, ")(", NULL); - } - } - - Printv(call, "C.", upcall_wname, "(C.uintptr_t(swig_p.", - go_type_name, ")", NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - Printv(call, ", ", NULL); - p = getParm(p); - SwigType *pt = Getattr(p, "type"); - - String *ln = Getattr(p, "lname"); - - String *ivar = NewStringf("_swig_i_%d", i); - - // This is an ordinary call from Go to C++, so adjust using - // the goin typemap. - String *goin = goGetattr(p, "tmap:goin"); - if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", NULL); - bool need_close = false; - if (goTypeIsInterface(p, pt)) { - Printv(f_go_wrappers, "getSwigcptr(", NULL); - need_close = true; - } - Printv(f_go_wrappers, ln, NULL); - if (need_close) { - Printv(f_go_wrappers, ")", NULL); - } - Printv(f_go_wrappers, "\n", NULL); - } else { - String *itm = goImType(p, pt); - Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL); - goin = Copy(goin); - Replaceall(goin, "$input", ln); - Replaceall(goin, "$result", ivar); - Printv(f_go_wrappers, goin, "\n", NULL); - Delete(goin); - } - - Setattr(p, "emit:goinput", ivar); - - bool c_struct_type; - String *ct = cgoTypeForGoValue(p, pt, &c_struct_type); - if (c_struct_type) { - Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL); - } else { - Printv(call, "C.", ct, "(", ivar, ")", NULL); - } - - p = nextParm(p); - } - - Printv(call, ")", NULL); - - if (wt) { - // Close the type conversion to the wrapper type. - Printv(call, ")", NULL); - } - if (SwigType_type(result) != T_VOID && !memcpy_ret) { - // Close the type conversion of the return value. - Printv(call, ")", NULL); - } - - Printv(call, "\n", NULL); - - Printv(f_go_wrappers, call, NULL); - Delete(call); - - if (memcpy_ret) { - Printv(f_go_wrappers, "\tswig_r = *(*", ret_type, ")(unsafe.Pointer(&swig_r_p))\n", NULL); - } - - goargout(parms); - - if (SwigType_type(result) != T_VOID) { - if (goout == NULL) { - Printv(f_go_wrappers, "\treturn swig_r\n", NULL); - } else { - String *tm = goType(n, result); - Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL); - Replaceall(goout, "$input", "swig_r"); - Replaceall(goout, "$result", "swig_r_1"); - Printv(f_go_wrappers, goout, "\n", NULL); - Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL); - } - } - - if (ret_type) { - Delete(ret_type); - } - if (wt) { - Delete(wt); - } - } - - Printv(f_go_wrappers, "}\n\n", NULL); - - if (!GetFlag(n, "abstract")) { - // Define a function that uses the Go director type that other - // methods in the Go type can call to get parent methods. - - Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(swig_p ", cn, NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL); - String *tm = goType(p, Getattr(p, "type")); - Printv(f_go_wrappers, tm, NULL); - Delete(tm); - p = nextParm(p); - } - - Printv(f_go_wrappers, ")", NULL); - - if (SwigType_type(result) != T_VOID) { - String *tm = goType(n, result); - Printv(f_go_wrappers, " ", tm, NULL); - Delete(tm); - } - - Printv(f_go_wrappers, " {\n", NULL); - - String *ret_type = NULL; - bool memcpy_ret = false; - String *wt = NULL; - String *goout = NULL; - if (SwigType_type(result) != T_VOID) { - ret_type = goImType(n, result); - Printv(f_go_wrappers, "\tvar swig_r ", ret_type, "\n", NULL); - goout = goTypemapLookup("goout", n, "swig_r"); - - bool c_struct_type; - Delete(cgoTypeForGoValue(n, result, &c_struct_type)); - if (c_struct_type) { - memcpy_ret = true; - } - } - - String *call = NewString(""); - - Printv(call, "\t", NULL); - if (SwigType_type(result) != T_VOID) { - if (memcpy_ret) { - Printv(call, "swig_r_p := ", NULL); - } else { - Printv(call, "swig_r = (", ret_type, ")(", NULL); - } - if (goTypeIsInterface(n, result)) { - wt = goWrapperType(n, result, true); - Printv(call, "(", wt, ")(", NULL); - } - } - - Printv(call, "C.", upcall_wname, "(C.uintptr_t(swig_p.(*", - director_struct_name, ").", go_type_name, ")", NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - Printv(call, ", ", NULL); - p = getParm(p); - SwigType *pt = Getattr(p, "type"); - - String *ivar = NewStringf("_swig_i_%d", i); - - String *ln = Copy(Getattr(p, "lname")); - - String *goin = goGetattr(p, "tmap:goin"); - if (goin == NULL) { - Printv(f_go_wrappers, "\t", ivar, " := ", NULL); - bool need_close = false; - if (goTypeIsInterface(p, pt)) { - Printv(f_go_wrappers, "getSwigcptr(", NULL); - need_close = true; - } - Printv(f_go_wrappers, ln, NULL); - if (need_close) { - Printv(f_go_wrappers, ")", NULL); - } - Printv(f_go_wrappers, "\n", NULL); - } else { - String *itm = goImType(p, pt); - Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL); - goin = Copy(goin); - Replaceall(goin, "$input", ln); - Replaceall(goin, "$result", ivar); - Printv(f_go_wrappers, goin, "\n", NULL); - Delete(goin); - } - - Setattr(p, "emit:goinput", ivar); - - bool c_struct_type; - String *ct = cgoTypeForGoValue(p, pt, &c_struct_type); - if (c_struct_type) { - Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL); - } else { - Printv(call, "C.", ct, "(", ivar, ")", NULL); - } - - Delete(ln); - - p = nextParm(p); - } - - Printv(call, ")", NULL); - - if (wt) { - // Close the type conversion to the wrapper type. - Printv(call, ")", NULL); - } - if (SwigType_type(result) != T_VOID && !memcpy_ret) { - // Close the type conversion of the return value. - Printv(call, ")", NULL); - } - - Printv(call, "\n", NULL); - - Printv(f_go_wrappers, call, NULL); - Delete(call); - - if (memcpy_ret) { - Printv(f_go_wrappers, "\tswig_r = *(*", ret_type, ")(unsafe.Pointer(&swig_r_p))\n", NULL); - } - - goargout(parms); - - if (SwigType_type(result) != T_VOID) { - if (goout == NULL) { - Printv(f_go_wrappers, "\treturn swig_r\n", NULL); - } else { - String *tm = goType(n, result); - Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL); - Replaceall(goout, "$input", "swig_r"); - Replaceall(goout, "$result", "swig_r_1"); - Printv(f_go_wrappers, goout, "\n", NULL); - Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL); - } - } - - Printv(f_go_wrappers, "}\n\n", NULL); - - if (ret_type) { - Delete(ret_type); - } - if (wt) { - Delete(wt); - } - - // Define a method in the C++ director class that the C++ - // upcall function can call. This permits an upcall to a - // protected method. - - String *upcall_method_name = NewString("_swig_upcall_"); - Append(upcall_method_name, name); - if (overname) { - Append(upcall_method_name, overname); - } - SwigType *rtype = Getattr(n, "classDirectorMethods:type"); - String *upcall_decl = Swig_method_decl(rtype, Getattr(n, "decl"), upcall_method_name, parms, 0); - Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL); - Delete(upcall_decl); - - Printv(f_c_directors_h, " ", NULL); - if (SwigType_type(result) != T_VOID) { - Printv(f_c_directors_h, "return ", NULL); - } - - String *super_call = Swig_method_call(super, parms); - Printv(f_c_directors_h, super_call, ";\n", NULL); - Delete(super_call); - - Printv(f_c_directors_h, " }\n", NULL); - - // Define the C++ function that the Go function calls. - - SwigType *first_type = NULL; - Parm *first_parm = parms; - if (!is_static) { - first_type = NewString("SwigDirector_"); - Append(first_type, class_name); - SwigType_add_pointer(first_type); - first_parm = NewParm(first_type, "p", n); - set_nextSibling(first_parm, parms); - } - - Swig_save("classDirectorMethod", n, "wrap:name", "wrap:action", NULL); - - Setattr(n, "wrap:name", upcall_wname); - - String *action = NewString(""); - if (SwigType_type(result) != T_VOID) { - Printv(action, Swig_cresult_name(), " = (", SwigType_lstr(result, 0), ")", NULL); - if (SwigType_isreference(result)) { - Printv(action, "&", NULL); - } - } - Printv(action, Swig_cparm_name(NULL, 0), "->", upcall_method_name, "(", NULL); - - p = parms; - int i = 0; - while (p != NULL) { - if (SwigType_type(Getattr(p, "type")) != T_VOID) { - String *pname = Swig_cparm_name(NULL, i + 1); - if (i > 0) { - Printv(action, ", ", NULL); - } - - // A parameter whose type is a reference is converted into a - // pointer type by gcCTypeForGoValue. We are calling a - // function which expects a reference so we need to convert - // back. - if (SwigType_isreference(Getattr(p, "type"))) { - Printv(action, "*", NULL); - } - - Printv(action, pname, NULL); - Delete(pname); - i++; - } - p = nextSibling(p); - } - Printv(action, ");", NULL); - Setattr(n, "wrap:action", action); - - cgoWrapperInfo info; - - info.n = n; - info.go_name = go_name; - info.overname = overname; - info.wname = upcall_wname; - info.base = NULL; - info.parms = first_parm; - info.result = result; - info.is_static = is_static; - info.receiver = NULL; - info.is_constructor = false; - info.is_destructor = false; - - int r = cgoGccWrapper(&info); - if (r != SWIG_OK) { - return r; - } - - Delete(first_type); - if (first_parm != parms) { - Delete(first_parm); - } - - Swig_restore(n); - Delete(upcall_method_name); - } - - // The Go function which invokes the method. This is called by - // the C++ method on the director class. - - Printv(f_go_wrappers, "//export ", callback_name, "\n", - "func ", callback_name, "(swig_c int", NULL); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - String *tm = goWrapperType(p, Getattr(p, "type"), false); - Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", tm, NULL); - Delete(tm); - p = nextParm(p); - } - - Printv(f_go_wrappers, ") ", NULL); - String *result_wrapper = NULL; - if (SwigType_type(result) != T_VOID) { - result_wrapper = goWrapperType(n, result, true); - Printv(f_go_wrappers, "(swig_result ", result_wrapper, ") ", NULL); - } - Printv(f_go_wrappers, "{\n", NULL); - - if (is_ignored) { - Printv(f_go_wrappers, "\treturn\n", NULL); - } else { - bool result_is_interface = false; - String *goout = NULL; - if (SwigType_type(result) != T_VOID) { - result_is_interface = goTypeIsInterface(NULL, result); - Printv(f_go_wrappers, "\tvar swig_r ", NULL); - if (!result_is_interface) { - Printv(f_go_wrappers, goType(n, result), NULL); - } else { - Printv(f_go_wrappers, result_wrapper, NULL); - } - Printv(f_go_wrappers, "\n", NULL); - goout = goTypemapLookup("godirectorout", n, "swig_r"); - } - - String *call = NewString(""); - Printv(call, "\t", NULL); - - if (SwigType_type(result) != T_VOID) { - Printv(call, "swig_r = ", NULL); - if (result_is_interface) { - Printv(call, result_wrapper, "(getSwigcptr(", NULL); - } - } - Printv(call, "swig_p.", go_with_over_name, "(", NULL); - - String *goincode = NewString(""); - - p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - if (i > 0) { - Printv(call, ", ", NULL); - } - SwigType *pt = Getattr(p, "type"); - - String *ln = NewString(""); - - // If the Go representation is an interface type class, then - // we are receiving a uintptr, and must convert to the - // interface. - bool is_interface = goTypeIsInterface(p, pt); - if (is_interface) { - // Passing is_result as true to goWrapperType gives us the - // name of the Go type we need to convert to an interface. - String *wt = goWrapperType(p, pt, true); - Printv(ln, wt, "(", NULL); - Delete(wt); - } - - Printv(ln, Getattr(p, "lname"), NULL); - - if (is_interface) { - Printv(ln, ")", NULL); - } - - String *goin = goGetattr(p, "tmap:godirectorin"); - if (goin == NULL) { - Printv(call, ln, NULL); - } else { - String *ivar = NewString(""); - Printf(ivar, "_swig_i_%d", i); - String *itm = goType(p, pt); - Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL); - goin = Copy(goin); - Replaceall(goin, "$input", ln); - Replaceall(goin, "$result", ivar); - Printv(goincode, goin, "\n", NULL); - Delete(goin); - Printv(call, ivar, NULL); - Delete(ivar); - } - - Delete(ln); - - p = nextParm(p); - } - - Printv(call, ")", NULL); - - if (result_is_interface) { - Printv(call, "))", NULL); - } - Printv(call, "\n", NULL); - - Printv(f_go_wrappers, "\tswig_p := swigDirectorLookup(swig_c).(*", director_struct_name, ")\n", NULL); - Printv(f_go_wrappers, goincode, NULL); - Printv(f_go_wrappers, call, NULL); - Delete(call); - - if (SwigType_type(result) != T_VOID) { - if (goout == NULL) { - Printv(f_go_wrappers, "\treturn swig_r\n", NULL); - } else { - String *tm = goImType(n, result); - Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL); - Replaceall(goout, "$input", "swig_r"); - Replaceall(goout, "$result", "swig_r_1"); - Printv(f_go_wrappers, goout, "\n", NULL); - Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL); - } - } - } - - Printv(f_go_wrappers, "}\n\n", NULL); - - Delete(result_wrapper); - - Delete(upcall_wname); - Delete(upcall_gc_name); - Delete(go_with_over_name); - } - - if (!is_ignored || is_pure_virtual) { - // Declare the method for the director class. - - SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type"); - String *decl = Swig_method_decl(rtype, Getattr(n, "decl"), Getattr(n, "name"), parms, 0); - Printv(f_c_directors_h, " virtual ", decl, NULL); - Delete(decl); - - String *qname = NewString(""); - Printv(qname, "SwigDirector_", class_name, "::", Getattr(n, "name"), NULL); - decl = Swig_method_decl(rtype, Getattr(n, "decl"), qname, parms, 0); - Printv(w->def, decl, NULL); - Delete(decl); - Delete(qname); - - String *throws = buildThrow(n); - if (throws) { - Printv(f_c_directors_h, " ", throws, NULL); - Printv(w->def, " ", throws, NULL); - Delete(throws); - } - - Printv(f_c_directors_h, ";\n", NULL); - - Printv(w->def, " {\n", NULL); - - if (SwigType_type(result) != T_VOID) { - if (!SwigType_isclass(result)) { - if (!(SwigType_ispointer(result) || SwigType_isreference(result))) { - String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(result, 0)); - Wrapper_add_localv(w, "c_result", SwigType_lstr(result, "c_result"), construct_result, NIL); - Delete(construct_result); - } else { - Wrapper_add_localv(w, "c_result", SwigType_lstr(result, "c_result"), "= 0", NIL); - } - } else { - String *cres = SwigType_lstr(result, "c_result"); - Printf(w->code, "%s;\n", cres); - Delete(cres); - } - } - - if (!is_ignored) { - makeDirectorMethodWrapper(n, w, callback_name); - } else { - assert(is_pure_virtual); - Printv(w->code, " _swig_gopanic(\"call to pure virtual function ", Getattr(parent, "sym:name"), name, "\");\n", NULL); - if (SwigType_type(result) != T_VOID) { - String *retstr = SwigType_rcaststr(result, "c_result"); - Printv(w->code, " return ", retstr, ";\n", NULL); - Delete(retstr); - } - } - - Printv(w->code, "}", NULL); - - Replaceall(w->code, "$symname", symname); - Wrapper_print(w, f_c_directors); - } - - Delete(cn); - Delete(go_type_name); - Delete(director_struct_name); - Delete(interface_name); - Delete(callback_name); - Delete(upcall_name); - Delete(go_name); - DelWrapper(w); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * makeDirectorMethodWrapper - * - * Emit the function wrapper for a director method. - * ------------------------------------------------------------ */ - void makeDirectorMethodWrapper(Node *n, Wrapper *w, String *callback_name) { - ParmList *parms = Getattr(n, "wrap:parms"); - SwigType *result = Getattr(n, "type"); - - Printv(f_c_directors, "extern \"C\" ", NULL); - - String *fnname = Copy(callback_name); - Append(fnname, "(int"); - - Parm *p = parms; - while (p) { - while (checkAttribute(p, "tmap:directorin:numinputs", "0")) { - p = Getattr(p, "tmap:directorin:next"); - } - String *cg = gcCTypeForGoValue(p, Getattr(p, "type"), Getattr(p, "lname")); - Printv(fnname, ", ", cg, NULL); - Delete(cg); - p = Getattr(p, "tmap:directorin:next"); - } - - Printv(fnname, ")", NULL); - - if (SwigType_type(result) == T_VOID) { - Printv(f_c_directors, "void ", fnname, NULL); - } else { - String *tm = gcCTypeForGoValue(n, result, fnname); - Printv(f_c_directors, tm, NULL); - Delete(tm); - } - - Delete(fnname); - - Printv(f_c_directors, ";\n", NULL); - - if (SwigType_type(result) != T_VOID) { - String *r = NewString(Swig_cresult_name()); - String *tm = gcCTypeForGoValue(n, result, r); - Wrapper_add_local(w, r, tm); - Delete(tm); - Delete(r); - } - - String *args = NewString(""); - - p = parms; - while (p) { - while (checkAttribute(p, "tmap:directorin:numinputs", "0")) { - p = Getattr(p, "tmap:directorin:next"); - } - - String *pn = NewString("swig_"); - Append(pn, Getattr(p, "lname")); - Setattr(p, "emit:directorinput", pn); - - String *tm = gcCTypeForGoValue(p, Getattr(p, "type"), pn); - Wrapper_add_local(w, pn, tm); - Delete(tm); - - tm = Getattr(p, "tmap:directorin"); - if (!tm) { - Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, - line_number, "Unable to use type %s as director method argument\n", SwigType_str(Getattr(p, "type"), 0)); - } else { - tm = Copy(tm); - Replaceall(tm, "$input", pn); - Replaceall(tm, "$owner", 0); - Printv(w->code, " ", tm, "\n", NULL); - Delete(tm); - - Printv(args, ", ", pn, NULL); - } - - p = Getattr(p, "tmap:directorin:next"); - } - - Printv(w->code, " ", NULL); - if (SwigType_type(result) != T_VOID) { - Printv(w->code, Swig_cresult_name(), " = ", NULL); - } - Printv(w->code, callback_name, "(go_val", args, ");\n", NULL); - - /* Marshal outputs */ - for (p = parms; p; ) { - String *tm; - if ((tm = Getattr(p, "tmap:directorargout"))) { - tm = Copy(tm); - Replaceall(tm, "$result", "jresult"); - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NULL); - Delete(tm); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } - } - - if (SwigType_type(result) != T_VOID) { - String *result_str = NewString("c_result"); - String *tm = Swig_typemap_lookup("directorout", n, result_str, NULL); - if (!tm) { - Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, - "Unable to use type %s as director method result\n", SwigType_str(result, 0)); - } else { - tm = Copy(tm); - Replaceall(tm, "$input", Swig_cresult_name()); - Replaceall(tm, "$result", "c_result"); - Printv(w->code, " ", tm, "\n", NULL); - String *retstr = SwigType_rcaststr(result, "c_result"); - Printv(w->code, " return ", retstr, ";\n", NULL); - Delete(retstr); - Delete(tm); - } - Delete(result_str); - } - } - - - /* ------------------------------------------------------------ - * classDirectorEnd - * - * Complete support for a director class. - * ------------------------------------------------------------ */ - - int classDirectorEnd(Node *n) { - (void) n; - - Printv(f_c_directors_h, " private:\n", NULL); - Printv(f_c_directors_h, " intgo go_val;\n", NULL); - Printv(f_c_directors_h, " Swig_memory *swig_mem;\n", NULL); - Printv(f_c_directors_h, "};\n\n", NULL); - - class_name = NULL; - class_node = NULL; - - Delete(class_receiver); - class_receiver = NULL; - - Delete(class_methods); - class_methods = NULL; - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * classDirectorDisown - * - * I think Go does not require a disown method. - * ------------------------------------------------------------ */ - - int classDirectorDisown(Node *n) { - (void) n; - return SWIG_OK; - } - - /*---------------------------------------------------------------------- - * buildThrow() - * - * Build and return a throw clause if needed. - *--------------------------------------------------------------------*/ - - String *buildThrow(Node *n) { - if (Getattr(n, "noexcept")) - return NewString("noexcept"); - ParmList *throw_parm_list = Getattr(n, "throws"); - if (!throw_parm_list && !Getattr(n, "throw")) - return NULL; - String *ret = NewString("throw("); - if (throw_parm_list) { - Swig_typemap_attach_parms("throws", throw_parm_list, NULL); - } - bool first = true; - for (Parm *p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - if (first) { - first = false; - } else { - Printv(ret, ", ", NULL); - } - String *s = SwigType_str(Getattr(p, "type"), 0); - Printv(ret, s, NULL); - Delete(s); - } - } - Printv(ret, ")", NULL); - return ret; - } - - /*---------------------------------------------------------------------- - * extraDirectorProtectedCPPMethodsRequired() - * - * We don't need to check upcall when calling methods. - *--------------------------------------------------------------------*/ - - bool extraDirectorProtectedCPPMethodsRequired() const { - return false; - } - - /*---------------------------------------------------------------------- - * makeDispatchFunction - * - * Make a dispatch function for an overloaded C++ function. The - * receiver parameter is the receiver for a method, unless is_upcall - * is true. If is_upcall is true, then the receiver parameter is - * the type of the first argument to the function. - *--------------------------------------------------------------------*/ - - int makeDispatchFunction(Node *n, String *go_name, String *receiver, bool is_static, SwigType *director_struct, bool is_upcall) { - bool is_director = director_struct ? true : false; - - String *nodetype = Getattr(n, "nodeType"); - bool is_constructor = Cmp(nodetype, "constructor") == 0; - bool is_destructor = Cmp(nodetype, "destructor") == 0; - - bool can_use_receiver = (!is_constructor && !is_destructor && !is_upcall); - - bool use_receiver = (!is_static && can_use_receiver); - - bool add_to_interface = (interfaces && !is_constructor && !is_destructor && !is_static && !is_upcall); - - List *dispatch = Swig_overload_rank(n, false); - int nfunc = Len(dispatch); - - SwigType *all_result; - bool mismatch; - if (is_constructor) { - assert(!is_upcall); - if (!is_director) { - all_result = Copy(Getattr(class_node, "classtypeobj")); - } else { - all_result = Copy(director_struct); - } - mismatch = false; - } else { - all_result = NULL; - mismatch = false; - bool any_void = false; - for (int i = 0; i < nfunc; ++i) { - Node *nn = Getitem(dispatch, i); - Node *ni = Getattr(nn, "directorNode") ? Getattr(nn, "directorNode") : nn; - SwigType *result = Getattr(ni, "go:type"); - assert(result); - - if (SwigType_type(result) == T_VOID) { - if (all_result) { - mismatch = true; - } - any_void = true; - } else { - if (any_void) { - mismatch = true; - } else if (!all_result) { - all_result = Copy(result); - } else if (Cmp(result, all_result) != 0) { - mismatch = true; - } - } - } - if (mismatch) { - Delete(all_result); - all_result = NULL; - } else if (all_result) { - ; - } else { - all_result = NewString("void"); - } - } - - Printv(f_go_wrappers, "func ", NULL); - - if (receiver && use_receiver) { - Printv(f_go_wrappers, "(p ", receiver, ") ", NULL); - } - - Printv(f_go_wrappers, go_name, "(", NULL); - if (is_director && is_constructor) { - Printv(f_go_wrappers, "abi interface{}, ", NULL); - assert(!add_to_interface); - } - if (is_upcall) { - Printv(f_go_wrappers, "p *", receiver, ", ", NULL); - assert(!add_to_interface); - } - Printv(f_go_wrappers, "a ...interface{})", NULL); - - if (add_to_interface) { - Printv(interfaces, "\t", go_name, "(a ...interface{})", NULL); - } - - if (mismatch) { - Printv(f_go_wrappers, " interface{}", NULL); - if (add_to_interface) { - Printv(interfaces, " interface{}", NULL); - } - } else if (all_result && SwigType_type(all_result) != T_VOID) { - if (is_director && is_constructor) { - Printv(f_go_wrappers, " ", receiver, NULL); - if (add_to_interface) { - Printv(interfaces, " ", receiver, NULL); - } - } else { - String *tm = goType(n, all_result); - Printv(f_go_wrappers, " ", tm, NULL); - if (add_to_interface) { - Printv(interfaces, " ", tm, NULL); - } - Delete(tm); - } - } - Printv(f_go_wrappers, " {\n", NULL); - if (add_to_interface) { - Printv(interfaces, "\n", NULL); - } - - Printv(f_go_wrappers, "\targc := len(a)\n", NULL); - - for (int i = 0; i < nfunc; ++i) { - int fn = 0; - Node *nn = Getitem(dispatch, i); - Node *ni = Getattr(nn, "directorNode") ? Getattr(nn, "directorNode") : nn; - Parm *pi = Getattr(ni, "wrap:parms"); - - // If we are using a receiver, we want to ignore a leading self - // parameter. Because of the way this is called, there may or - // may not be a self parameter at this point. - if (use_receiver && pi && Getattr(pi, "self")) { - pi = getParm(pi); - if (pi) { - pi = nextParm(pi); - } - } - - int num_required = emit_num_required(pi); - int num_arguments = emit_num_arguments(pi); - bool varargs = emit_isvarargs(pi) ? true : false; - - if (varargs) { - Printf(f_go_wrappers, "\tif argc >= %d {\n", num_required); - } else { - if (num_required == num_arguments) { - Printf(f_go_wrappers, "\tif argc == %d {\n", num_required); - } else { - Printf(f_go_wrappers, "\tif argc >= %d && argc <= %d {\n", num_required, num_arguments); - } - } - - // Build list of collisions with the same number of arguments. - List *coll = NewList(); - for (int k = i + 1; k < nfunc; ++k) { - Node *nnk = Getitem(dispatch, k); - Node *nk = Getattr(nnk, "directorNode") ? Getattr(nnk, "directorNode") : nnk; - Parm *pk = Getattr(nk, "wrap:parms"); - if (use_receiver && pk && Getattr(pk, "self")) { - pk = getParm(pk); - if (pk) { - pk = nextParm(pk); - } - } - int nrk = emit_num_required(pk); - int nak = emit_num_arguments(pk); - if ((nrk >= num_required && nrk <= num_arguments) - || (nak >= num_required && nak <= num_arguments) - || (nrk <= num_required && nak >= num_arguments) - || (varargs && nrk >= num_required)) { - Append(coll, nk); - } - } - - int num_braces = 0; - if (Len(coll) > 0 && num_arguments > 0) { - int j = 0; - Parm *pj = pi; - while (pj) { - pj = getParm(pj); - if (!pj) { - break; - } - - // If all the overloads have the same type in this position, - // we can omit the check. - SwigType *tm = goOverloadType(pj, Getattr(pj, "type")); - bool emitcheck = false; - for (int k = 0; k < Len(coll) && !emitcheck; ++k) { - Node *nk = Getitem(coll, k); - Parm *pk = Getattr(nk, "wrap:parms"); - if (use_receiver && pk && Getattr(pk, "self")) { - pk = getParm(pk); - if (pk) { - pk = nextParm(pk); - } - } - int nak = emit_num_arguments(pk); - if (nak <= j) - continue; - int l = 0; - Parm *pl = pk; - while (pl && l <= j) { - pl = getParm(pl); - if (!pl) { - break; - } - if (l == j) { - SwigType *tml = goOverloadType(pl, Getattr(pl, "type")); - if (Cmp(tm, tml) != 0) { - emitcheck = true; - } - Delete(tml); - } - pl = nextParm(pl); - ++l; - } - } - - if (emitcheck) { - if (j >= num_required) { - Printf(f_go_wrappers, "\t\tif argc > %d {\n", j); - ++num_braces; - } - - fn = i + 1; - Printf(f_go_wrappers, "\t\tif _, ok := a[%d].(%s); !ok {\n", j, tm); - Printf(f_go_wrappers, "\t\t\tgoto check_%d\n", fn); - Printv(f_go_wrappers, "\t\t}\n", NULL); - } - - Delete(tm); - - pj = nextParm(pj); - - ++j; - } - } - - for (; num_braces > 0; --num_braces) { - Printv(f_go_wrappers, "\t\t}\n", NULL); - } - - // We may need to generate multiple calls if there are variable - // argument lists involved. Build the start of the call. - - String *start = NewString(""); - - SwigType *result = Getattr(ni, "go:type"); - - if (is_constructor) { - result = all_result; - } else if (is_destructor) { - result = NULL; - } - - if (result && SwigType_type(result) != T_VOID && (!all_result || SwigType_type(all_result) != T_VOID)) { - Printv(start, "return ", NULL); - } - - bool advance_parm = false; - - if (receiver && use_receiver) { - Printv(start, "p.", go_name, NULL); - } else if (can_use_receiver && !isStatic(ni) && pi && Getattr(pi, "self")) { - // This is an overload of a static function and a non-static - // function. - assert(num_required > 0); - SwigType *tm = goWrapperType(pi, Getattr(pi, "type"), true); - String *nm = buildGoName(Getattr(ni, "sym:name"), false, isFriend(ni)); - Printv(start, "a[0].(", tm, ").", nm, NULL); - Delete(nm); - Delete(tm); - advance_parm = true; - } else { - Printv(start, go_name, NULL); - } - - Printv(start, Getattr(ni, "sym:overname"), "(", NULL); - - bool need_comma = false; - - if (is_director && is_constructor) { - Printv(start, "abi", NULL); - need_comma = true; - } - if (is_upcall) { - Printv(start, "p", NULL); - need_comma = true; - } - Parm *p = pi; - int pn = 0; - if (advance_parm) { - p = getParm(p); - if (p) { - p = nextParm(p); - } - ++pn; - } - while (pn < num_required) { - p = getParm(p); - - if (need_comma) { - Printv(start, ", ", NULL); - } - - SwigType *tm = goType(p, Getattr(p, "type")); - Printf(start, "a[%d].(%s)", pn, tm); - Delete(tm); - - need_comma = true; - ++pn; - p = nextParm(p); - } - - String *end = NULL; - if (!result || SwigType_type(result) == T_VOID || (all_result && SwigType_type(all_result) == T_VOID)) { - end = NewString(""); - Printv(end, "return", NULL); - if (!all_result || SwigType_type(all_result) != T_VOID) { - Printv(end, " 0", NULL); - } - } - - if (num_required == num_arguments) { - Printv(f_go_wrappers, "\t\t", start, ")\n", NULL); - if (end) { - Printv(f_go_wrappers, "\t\t", end, "\n", NULL); - } - } else { - Printv(f_go_wrappers, "\t\tswitch argc {\n", NULL); - for (int j = num_required; j <= num_arguments; ++j) { - Printf(f_go_wrappers, "\t\tcase %d:\n", j); - Printv(f_go_wrappers, "\t\t\t", start, NULL); - bool nc = need_comma; - for (int k = num_required; k < j; ++k) { - if (nc) { - Printv(f_go_wrappers, ", ", NULL); - } - Printf(f_go_wrappers, "a[%d]", k); - nc = true; - } - Printv(f_go_wrappers, ")\n", NULL); - if (end) { - Printv(f_go_wrappers, "\t\t\t", end, "\n", NULL); - } - } - Printv(f_go_wrappers, "\t\t}\n", NULL); - } - - Printv(f_go_wrappers, "\t}\n", NULL); - - if (fn != 0) { - Printf(f_go_wrappers, "check_%d:\n", fn); - } - - Delete(coll); - } - - Printv(f_go_wrappers, "\tpanic(\"No match for overloaded function call\")\n", NULL); - Printv(f_go_wrappers, "}\n\n", NULL); - - Delete(all_result); - Delete(dispatch); - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * checkFunctionVisibility() - * - * Return true if we should write out a function based on its - * visibility, false otherwise. - * ---------------------------------------------------------------------- */ - - bool checkFunctionVisibility(Node *n, Node *parent) { - // Write out a public function. - if (is_public(n)) - return true; - // Don't write out a private function. - if (is_private(n)) - return false; - // Write a protected function for a director class in - // dirprot_mode. - if (parent == NULL) { - return false; - } - if (dirprot_mode() && Swig_directorclass(parent)) - return true; - // Otherwise don't write out a protected function. - return false; - } - - - /* ---------------------------------------------------------------------- - * exportedName() - * - * Given a C/C++ name, return a name in Go which will be exported. - * If the first character is an upper case letter, this returns a - * copy of its argument. If the first character is a lower case - * letter, this forces it to upper case. Otherwise, this prepends - * 'X'. - * ---------------------------------------------------------------------- */ - - String *exportedName(String *name) { - String *copy = Copy(name); - char c = *Char(copy); - if (islower(c)) { - char l[2]; - char u[2]; - l[0] = c; - l[1] = '\0'; - u[0] = toupper(c); - u[1] = '\0'; - Replace(copy, l, u, DOH_REPLACE_FIRST); - } else if (!isalpha(c)) { - char l[2]; - char u[3]; - l[0] = c; - l[1] = '\0'; - u[0] = 'X'; - u[1] = c; - u[2] = '\0'; - Replace(copy, l, u, DOH_REPLACE_FIRST); - } - String *ret = Swig_name_mangle(copy); - Delete(copy); - return ret; - } - - /* ---------------------------------------------------------------------- - * removeClassname() - * - * If the name starts with the current class name, followed by an - * underscore, remove it. If there is no current class name, this - * simply returns a copy of the name. This undoes Swig's way of - * recording the class name in a member name. - * ---------------------------------------------------------------------- */ - - String *removeClassname(String *name) { - String *copy = Copy(name); - if (class_name) { - char *p = Char(name); - if (Strncmp(name, class_name, Len(class_name)) == 0 && p[Len(class_name)] == '_') { - Replace(copy, class_name, "", DOH_REPLACE_FIRST); - Replace(copy, "_", "", DOH_REPLACE_FIRST); - } - } - return copy; - } - - /* ---------------------------------------------------------------------- - * buildGoName() - * - * Build the name to use for an ordinary function, variable, or - * whatever in Go. The name argument is something like the sym:name - * attribute of the node. If is_static is false, this could be a - * method, and the returned name will be the name of the - * method--i.e., it will not include the class name. - * ---------------------------------------------------------------------- */ - - String *buildGoName(String *name, bool is_static, bool is_friend) { - String *nw = NewString(""); - if (is_static && !is_friend && class_name) { - String *c1 = exportedName(class_name); - Append(nw, c1); - Delete(c1); - } - String *c2 = removeClassname(name); - String *c3 = exportedName(c2); - Append(nw, c3); - Delete(c2); - Delete(c3); - String *ret = Swig_name_mangle(nw); - Delete(nw); - return ret; - } - - /* ---------------------------------------------------------------------- - * buildGoWrapperName() - * - * Build the name to use for a Go wrapper function. This is a - * function called by the real Go function in order to convert C++ - * classes from interfaces to pointers, and other such conversions - * between the Go type and the C++ type. - * ---------------------------------------------------------------------- */ - - String *buildGoWrapperName(String *name, String *overname) { - String *s1 = NewString("_swig_wrap_"); - Append(s1, name); - String *s2 = Swig_name_mangle(s1); - Delete(s1); - if (overname) { - Append(s2, overname); - } - return s2; - } - - /* ---------------------------------------------------------------------- - * checkNameConflict() - * - * Check for a name conflict on the name we are going to use in Go. - * These conflicts are likely because of the enforced - * capitalization. When we find one, issue a warning and return - * false. If the name is OK, return true. - * ---------------------------------------------------------------------- */ - - bool checkNameConflict(String* name, Node* n, const_String_or_char_ptr scope) { - Node *lk = symbolLookup(name, scope); - if (lk) { - String *n1 = Getattr(n, "sym:name"); - if (!n1) { - n1 = Getattr(n, "name"); - } - String *n2 = Getattr(lk, "sym:name"); - if (!n2) { - n2 = Getattr(lk, "name"); - } - Swig_warning(WARN_GO_NAME_CONFLICT, input_file, line_number, - "Ignoring '%s' due to Go name ('%s') conflict with '%s'\n", - n1, name, n2); - return false; - } - bool r = addSymbol(name, n, scope) ? true : false; - assert(r); - (void)r; - return true; - } - - /* ---------------------------------------------------------------------- - * checkIgnoredParameters() - * - * If any of the parameters of this function, or the return type, - * are ignored due to a name conflict, give a warning and return - * false. - * ---------------------------------------------------------------------- */ - - bool checkIgnoredParameters(Node *n, String *go_name) { - ParmList *parms = Getattr(n, "parms"); - if (parms) { - Wrapper *dummy = NewWrapper(); - emit_attach_parmmaps(parms, dummy); - int parm_count = emit_num_arguments(parms); - Parm *p = parms; - - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - if (!checkIgnoredType(n, go_name, Getattr(p, "type"))) { - DelWrapper(dummy); - return false; - } - p = nextParm(p); - } - - DelWrapper(dummy); - } - - if (!checkIgnoredType(n, go_name, Getattr(n, "type"))) { - return false; - } - - return true; - } - - /* ---------------------------------------------------------------------- - * checkIgnoredType() - * - * If this type is being ignored due to a name conflict, give a - * warning and return false. - * ---------------------------------------------------------------------- */ - - bool checkIgnoredType(Node *n, String *go_name, SwigType *type) { - if (hasGoTypemap(n, type)) { - return true; - } - - SwigType *t = SwigType_typedef_resolve_all(type); - - bool ret = true; - bool is_conflict = false; - Node *e = Language::enumLookup(t); - if (e) { - if (GetFlag(e, "go:conflict")) { - is_conflict = true; - } - } else if (SwigType_issimple(t)) { - Node *cn = classLookup(t); - if (cn) { - if (GetFlag(cn, "go:conflict")) { - is_conflict = true; - } - } - } else if (SwigType_ispointer(t) || SwigType_isarray(t) || SwigType_isqualifier(t) || SwigType_isreference(t)) { - SwigType *r = Copy(t); - if (SwigType_ispointer(r)) { - SwigType_del_pointer(r); - } else if (SwigType_isarray(r)) { - SwigType_del_array(r); - } else if (SwigType_isqualifier(r)) { - SwigType_del_qualifier(r); - } else { - SwigType_del_reference(r); - } - - if (!checkIgnoredType(n, go_name, r)) { - ret = false; - } - - Delete(r); - } - - if (is_conflict) { - String *s = SwigType_str(t, NULL); - Swig_warning(WARN_GO_NAME_CONFLICT, input_file, line_number, - "Ignoring '%s' (Go name '%s') due to Go name conflict for parameter or result type '%s'\n", - Getattr(n, "name"), go_name, s); - Delete(s); - ret = false; - } - - Delete(t); - - return ret; - } - - /* ---------------------------------------------------------------------- - * goType() - * - * Given a SWIG type, return a string for the type in Go. - * ---------------------------------------------------------------------- */ - - String *goType(Node *n, SwigType *type) { - return goTypeWithInfo(n, type, false, NULL); - } - - /* ---------------------------------------------------------------------- - * goImType() - * - * Given a SWIG type, return a string for the intermediate Go type - * to pass to C/C++. This is like goType except that it looks for - * an imtype typemap entry first. - * ---------------------------------------------------------------------- */ - - String *goImType(Node *n, SwigType *type) { - return goTypeWithInfo(n, type, true, NULL); - } - - /* ---------------------------------------------------------------------- - * goTypeWithInfo() - * - * Like goType, but return some more information. - * - * If use_imtype is true, this look for a imtype typemap entry. - * - * If the p_is_interface parameter is not NULL, this sets - * *p_is_interface to indicate whether this type is going to be - * represented by a Go interface type. These are cases where the Go - * code needs to make some adjustments when passing values back and - * forth with C/C++. - * ---------------------------------------------------------------------- */ - - String *goTypeWithInfo(Node *n, SwigType *type, bool use_imtype, bool *p_is_interface) { - if (p_is_interface) { - *p_is_interface = false; - } - - String *ret = NULL; - if (use_imtype) { - if (n && Cmp(type, Getattr(n, "type")) == 0) { - if (Strcmp(Getattr(n, "nodeType"), "parm") == 0) { - ret = Getattr(n, "tmap:imtype"); - } - if (!ret) { - ret = Swig_typemap_lookup("imtype", n, "", NULL); - } - } else { - Parm *p = NewParm(type, "goImType", n); - ret = Swig_typemap_lookup("imtype", p, "", NULL); - Delete(p); - } - } - if (!ret) { - if (n && Cmp(type, Getattr(n, "type")) == 0) { - if (Strcmp(Getattr(n, "nodeType"), "parm") == 0) { - ret = Getattr(n, "tmap:gotype"); - } - if (!ret) { - ret = Swig_typemap_lookup("gotype", n, "", NULL); - } - } else { - Parm *p = NewParm(type, "goType", n); - ret = Swig_typemap_lookup("gotype", p, "", NULL); - Delete(p); - } - } - - if (ret && Strstr(ret, "$gotypename") != 0) { - ret = NULL; - } - - if (ret) { - return Copy(ret); - } - - SwigType *t = SwigType_typedef_resolve_all(type); - - if (SwigType_isenum(t)) { - Node *e = Language::enumLookup(t); - if (e) { - ret = goEnumName(e); - } else if (Strcmp(t, "enum ") == 0) { - ret = NewString("int"); - } else { - // An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition) or an ignored enum - String *tt = Copy(t); - Replace(tt, "enum ", "", DOH_REPLACE_ANY); - ret = exportedName(tt); - Setattr(undefined_enum_types, t, ret); - Delete(tt); - } - } else if (SwigType_isfunctionpointer(t) || SwigType_isfunction(t)) { - ret = NewString("_swig_fnptr"); - } else if (SwigType_ismemberpointer(t)) { - ret = NewString("_swig_memberptr"); - } else if (SwigType_issimple(t)) { - Node *cn = classLookup(t); - if (cn) { - ret = Getattr(cn, "sym:name"); - if (!ret) { - ret = Getattr(cn, "name"); - } - ret = exportedName(ret); - - Node *cnmod = Getattr(cn, "module"); - if (!cnmod || Strcmp(Getattr(cnmod, "name"), module) == 0) { - Setattr(undefined_types, t, t); - } else { - String *nw = NewString(""); - Printv(nw, getModuleName(Getattr(cnmod, "name")), ".", ret, NULL); - Delete(ret); - ret = nw; - } - } else { - // SWIG does not know about this type. - ret = exportedName(t); - Setattr(undefined_types, t, t); - } - if (p_is_interface) { - *p_is_interface = true; - } - } else if (SwigType_ispointer(t) || SwigType_isarray(t)) { - SwigType *r = Copy(t); - if (SwigType_ispointer(r)) { - SwigType_del_pointer(r); - } else { - SwigType_del_array(r); - } - - if (SwigType_type(r) == T_VOID) { - ret = NewString("uintptr"); - } else { - bool is_interface; - String *base = goTypeWithInfo(n, r, false, &is_interface); - - // At the Go level, an unknown or class type is handled as an - // interface wrapping a pointer. This means that if a - // function returns the C type X, we will be wrapping the C - // type X*. In Go we will call that type X. That means that - // if a C function expects X*, we can pass the Go type X. And - // that means that when we see the C type X*, we should use - // the Go type X. - - // The is_interface variable tells us this. However, it will - // be true both for the case of X and for the case of X*. If - // r is a pointer here, then we are looking at X**. There is - // really no good way for us to handle that. - bool is_pointer_to_pointer = false; - if (is_interface) { - SwigType *c = Copy(r); - if (SwigType_isqualifier(c)) { - SwigType_del_qualifier(c); - if (SwigType_ispointer(c) || SwigType_isarray(c)) { - is_pointer_to_pointer = true; - } - } - Delete(c); - } - - if (is_interface) { - if (!is_pointer_to_pointer) { - ret = base; - if (p_is_interface) { - *p_is_interface = true; - } - } else { - ret = NewString("uintptr"); - } - } else { - ret = NewString("*"); - Append(ret, base); - Delete(base); - } - } - - Delete(r); - } else if (SwigType_isreference(t)) { - SwigType *r = Copy(t); - SwigType_del_reference(r); - - // If this is a const reference, and we are looking at a pointer - // to it, then we just use the pointer we already have. - bool add_pointer = true; - if (SwigType_isqualifier(r)) { - String *q = SwigType_parm(r); - if (Strcmp(q, "const") == 0) { - SwigType *c = Copy(r); - SwigType_del_qualifier(c); - if (SwigType_ispointer(c)) { - add_pointer = false; - } - Delete(c); - } - } - if (add_pointer) { - SwigType_add_pointer(r); - } - ret = goTypeWithInfo(n, r, false, p_is_interface); - Delete(r); - } else if (SwigType_isqualifier(t)) { - SwigType *r = Copy(t); - SwigType_del_qualifier(r); - ret = goTypeWithInfo(n, r, false, p_is_interface); - Delete(r); - } else if (SwigType_isvarargs(t)) { - ret = NewString("[]interface{}"); - } - - Delete(t); - - if (!ret) { - Swig_warning(WARN_LANG_NATIVE_UNIMPL, input_file, line_number, "No Go typemap defined for %s\n", SwigType_str(type, 0)); - ret = NewString("uintptr"); - } - - return ret; - } - - /* ---------------------------------------------------------------------- - * cgoTypeForGoValue() - * - * Given a SWIG type, return a string for the C type to use for the - * cgo wrapper code. This always returns a simple identifier, since - * it is used in Go code as C.name. - * - * This sets *c_struct_type if the C type uses a struct where the Go - * type uses a simple type. This is true for strings and slices. - * When this is true the Go code has to jump through unsafe hoops to - * pass the type checker. - * ---------------------------------------------------------------------- */ - - String *cgoTypeForGoValue(Node *n, SwigType *type, bool *c_struct_type) { - *c_struct_type = false; - - bool is_interface; - String *go_type = goTypeWithInfo(n, type, true, &is_interface); - if (is_interface) { - Delete(go_type); - return NewString("uintptr_t"); - } - if (Strcmp(go_type, "uintptr") == 0) { - Delete(go_type); - return NewString("uintptr_t"); - } - if (((char*)Char(go_type))[0] == '*') { - // Treat all pointers as void*. There is no meaningful type - // checking going on here anyhow, and that lets us avoid - // worrying about defining the base type of the pointer. - Delete(go_type); - return NewString("swig_voidp"); - } - - // Check for some Go types that are really pointers under the covers. - bool is_hidden_pointer = Strncmp(go_type, "func(", 5) == 0 || Strncmp(go_type, "map[", 4) == 0 || Strncmp(go_type, "chan ", 5) == 0; - - Delete(go_type); - - String *ct = Getattr(n, "emit:cgotype"); - if (ct) { - *c_struct_type = Getattr(n, "emit:cgotypestruct") ? true : false; - return Copy(ct); - } - - String *t = Copy(type); - if (SwigType_isarray(t) && Getattr(n, "tmap:gotype") == NULL) { - SwigType_del_array(t); - SwigType_add_pointer(t); - } - - bool add_typedef = true; - - static int count; - ++count; - ct = NewStringf("swig_type_%d", count); - - String *gct = gcCTypeForGoValue(n, t, ct); - Delete(t); - - if (Strncmp(gct, "_gostring_", 10) == 0 || Strncmp(gct, "_goslice_", 9) == 0) { - *c_struct_type = true; - Setattr(n, "emit:cgotypestruct", type); - } else { - char *p = Strstr(gct, ct); - if (p != NULL && p > (char*)Char(gct) && p[-1] == '*' && p[Len(ct)] == '\0') { - // Treat all pointers as void*. See above. - Delete(ct); - --count; - ct = NewString("swig_voidp"); - add_typedef = false; - if (is_hidden_pointer) { - // A Go type that is really a pointer, like func, map, chan, - // is being represented in C by a pointer. This is fine, - // but we have to memcpy the type rather than simply - // converting it. - *c_struct_type = true; - Setattr(n, "emit:cgotypestruct", type); - } - } - - if (Strncmp(gct, "bool ", 5) == 0) { - // Change the C++ type bool to the C type _Bool. - Replace(gct, "bool", "_Bool", DOH_REPLACE_FIRST); - } - if (Strncmp(gct, "intgo ", 6) == 0) { - // We #define intgo to swig_intgo for the cgo comment. - Replace(gct, "intgo", "swig_intgo", DOH_REPLACE_FIRST); - } - p = Strstr(gct, ct); - if (p != NULL && p > (char*)Char(gct) && p[-1] == ' ' && p[Len(ct)] == '\0') { - String *q = NewStringWithSize(gct, Len(gct) - Len(ct) - 1); - if (validIdentifier(q)) { - // This is a simple type name, and we can use it directly. - Delete(ct); - --count; - ct = q; - add_typedef = false; - } - } - } - if (add_typedef) { - Printv(f_cgo_comment_typedefs, "typedef ", gct, ";\n", NULL); - } - - Setattr(n, "emit:cgotype", ct); - - Delete(gct); - - return Copy(ct); - } - - /* ---------------------------------------------------------------------- - * goWrapperType() - * - * Given a type, return a string for the type to use for the wrapped - * Go function. This function exists because for a C++ class we - * need to convert interface and reference types. - * ---------------------------------------------------------------------- */ - - String *goWrapperType(Node *n, SwigType *type, bool is_result) { - bool is_interface; - String *ret = goTypeWithInfo(n, type, true, &is_interface); - - // If this is an interface, we want to pass the real type. - if (is_interface) { - Delete(ret); - if (!is_result) { - ret = NewString("uintptr"); - } else { - SwigType *ty = SwigType_typedef_resolve_all(type); - while (true) { - if (SwigType_ispointer(ty)) { - SwigType_del_pointer(ty); - } else if (SwigType_isarray(ty)) { - SwigType_del_array(ty); - } else if (SwigType_isreference(ty)) { - SwigType_del_reference(ty); - } else if (SwigType_isqualifier(ty)) { - SwigType_del_qualifier(ty); - } else { - break; - } - } - assert(SwigType_issimple(ty)); - String *p = goCPointerType(ty, true); - Delete(ty); - ret = p; - } - } - - return ret; - } - - /* ---------------------------------------------------------------------- - * goOverloadType() - * - * Given a type, return the Go type to use when dispatching of - * overloaded functions. This is normally just the usual Go type. - * However, for a C++ class, the usual Go type is an interface type. - * And if that interface type represents a C++ type that SWIG does - * not know about, then the interface type generated for any C++ - * class will match that interface. So for that case, we match on - * the underlying integer type. - * - * It has to work this way so that we can handle a derived type of a - * %ignore'd type. It's unlikely that anybody will have a value of - * an undefined type, but we support it because it worked in the - * past. - * ---------------------------------------------------------------------- */ - - String *goOverloadType(Node *n, SwigType *type) { - SwigType *ty = SwigType_typedef_resolve_all(type); - while (true) { - if (SwigType_ispointer(ty)) { - SwigType_del_pointer(ty); - } else if (SwigType_isarray(ty)) { - SwigType_del_array(ty); - } else if (SwigType_isreference(ty)) { - SwigType_del_reference(ty); - } else if (SwigType_isqualifier(ty)) { - SwigType_del_qualifier(ty); - } else { - break; - } - } - - String* go_type = goType(n, ty); - - if (Getattr(undefined_types, ty) && !Getattr(defined_types, go_type)) { - Delete(go_type); - return goWrapperType(n, type, true); - } - - Delete(go_type); - return goType(n, type); - } - - /* ---------------------------------------------------------------------- - * goCPointerType() - * - * Return the name of the Go type to use for the C pointer value. - * The regular C type is the name of an interface type which wraps a - * pointer whose name is returned by this function. - * ---------------------------------------------------------------------- */ - - String *goCPointerType(SwigType *type, bool add_to_hash) { - SwigType *ty = SwigType_typedef_resolve_all(type); - Node *cn = classLookup(ty); - String *ex; - String *ret; - if (!cn) { - if (add_to_hash) { - Setattr(undefined_types, ty, ty); - } - ret = NewString("Swigcptr"); - ex = exportedName(ty); - Append(ret, ex); - } else { - String *cname = Getattr(cn, "sym:name"); - if (!cname) { - cname = Getattr(cn, "name"); - } - ex = exportedName(cname); - Node *cnmod = Getattr(cn, "module"); - if (!cnmod || Strcmp(Getattr(cnmod, "name"), module) == 0) { - if (add_to_hash) { - Setattr(undefined_types, ty, ty); - } - ret = NewString("Swigcptr"); - Append(ret, ex); - } else { - ret = NewString(""); - Printv(ret, getModuleName(Getattr(cnmod, "name")), ".Swigcptr", ex, NULL); - } - } - Delete(ty); - Delete(ex); - return ret; - } - - /* ---------------------------------------------------------------------- - * gcCTypeForGoValue() - * - * Given a type, return the C/C++ type which will be used to catch - * the value in Go. This is the gc version. - * ---------------------------------------------------------------------- */ - - String *gcCTypeForGoValue(Node *n, SwigType *type, String *name) { - bool is_interface; - String *gt = goTypeWithInfo(n, type, true, &is_interface); - - String *tail = NewString(""); - SwigType *t = SwigType_typedef_resolve_all(type); - bool is_const_ref = false; - if (SwigType_isreference(t)) { - SwigType* tt = Copy(t); - SwigType_del_reference(tt); - if (SwigType_isqualifier(tt)) { - String* q = SwigType_parm(tt); - if (Strcmp(q, "const") == 0) { - is_const_ref = true; - } - } - Delete(tt); - } - if (!is_const_ref) { - while (Strncmp(gt, "*", 1) == 0) { - Replace(gt, "*", "", DOH_REPLACE_FIRST); - Printv(tail, "*", NULL); - } - } - Delete(t); - - bool is_string = Strcmp(gt, "string") == 0; - bool is_slice = Strncmp(gt, "[]", 2) == 0; - bool is_function = Strcmp(gt, "_swig_fnptr") == 0; - bool is_member = Strcmp(gt, "_swig_memberptr") == 0; - bool is_complex64 = Strcmp(gt, "complex64") == 0; - bool is_complex128 = Strcmp(gt, "complex128") == 0; - bool is_bool = false; - bool is_int8 = false; - bool is_int16 = false; - bool is_int = Strcmp(gt, "int") == 0 || Strcmp(gt, "uint") == 0; - bool is_int32 = false; - bool is_int64 = false; - bool is_float32 = false; - bool is_float64 = false; - - bool has_typemap = (n != NULL && Getattr(n, "tmap:gotype") != NULL) || hasGoTypemap(n, type); - if (has_typemap) { - is_bool = Strcmp(gt, "bool") == 0; - is_int8 = Strcmp(gt, "int8") == 0 || Strcmp(gt, "uint8") == 0 || Strcmp(gt, "byte") == 0; - is_int16 = Strcmp(gt, "int16") == 0 || Strcmp(gt, "uint16") == 0; - is_int32 = Strcmp(gt, "int32") == 0 || Strcmp(gt, "uint32") == 0; - is_int64 = Strcmp(gt, "int64") == 0 || Strcmp(gt, "uint64") == 0; - is_float32 = Strcmp(gt, "float32") == 0; - is_float64 = Strcmp(gt, "float64") == 0; - } - Delete(gt); - - String *ret; - if (is_string) { - // Note that we don't turn a reference to a string into a - // pointer to a string. Strings are immutable anyhow. - ret = NewString(""); - Printv(ret, "_gostring_", tail, " ", name, NULL); - Delete(tail); - return ret; - } else if (is_slice) { - // Slices are always passed as a _goslice_, whether or not references - // are involved. - ret = NewString(""); - Printv(ret, "_goslice_", tail, " ", name, NULL); - Delete(tail); - return ret; - } else if (is_function || is_member) { - ret = NewString(""); - Printv(ret, "void*", tail, " ", name, NULL); - Delete(tail); - return ret; - } else if (is_complex64) { - ret = NewString("_Complex float "); - } else if (is_complex128) { - ret = NewString("_Complex double "); - } else if (is_interface) { - SwigType *t = SwigType_typedef_resolve_all(type); - if (SwigType_ispointer(t)) { - SwigType_del_pointer(t); - } - if (SwigType_isreference(t)) { - SwigType_del_reference(t); - } - SwigType_add_pointer(t); - ret = SwigType_lstr(t, name); - Delete(t); - Delete(tail); - return ret; - } else { - SwigType *t = SwigType_typedef_resolve_all(type); - if (!has_typemap && SwigType_isreference(t)) { - // A const reference to a known type, or to a pointer, is not - // mapped to a pointer. - SwigType_del_reference(t); - if (SwigType_isqualifier(t)) { - String *q = SwigType_parm(t); - if (Strcmp(q, "const") == 0) { - SwigType_del_qualifier(t); - if (hasGoTypemap(n, t) || SwigType_ispointer(t)) { - if (is_int) { - ret = NewString("intgo "); - Append(ret, name); - } else if (is_int64) { - ret = NewString("long long "); - Append(ret, name); - } else { - ret = SwigType_lstr(t, name); - } - Delete(q); - Delete(t); - Delete(tail); - return ret; - } - } - Delete(q); - } - } - - if (Language::enumLookup(t) != NULL) { - is_int = true; - } else { - SwigType *tstripped = SwigType_strip_qualifiers(t); - if (SwigType_isenum(tstripped)) - is_int = true; - Delete(tstripped); - } - - Delete(t); - if (is_bool) { - ret = NewString("bool "); - } else if (is_int8) { - ret = NewString("char "); - } else if (is_int16) { - ret = NewString("short "); - } else if (is_int) { - ret = NewString("intgo "); - } else if (is_int32) { - ret = NewString("int "); - } else if (is_int64) { - ret = NewString("long long "); - } else if (is_float32) { - ret = NewString("float "); - } else if (is_float64) { - ret = NewString("double "); - } else { - Delete(tail); - return SwigType_lstr(type, name); - } - } - - Append(ret, tail); - if (!has_typemap && SwigType_isreference(type)) { - Append(ret, "* "); - } - Append(ret, name); - Delete(tail); - return ret; - } - - /* ---------------------------------------------------------------------- - * goTypeIsInterface - * - * Return whether this C++ type is represented as an interface type - * in Go. These types require adjustments in the Go code when - * passing them back and forth between Go and C++. - * ---------------------------------------------------------------------- */ - - bool goTypeIsInterface(Node *n, SwigType *type) { - bool is_interface; - Delete(goTypeWithInfo(n, type, false, &is_interface)); - return is_interface; - } - - /* ---------------------------------------------------------------------- - * hasGoTypemap - * - * Return whether a type has a "gotype" typemap entry. - * ---------------------------------------------------------------------- */ - - bool hasGoTypemap(Node *n, SwigType *type) { - Parm *p = NewParm(type, "test", n); - SwigType *tm = Swig_typemap_lookup("gotype", p, "", NULL); - Delete(p); - if (tm && Strstr(tm, "$gotypename") == 0) { - Delete(tm); - return true; - } - Delete(tm); - return false; - } - - /* ---------------------------------------------------------------------- - * goEnumName() - * - * Given an enum node, return a string to use for the enum type in Go. - * ---------------------------------------------------------------------- */ - - String *goEnumName(Node *n) { - String *ret = Getattr(n, "go:enumname"); - if (ret) { - return Copy(ret); - } - - if (Equal(Getattr(n, "type"), "enum ")) { - return NewString("int"); - } - - String *type = Getattr(n, "enumtype"); - assert(type); - char *p = Char(type); - int len = Len(type); - String *s = NewString(""); - bool capitalize = true; - for (int i = 0; i < len; ++i, ++p) { - if (*p == ':') { - ++i; - ++p; - assert(*p == ':'); - capitalize = true; - } else if (capitalize) { - Putc(toupper(*p), s); - capitalize = false; - } else { - Putc(*p, s); - } - } - - ret = Swig_name_mangle(s); - Delete(s); - return ret; - } - - - /* ---------------------------------------------------------------------- - * getParm() - * - * Get the real parameter to use. - * ---------------------------------------------------------------------- */ - - Parm *getParm(Parm *p) { - while (p && checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - return p; - } - - /* ---------------------------------------------------------------------- - * nextParm() - * - * Return the next parameter. - * ---------------------------------------------------------------------- */ - - Parm *nextParm(Parm *p) { - if (!p) { - return NULL; - } else if (Getattr(p, "tmap:in")) { - return Getattr(p, "tmap:in:next"); - } else { - return nextSibling(p); - } - } - - /* ---------------------------------------------------------------------- - * isStatic - * - * Return whether a node should be considered as static rather than - * as a member. - * ---------------------------------------------------------------------- */ - - bool isStatic(Node *n) { - String *storage = Getattr(n, "storage"); - return (storage && (Swig_storage_isstatic(n) || Strcmp(storage, "friend") == 0) && (!SmartPointer || !Getattr(n, "allocate:smartpointeraccess"))); - } - - /* ---------------------------------------------------------------------- - * isFriend - * - * Return whether a node is a friend. - * ---------------------------------------------------------------------- */ - - bool isFriend(Node *n) { - String *storage = Getattr(n, "storage"); - return storage && Strcmp(storage, "friend") == 0; - } - - /* ---------------------------------------------------------------------- - * goGetattr - * - * Fetch an attribute from a node but return NULL if it is the empty string. - * ---------------------------------------------------------------------- */ - Node *goGetattr(Node *n, const char *name) { - Node *ret = Getattr(n, name); - if (ret != NULL && Len(ret) == 0) { - ret = NULL; - } - return ret; - } - - /* ---------------------------------------------------------------------- - * goTypemapLookup - * - * Look up a typemap but return NULL if it is the empty string. - * ---------------------------------------------------------------------- */ - String *goTypemapLookup(const char *name, Node *node, const char *lname) { - String *ret = Swig_typemap_lookup(name, node, lname, NULL); - if (ret != NULL && Len(ret) == 0) { - ret = NULL; - } - return ret; - } - - /* ---------------------------------------------------------------------- - * getModuleName - * - * Return the name of a module. This is different from module path: - * "some/path/to/module" -> "module". - * ---------------------------------------------------------------------- */ - - String *getModuleName(String *module_path) { - char *suffix = strrchr(Char(module_path), '/'); - if (suffix == NULL) { - return module_path; - } - return Str(suffix + 1); - } - -}; /* class GO */ - -/* ----------------------------------------------------------------------------- - * swig_go() - Instantiate module - * ----------------------------------------------------------------------------- */ - -static Language *new_swig_go() { - return new GO(); -} -extern "C" Language *swig_go(void) { - return new_swig_go(); -} - -/* ----------------------------------------------------------------------------- - * Static member variables - * ----------------------------------------------------------------------------- */ - -// Usage message. -const char * const GO::usage = "\ -Go Options (available with -go)\n\ - -cgo - Generate cgo input files\n\ - -no-cgo - Do not generate cgo input files\n\ - -gccgo - Generate code for gccgo rather than gc\n\ - -go-pkgpath <p> - Like gccgo -fgo-pkgpath option\n\ - -go-prefix <p> - Like gccgo -fgo-prefix option\n\ - -import-prefix <p> - Prefix to add to %import directives\n\ - -intgosize <s> - Set size of Go int type--32 or 64 bits\n\ - -package <name> - Set name of the Go package to <name>\n\ - -use-shlib - Force use of a shared library\n\ - -soname <name> - Set shared library holding C/C++ code to <name>\n\ -\n"; diff --git a/contrib/tools/swig/Source/Modules/guile.cxx b/contrib/tools/swig/Source/Modules/guile.cxx deleted file mode 100644 index 605e0319758..00000000000 --- a/contrib/tools/swig/Source/Modules/guile.cxx +++ /dev/null @@ -1,1662 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * guile.cxx - * - * Guile language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include <ctype.h> - -// Note string broken in half for compilers that can't handle long strings -static const char *usage = "\ -Guile Options (available with -guile)\n\ - -emitsetters - Emit procedures-with-setters for variables\n\ - and structure slots.\n\ - -emitslotaccessors - Emit accessor methods for all GOOPS slots\n" "\ - -exportprimitive - Add the (export ...) code from scmstub into the\n\ - GOOPS file.\n\ - -goopsprefix <prefix> - Prepend <prefix> to all goops identifiers\n\ - -Linkage <lstyle> - Use linkage protocol <lstyle> (default `simple')\n\ - Use `module' for native Guile module linking\n\ - (requires Guile >= 1.5.0). Use `passive' for\n\ - passive linking (no C-level module-handling code),\n\ - `ltdlmod' for Guile's old dynamic module\n\ - convention (Guile <= 1.4), or `hobbit' for hobbit\n\ - modules.\n\ - -onlysetters - Don't emit traditional getter and setter\n\ - procedures for structure slots,\n\ - only emit procedures-with-setters.\n\ - -package <name> - Set the path of the module to <name>\n\ - (default NULL)\n\ - -prefix <name> - Use <name> as prefix [default \"gswig_\"]\n\ - -procdoc <file> - Output procedure documentation to <file>\n\ - -procdocformat <format> - Output procedure documentation in <format>;\n\ - one of `guile-1.4', `plain', `texinfo'\n\ - -proxy - Export GOOPS class definitions\n\ - -primsuffix <suffix> - Name appended to primitive module when exporting\n\ - GOOPS classes. (default = \"primitive\")\n\ - -scmstub - Output Scheme file with module declaration and\n\ - exports; only with `passive' and `simple' linkage\n\ - -useclassprefix - Prepend the class name to all goops identifiers\n\ -\n"; - -static File *f_begin = 0; -static File *f_runtime = 0; -static File *f_header = 0; -static File *f_wrappers = 0; -static File *f_init = 0; - - -static String *prefix = NewString("gswig_"); -static char *module = 0; -static String *package = 0; -static enum { - GUILE_LSTYLE_SIMPLE, // call `SWIG_init()' - GUILE_LSTYLE_PASSIVE, // passive linking (no module code) - GUILE_LSTYLE_MODULE, // native guile module linking (Guile >= 1.4.1) - GUILE_LSTYLE_LTDLMOD_1_4, // old (Guile <= 1.4) dynamic module convention - GUILE_LSTYLE_HOBBIT // use (hobbit4d link) -} linkage = GUILE_LSTYLE_SIMPLE; - -static File *procdoc = 0; -static bool scmstub = false; -static String *scmtext; -static bool goops = false; -static String *goopstext; -static String *goopscode; -static String *goopsexport; - -static enum { - GUILE_1_4, - PLAIN, - TEXINFO -} docformat = GUILE_1_4; - -static int emit_setters = 0; -static int only_setters = 0; -static int emit_slot_accessors = 0; -static int struct_member = 0; - -static String *beforereturn = 0; -static String *return_nothing_doc = 0; -static String *return_one_doc = 0; -static String *return_multi_doc = 0; - -static String *exported_symbols = 0; - -static int exporting_destructor = 0; -static String *swigtype_ptr = 0; - -/* GOOPS stuff */ -static String *primsuffix = 0; -static String *class_name = 0; -static String *short_class_name = 0; -static String *goops_class_methods; -static int in_class = 0; -static int have_constructor = 0; -static int useclassprefix = 0; // -useclassprefix argument -static String *goopsprefix = 0; // -goopsprefix argument -static int primRenamer = 0; // if (use-modules ((...) :renamer ...) is exported to GOOPS file -static int exportprimitive = 0; // -exportprimitive argument -static String *memberfunction_name = 0; - -extern "C" { - static int has_classname(Node *class_node) { - return Getattr(class_node, "guile:goopsclassname") ? 1 : 0; - } -} - -class GUILE:public Language { -public: - - /* ------------------------------------------------------------ - * main() - * ------------------------------------------------------------ */ - - virtual void main(int argc, char *argv[]) { - int i; - - SWIG_library_directory("guile"); - SWIG_typemap_lang("guile"); - - // Look for certain command line options - for (i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-help") == 0) { - fputs(usage, stdout); - Exit(EXIT_SUCCESS); - } else if (strcmp(argv[i], "-prefix") == 0) { - if (argv[i + 1]) { - prefix = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-package") == 0) { - if (argv[i + 1]) { - package = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-Linkage") == 0 || strcmp(argv[i], "-linkage") == 0) { - if (argv[i + 1]) { - if (0 == strcmp(argv[i + 1], "ltdlmod")) - linkage = GUILE_LSTYLE_LTDLMOD_1_4; - else if (0 == strcmp(argv[i + 1], "hobbit")) - linkage = GUILE_LSTYLE_HOBBIT; - else if (0 == strcmp(argv[i + 1], "simple")) - linkage = GUILE_LSTYLE_SIMPLE; - else if (0 == strcmp(argv[i + 1], "passive")) - linkage = GUILE_LSTYLE_PASSIVE; - else if (0 == strcmp(argv[i + 1], "module")) - linkage = GUILE_LSTYLE_MODULE; - else - Swig_arg_error(); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-procdoc") == 0) { - if (argv[i + 1]) { - procdoc = NewFile(argv[i + 1], "w", SWIG_output_files()); - if (!procdoc) { - FileErrorDisplay(argv[i + 1]); - Exit(EXIT_FAILURE); - } - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-procdocformat") == 0) { - if (strcmp(argv[i + 1], "guile-1.4") == 0) - docformat = GUILE_1_4; - else if (strcmp(argv[i + 1], "plain") == 0) - docformat = PLAIN; - else if (strcmp(argv[i + 1], "texinfo") == 0) - docformat = TEXINFO; - else - Swig_arg_error(); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else if (strcmp(argv[i], "-emit-setters") == 0 || strcmp(argv[i], "-emitsetters") == 0) { - emit_setters = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-only-setters") == 0 || strcmp(argv[i], "-onlysetters") == 0) { - emit_setters = 1; - only_setters = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-emit-slot-accessors") == 0 || strcmp(argv[i], "-emitslotaccessors") == 0) { - emit_slot_accessors = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-scmstub") == 0) { - scmstub = true; - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) { - goops = true; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-gh") == 0) { - Printf(stderr, "Deprecated command line option: -gh. Wrappers are always generated for the SCM interface. See documentation for more information regarding the deprecated GH interface.\n"); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-scm") == 0) { - Printf(stderr, "Deprecated command line option: -scm. Wrappers are always generated for the SCM interface. See documentation for more information regarding the deprecated GH interface.\n"); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-primsuffix") == 0) { - if (argv[i + 1]) { - primsuffix = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-goopsprefix") == 0) { - if (argv[i + 1]) { - goopsprefix = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-useclassprefix") == 0) { - useclassprefix = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-exportprimitive") == 0) { - exportprimitive = 1; - // should use Swig_warning() here? - Swig_mark_arg(i); - } - } - } - - // set default value for primsuffix - if (!primsuffix) - primsuffix = NewString("primitive"); - - //goops support can only be enabled if passive or module linkage is used - if (goops) { - if (linkage != GUILE_LSTYLE_PASSIVE && linkage != GUILE_LSTYLE_MODULE) { - Printf(stderr, "guile: GOOPS support requires passive or module linkage\n"); - Exit(EXIT_FAILURE); - } - } - - if (goops) { - // -proxy implies -emit-setters - emit_setters = 1; - } - - if ((linkage == GUILE_LSTYLE_PASSIVE && scmstub) || linkage == GUILE_LSTYLE_MODULE) - primRenamer = 1; - - if (exportprimitive && primRenamer) { - // should use Swig_warning() ? - Printf(stderr, "guile: Warning: -exportprimitive only makes sense with passive linkage without a scmstub.\n"); - } - - // Make sure `prefix' ends in an underscore - if (prefix) { - const char *px = Char(prefix); - if (px[Len(prefix) - 1] != '_') - Printf(prefix, "_"); - } - - /* Add a symbol for this module */ - Preprocessor_define("SWIGGUILE 1", 0); - /* Read in default typemaps */ - SWIG_config_file("guile_scm.swg"); - allow_overloading(); - - } - - /* ------------------------------------------------------------ - * top() - * ------------------------------------------------------------ */ - - virtual int top(Node *n) { - /* Initialize all of the output files */ - String *outfile = Getattr(n, "outfile"); - - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - f_wrappers = NewString(""); - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", f_init); - - scmtext = NewString(""); - Swig_register_filebyname("scheme", scmtext); - exported_symbols = NewString(""); - goopstext = NewString(""); - Swig_register_filebyname("goops", goopstext); - goopscode = NewString(""); - goopsexport = NewString(""); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "GUILE"); - - /* Write out directives and declarations */ - - module = Swig_copy_string(Char(Getattr(n, "name"))); - - switch (linkage) { - case GUILE_LSTYLE_SIMPLE: - /* Simple linkage; we have to export the SWIG_init function. The user can - rename the function by a #define. */ - Printf(f_runtime, "#define SWIG_GUILE_INIT_STATIC extern\n"); - break; - default: - /* Other linkage; we make the SWIG_init function static */ - Printf(f_runtime, "#define SWIG_GUILE_INIT_STATIC static\n"); - break; - } - - if (CPlusPlus) { - Printf(f_runtime, "extern \"C\" {\n\n"); - } - Printf(f_runtime, "SWIG_GUILE_INIT_STATIC void\nSWIG_init (void);\n"); - if (CPlusPlus) { - Printf(f_runtime, "\n}\n"); - } - - Printf(f_runtime, "\n"); - - Language::top(n); - - /* Close module */ - - Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); - - SwigType_emit_type_table(f_runtime, f_wrappers); - - Printf(f_init, "}\n\n"); - Printf(f_init, "#ifdef __cplusplus\n}\n#endif\n"); - - String *module_name = NewString(""); - - if (!module) - Printv(module_name, "swig", NIL); - else { - if (package) - Printf(module_name, "%s/%s", package, module); - else - Printv(module_name, module, NIL); - } - emit_linkage(module_name); - - Delete(module_name); - - if (procdoc) { - Delete(procdoc); - procdoc = NULL; - } - Delete(goopscode); - Delete(goopsexport); - Delete(goopstext); - - /* Close all of the files */ - Dump(f_runtime, f_begin); - Dump(f_header, f_begin); - Dump(f_wrappers, f_begin); - Wrapper_pretty_print(f_init, f_begin); - Delete(f_header); - Delete(f_wrappers); - Delete(f_init); - Delete(f_runtime); - Delete(f_begin); - return SWIG_OK; - } - - void emit_linkage(String *module_name) { - String *module_func = NewString(""); - - if (CPlusPlus) { - Printf(f_init, "extern \"C\" {\n\n"); - } - - Printv(module_func, module_name, NIL); - Replaceall(module_func, "-", "_"); - - switch (linkage) { - case GUILE_LSTYLE_SIMPLE: - Printf(f_init, "\n/* Linkage: simple */\n"); - break; - case GUILE_LSTYLE_PASSIVE: - Printf(f_init, "\n/* Linkage: passive */\n"); - Replaceall(module_func, "/", "_"); - Insert(module_func, 0, "scm_init_"); - Append(module_func, "_module"); - - Printf(f_init, "SCM\n%s (void)\n{\n", module_func); - Printf(f_init, " SWIG_init();\n"); - Printf(f_init, " return SCM_UNSPECIFIED;\n"); - Printf(f_init, "}\n"); - break; - case GUILE_LSTYLE_LTDLMOD_1_4: - Printf(f_init, "\n/* Linkage: ltdlmod */\n"); - Replaceall(module_func, "/", "_"); - Insert(module_func, 0, "scm_init_"); - Append(module_func, "_module"); - Printf(f_init, "SCM\n%s (void)\n{\n", module_func); - { - String *mod = NewString(module_name); - Replaceall(mod, "/", " "); - Printf(f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", mod); - Printf(f_init, " return SCM_UNSPECIFIED;\n"); - Delete(mod); - } - Printf(f_init, "}\n"); - break; - case GUILE_LSTYLE_MODULE: - Printf(f_init, "\n/* Linkage: module */\n"); - Replaceall(module_func, "/", "_"); - Insert(module_func, 0, "scm_init_"); - Append(module_func, "_module"); - - Printf(f_init, "static void SWIG_init_helper(void *data)\n"); - Printf(f_init, "{\n SWIG_init();\n"); - if (Len(exported_symbols) > 0) - Printf(f_init, " scm_c_export(%sNULL);", exported_symbols); - Printf(f_init, "\n}\n\n"); - - Printf(f_init, "SCM\n%s (void)\n{\n", module_func); - { - String *mod = NewString(module_name); - if (goops) - Printv(mod, "-", primsuffix, NIL); - Replaceall(mod, "/", " "); - Printf(f_init, " scm_c_define_module(\"%s\",\n", mod); - Printf(f_init, " SWIG_init_helper, NULL);\n"); - Printf(f_init, " return SCM_UNSPECIFIED;\n"); - Delete(mod); - } - Printf(f_init, "}\n"); - break; - case GUILE_LSTYLE_HOBBIT: - Printf(f_init, "\n/* Linkage: hobbit */\n"); - Replaceall(module_func, "/", "_slash_"); - Insert(module_func, 0, "scm_init_"); - Printf(f_init, "SCM\n%s (void)\n{\n", module_func); - { - String *mod = NewString(module_name); - Replaceall(mod, "/", " "); - Printf(f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", mod); - Printf(f_init, " return SCM_UNSPECIFIED;\n"); - Delete(mod); - } - Printf(f_init, "}\n"); - break; - default: - fputs("Fatal internal error: Invalid Guile linkage setting.\n", stderr); - Exit(EXIT_FAILURE); - } - - if (scmstub) { - /* Emit Scheme stub if requested */ - String *primitive_name = NewString(module_name); - if (goops) - Printv(primitive_name, "-", primsuffix, NIL); - - String *mod = NewString(primitive_name); - Replaceall(mod, "/", " "); - - String *fname = NewStringf("%s%s.scm", - SWIG_output_directory(), - primitive_name); - Delete(primitive_name); - File *scmstubfile = NewFile(fname, "w", SWIG_output_files()); - if (!scmstubfile) { - FileErrorDisplay(fname); - Exit(EXIT_FAILURE); - } - Delete(fname); - - Swig_banner_target_lang(scmstubfile, ";;;"); - Printf(scmstubfile, "\n"); - if (linkage == GUILE_LSTYLE_SIMPLE || linkage == GUILE_LSTYLE_PASSIVE) - Printf(scmstubfile, "(define-module (%s))\n\n", mod); - Delete(mod); - Printf(scmstubfile, "%s", scmtext); - if ((linkage == GUILE_LSTYLE_SIMPLE || linkage == GUILE_LSTYLE_PASSIVE) - && Len(exported_symbols) > 0) { - String *ex = NewString(exported_symbols); - Replaceall(ex, ", ", "\n "); - Replaceall(ex, "\"", ""); - Chop(ex); - Printf(scmstubfile, "\n(export %s)\n", ex); - Delete(ex); - } - Delete(scmstubfile); - } - - if (goops) { - String *mod = NewString(module_name); - Replaceall(mod, "/", " "); - - String *fname = NewStringf("%s%s.scm", SWIG_output_directory(), - module_name); - File *goopsfile = NewFile(fname, "w", SWIG_output_files()); - if (!goopsfile) { - FileErrorDisplay(fname); - Exit(EXIT_FAILURE); - } - Delete(fname); - Swig_banner_target_lang(goopsfile, ";;;"); - Printf(goopsfile, "\n"); - Printf(goopsfile, "(define-module (%s))\n", mod); - Printf(goopsfile, "%s\n", goopstext); - Printf(goopsfile, "(use-modules (oop goops) (Swig common))\n"); - if (primRenamer) { - Printf(goopsfile, "(use-modules ((%s-%s) :renamer (symbol-prefix-proc 'primitive:)))\n", mod, primsuffix); - } - Printf(goopsfile, "%s\n(export %s)", goopscode, goopsexport); - if (exportprimitive) { - String *ex = NewString(exported_symbols); - Replaceall(ex, ", ", "\n "); - Replaceall(ex, "\"", ""); - Chop(ex); - Printf(goopsfile, "\n(export %s)", ex); - Delete(ex); - } - Delete(mod); - Delete(goopsfile); - } - - Delete(module_func); - if (CPlusPlus) { - Printf(f_init, "\n}\n"); - } - } - - /* Return true iff T is a pointer type */ - - int is_a_pointer(SwigType *t) { - return SwigType_ispointer(SwigType_typedef_resolve_all(t)); - } - - /* Report an error handling the given type. */ - - void throw_unhandled_guile_type_error(SwigType *d) { - Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s.\n", SwigType_str(d, 0)); - } - - /* Write out procedure documentation */ - - void write_doc(const String *proc_name, const String *signature, const String *doc, const String *signature2 = NULL) { - switch (docformat) { - case GUILE_1_4: - Printv(procdoc, "\f\n", NIL); - Printv(procdoc, "(", signature, ")\n", NIL); - if (signature2) - Printv(procdoc, "(", signature2, ")\n", NIL); - Printv(procdoc, doc, "\n", NIL); - break; - case PLAIN: - Printv(procdoc, "\f", proc_name, "\n\n", NIL); - Printv(procdoc, "(", signature, ")\n", NIL); - if (signature2) - Printv(procdoc, "(", signature2, ")\n", NIL); - Printv(procdoc, doc, "\n\n", NIL); - break; - case TEXINFO: - Printv(procdoc, "\f", proc_name, "\n", NIL); - Printv(procdoc, "@deffn primitive ", signature, "\n", NIL); - if (signature2) - Printv(procdoc, "@deffnx primitive ", signature2, "\n", NIL); - Printv(procdoc, doc, "\n", NIL); - Printv(procdoc, "@end deffn\n\n", NIL); - break; - } - } - - /* returns false if the typemap is an empty string */ - bool handle_documentation_typemap(String *output, - const String *maybe_delimiter, Parm *p, const String *typemap, const String *default_doc, const String *name = NULL) { - String *tmp = NewString(""); - String *tm; - if (!(tm = Getattr(p, typemap))) { - Printf(tmp, "%s", default_doc); - tm = tmp; - } - bool result = (Len(tm) > 0); - if (maybe_delimiter && Len(output) > 0 && Len(tm) > 0) { - Printv(output, maybe_delimiter, NIL); - } - const String *pn = !name ? (const String *) Getattr(p, "name") : name; - String *pt = Getattr(p, "type"); - Replaceall(tm, "$name", pn); // legacy for $parmname - Replaceall(tm, "$type", SwigType_str(pt, 0)); - /* $NAME is like $name, but marked-up as a variable. */ - String *ARGNAME = NewString(""); - if (docformat == TEXINFO) - Printf(ARGNAME, "@var{%s}", pn); - else - Printf(ARGNAME, "%(upper)s", pn); - Replaceall(tm, "$NAME", ARGNAME); - Replaceall(tm, "$PARMNAME", ARGNAME); - Printv(output, tm, NIL); - Delete(tmp); - return result; - } - - /* ------------------------------------------------------------ - * functionWrapper() - * Create a function declaration and register it with the interpreter. - * ------------------------------------------------------------ */ - - virtual int functionWrapper(Node *n) { - String *iname = Getattr(n, "sym:name"); - SwigType *d = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - Parm *p; - String *proc_name = 0; - char source[256]; - Wrapper *f = NewWrapper(); - String *cleanup = NewString(""); - String *outarg = NewString(""); - String *signature = NewString(""); - String *doc_body = NewString(""); - String *returns = NewString(""); - String *method_signature = NewString(""); - String *primitive_args = NewString(""); - Hash *scheme_arg_names = NewHash(); - int num_results = 1; - String *tmp = NewString(""); - String *tm; - int i; - int numargs = 0; - int numreq = 0; - String *overname = 0; - int args_passed_as_array = 0; - int scheme_argnum = 0; - bool any_specialized_arg = false; - - // Make a wrapper name for this - String *wname = Swig_name_wrapper(iname); - if (Getattr(n, "sym:overloaded")) { - overname = Getattr(n, "sym:overname"); - args_passed_as_array = 1; - } else { - if (!addSymbol(iname, n)) { - DelWrapper(f); - return SWIG_ERROR; - } - } - if (overname) { - Append(wname, overname); - } - Setattr(n, "wrap:name", wname); - - // Build the name for scheme. - proc_name = NewString(iname); - Replaceall(proc_name, "_", "-"); - - /* Emit locals etc. into f->code; figure out which args to ignore */ - emit_parameter_variables(l, f); - - /* Attach the standard typemaps */ - emit_attach_parmmaps(l, f); - Setattr(n, "wrap:parms", l); - - /* Get number of required and total arguments */ - numargs = emit_num_arguments(l); - numreq = emit_num_required(l); - - /* Declare return variable */ - - Wrapper_add_local(f, "gswig_result", "SCM gswig_result"); - Wrapper_add_local(f, "gswig_list_p", "SWIGUNUSED int gswig_list_p = 0"); - - /* Open prototype and signature */ - - Printv(f->def, "static SCM\n", wname, " (", NIL); - if (args_passed_as_array) { - Printv(f->def, "int argc, SCM *argv", NIL); - } - Printv(signature, proc_name, NIL); - - /* Now write code to extract the parameters */ - - for (i = 0, p = l; i < numargs; i++) { - - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - int opt_p = (i >= numreq); - - // Produce names of source and target - if (args_passed_as_array) - sprintf(source, "argv[%d]", i); - else - sprintf(source, "s_%d", i); - - if (!args_passed_as_array) { - if (i != 0) - Printf(f->def, ", "); - Printf(f->def, "SCM s_%d", i); - } - if (opt_p) { - Printf(f->code, " if (%s != SCM_UNDEFINED) {\n", source); - } - if ((tm = Getattr(p, "tmap:in"))) { - Replaceall(tm, "$input", source); - Setattr(p, "emit:input", source); - Printv(f->code, tm, "\n", NIL); - - SwigType *pb = SwigType_typedef_resolve_all(SwigType_base(pt)); - SwigType *pn = Getattr(p, "name"); - String *argname; - scheme_argnum++; - if (pn && !Getattr(scheme_arg_names, pn)) - argname = pn; - else { - /* Anonymous arg or re-used argument name -- choose a name that cannot clash */ - argname = NewStringf("%%arg%d", scheme_argnum); - } - - if (procdoc) { - if (i == numreq) { - /* First optional argument */ - Printf(signature, " #:optional"); - } - /* Add to signature (arglist) */ - handle_documentation_typemap(signature, " ", p, "tmap:in:arglist", "$name", argname); - /* Document the type of the arg in the documentation body */ - handle_documentation_typemap(doc_body, ", ", p, "tmap:in:doc", "$NAME is of type <$type>", argname); - } - - if (goops) { - if (i < numreq) { - if (strcmp("void", Char(pt)) != 0) { - Node *class_node = Swig_symbol_clookup_check(pb, Getattr(n, "sym:symtab"), - has_classname); - String *goopsclassname = !class_node ? NULL : Getattr(class_node, "guile:goopsclassname"); - /* do input conversion */ - if (goopsclassname) { - Printv(method_signature, " (", argname, " ", goopsclassname, ")", NIL); - any_specialized_arg = true; - } else { - Printv(method_signature, " ", argname, NIL); - } - Printv(primitive_args, " ", argname, NIL); - Setattr(scheme_arg_names, argname, p); - } - } - } - - if (!pn) { - Delete(argname); - } - p = Getattr(p, "tmap:in:next"); - } else { - throw_unhandled_guile_type_error(pt); - p = nextSibling(p); - } - if (opt_p) - Printf(f->code, " }\n"); - } - if (Len(doc_body) > 0) - Printf(doc_body, ".\n"); - - /* Insert constraint checking code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - /* Pass output arguments back to the caller. */ - - /* Insert argument output code */ - String *returns_argout = NewString(""); - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - Replaceall(tm, "$arg", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(outarg, tm, "\n", NIL); - if (procdoc) { - if (handle_documentation_typemap(returns_argout, ", ", p, "tmap:argout:doc", "$NAME (of type $type)")) { - /* A documentation typemap that is not the empty string - indicates that a value is returned to Scheme. */ - num_results++; - } - } - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert cleanup code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:freearg"))) { - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(cleanup, tm, "\n", NIL); - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - if (exporting_destructor) { - /* Mark the destructor's argument as destroyed. */ - String *tm = NewString("SWIG_Guile_MarkPointerDestroyed($input);"); - Replaceall(tm, "$input", Getattr(l, "emit:input")); - Printv(cleanup, tm, "\n", NIL); - Delete(tm); - } - - /* Close prototype */ - - Printf(f->def, ")\n{\n"); - - /* Define the scheme name in C. This define is used by several Guile - macros. */ - Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); - - // Now write code to make the function call - String *actioncode = emit_action(n); - - // Now have return value, figure out what to do with it. - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { - Replaceall(tm, "$result", "gswig_result"); - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "1"); - else - Replaceall(tm, "$owner", "0"); - Printv(f->code, tm, "\n", NIL); - } else { - throw_unhandled_guile_type_error(d); - } - emit_return_variable(n, d, f); - - // Documentation - if ((tm = Getattr(n, "tmap:out:doc"))) { - Printv(returns, tm, NIL); - if (Len(tm) > 0) - num_results = 1; - else - num_results = 0; - } else { - String *s = SwigType_str(d, 0); - Chop(s); - Printf(returns, "<%s>", s); - Delete(s); - num_results = 1; - } - Append(returns, returns_argout); - - - // Dump the argument output code - Printv(f->code, outarg, NIL); - - // Dump the argument cleanup code - Printv(f->code, cleanup, NIL); - - // Look for any remaining cleanup - - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - Printv(f->code, tm, "\n", NIL); - } - } - // Free any memory allocated by the function being wrapped.. - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printv(f->code, tm, "\n", NIL); - } - // Wrap things up (in a manner of speaking) - - if (beforereturn) - Printv(f->code, beforereturn, "\n", NIL); - Printv(f->code, "return gswig_result;\n", NIL); - - /* Substitute the function name */ - Replaceall(f->code, "$symname", iname); - // Undefine the scheme name - - Printf(f->code, "#undef FUNC_NAME\n"); - Printf(f->code, "}\n"); - - Wrapper_print(f, f_wrappers); - - if (!Getattr(n, "sym:overloaded")) { - if (numargs > 10) { - int i; - /* gh_new_procedure would complain: too many args */ - /* Build a wrapper wrapper */ - Printv(f_wrappers, "static SCM\n", wname, "_rest (SCM rest)\n", NIL); - Printv(f_wrappers, "{\n", NIL); - Printf(f_wrappers, "SCM arg[%d];\n", numargs); - Printf(f_wrappers, "SWIG_Guile_GetArgs (arg, rest, %d, %d, \"%s\");\n", numreq, numargs - numreq, proc_name); - Printv(f_wrappers, "return ", wname, "(", NIL); - Printv(f_wrappers, "arg[0]", NIL); - for (i = 1; i < numargs; i++) - Printf(f_wrappers, ", arg[%d]", i); - Printv(f_wrappers, ");\n", NIL); - Printv(f_wrappers, "}\n", NIL); - /* Register it */ - Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, 0, 1, (swig_guile_proc) %s_rest);\n", proc_name, wname); - } else if (emit_setters && struct_member && strlen(Char(proc_name)) > 3) { - int len = Len(proc_name); - const char *pc = Char(proc_name); - /* MEMBER-set and MEMBER-get functions. */ - int is_setter = (pc[len - 3] == 's'); - if (is_setter) { - Printf(f_init, "SCM setter = "); - struct_member = 2; /* have a setter */ - } else - Printf(f_init, "SCM getter = "); - /* GOOPS support uses the MEMBER-set and MEMBER-get functions, - so ignore only_setters in this case. */ - if (only_setters && !goops) - Printf(f_init, "scm_c_make_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname); - else - Printf(f_init, "scm_c_define_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname); - - if (!is_setter) { - /* Strip off "-get" */ - if (struct_member == 2) { - /* There was a setter, so create a procedure with setter */ - Printf(f_init, "scm_c_define"); - Printf(f_init, "(\"%.*s\", " "scm_make_procedure_with_setter(getter, setter));\n", pc, len - 4); - } else { - /* There was no setter, so make an alias to the getter */ - Printf(f_init, "scm_c_define"); - Printf(f_init, "(\"%.*s\", getter);\n", pc, len - 4); - } - Printf(exported_symbols, "\"%.*s\", ", pc, len - 4); - } - } else { - /* Register the function */ - if (exporting_destructor) { - Printf(f_init, "((swig_guile_clientdata *)(SWIGTYPE%s->clientdata))->destroy = (guile_destructor) %s;\n", swigtype_ptr, wname); - //Printf(f_init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname); - } - Printf(f_init, "scm_c_define_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs - numreq, wname); - } - } else { /* overloaded function; don't export the single methods */ - if (!Getattr(n, "sym:nextSibling")) { - /* Emit overloading dispatch function */ - - int maxargs; - String *dispatch = Swig_overload_dispatch(n, "return %s(argc,argv);", &maxargs); - - /* Generate a dispatch wrapper for all overloaded functions */ - - Wrapper *df = NewWrapper(); - String *dname = Swig_name_wrapper(iname); - - Printv(df->def, "static SCM\n", dname, "(SCM rest)\n{\n", NIL); - Printf(df->code, "#define FUNC_NAME \"%s\"\n", proc_name); - Printf(df->code, "SCM argv[%d];\n", maxargs); - Printf(df->code, "int argc = SWIG_Guile_GetArgs (argv, rest, %d, %d, \"%s\");\n", 0, maxargs, proc_name); - Printv(df->code, dispatch, "\n", NIL); - Printf(df->code, "scm_misc_error(\"%s\", \"No matching method for generic function `%s'\", SCM_EOL);\n", proc_name, iname); - Printf(df->code, "#undef FUNC_NAME\n"); - Printv(df->code, "}\n", NIL); - Wrapper_print(df, f_wrappers); - Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, 0, 1, (swig_guile_proc) %s);\n", proc_name, dname); - DelWrapper(df); - Delete(dispatch); - Delete(dname); - } - } - Printf(exported_symbols, "\"%s\", ", proc_name); - - if (!in_class || memberfunction_name) { - // export wrapper into goops file - String *method_def = NewString(""); - String *goops_name; - if (in_class) - goops_name = NewString(memberfunction_name); - else - goops_name = goopsNameMapping(proc_name, ""); - String *primitive_name = NewString(""); - if (primRenamer) - Printv(primitive_name, "primitive:", proc_name, NIL); - else - Printv(primitive_name, proc_name, NIL); - Replaceall(method_signature, "_", "-"); - Replaceall(primitive_args, "_", "-"); - if (!any_specialized_arg) { - /* If there would not be any specialized argument in - the method declaration, we simply re-export the - function. This is a performance optimization. */ - Printv(method_def, "(define ", goops_name, " ", primitive_name, ")\n", NIL); - } else if (numreq == numargs) { - Printv(method_def, "(define-method (", goops_name, method_signature, ")\n", NIL); - Printv(method_def, " (", primitive_name, primitive_args, "))\n", NIL); - } else { - /* Handle optional args. For the rest argument, use a name - that cannot clash. */ - Printv(method_def, "(define-method (", goops_name, method_signature, " . %args)\n", NIL); - Printv(method_def, " (apply ", primitive_name, primitive_args, " %args))\n", NIL); - } - if (in_class) { - /* Defer method definition till end of class definition. */ - Printv(goops_class_methods, method_def, NIL); - } else { - Printv(goopscode, method_def, NIL); - } - Printf(goopsexport, "%s ", goops_name); - Delete(primitive_name); - Delete(goops_name); - Delete(method_def); - } - - if (procdoc) { - String *returns_text = NewString(""); - if (num_results == 0) - Printv(returns_text, return_nothing_doc, NIL); - else if (num_results == 1) - Printv(returns_text, return_one_doc, NIL); - else - Printv(returns_text, return_multi_doc, NIL); - /* Substitute documentation variables */ - static const char *numbers[] = { "zero", "one", "two", "three", - "four", "five", "six", "seven", - "eight", "nine", "ten", "eleven", - "twelve" - }; - if (num_results <= 12) - Replaceall(returns_text, "$num_values", numbers[num_results]); - else { - String *num_results_str = NewStringf("%d", num_results); - Replaceall(returns_text, "$num_values", num_results_str); - Delete(num_results_str); - } - Replaceall(returns_text, "$values", returns); - Printf(doc_body, "\n%s", returns_text); - write_doc(proc_name, signature, doc_body); - Delete(returns_text); - } - - Delete(proc_name); - Delete(outarg); - Delete(cleanup); - Delete(signature); - Delete(method_signature); - Delete(primitive_args); - Delete(doc_body); - Delete(returns_argout); - Delete(returns); - Delete(tmp); - Delete(scheme_arg_names); - DelWrapper(f); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * variableWrapper() - * - * Create a link to a C variable. - * This creates a single function PREFIX_var_VARNAME(). - * This function takes a single optional argument. If supplied, it means - * we are setting this variable to some value. If omitted, it means we are - * simply evaluating this variable. Either way, we return the variables - * value. - * ------------------------------------------------------------ */ - - virtual int variableWrapper(Node *n) { - - char *name = GetChar(n, "name"); - char *iname = GetChar(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - - String *proc_name; - Wrapper *f; - String *tm; - - if (!addSymbol(iname, n)) - return SWIG_ERROR; - - f = NewWrapper(); - // evaluation function names - - String *var_name = Swig_name_wrapper(iname); - - // Build the name for scheme. - proc_name = NewString(iname); - Replaceall(proc_name, "_", "-"); - Setattr(n, "wrap:name", proc_name); - - if (1 || (SwigType_type(t) != T_USER) || (is_a_pointer(t))) { - - Printf(f->def, "static SCM\n%s(SCM s_0)\n{\n", var_name); - - /* Define the scheme name in C. This define is used by several Guile - macros. */ - Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); - - Wrapper_add_local(f, "gswig_result", "SCM gswig_result"); - - if (!GetFlag(n, "feature:immutable")) { - /* Check for a setting of the variable value */ - Printf(f->code, "if (s_0 != SCM_UNDEFINED) {\n"); - if ((tm = Swig_typemap_lookup("varin", n, name, 0))) { - Replaceall(tm, "$input", "s_0"); - /* Printv(f->code,tm,"\n",NIL); */ - emit_action_code(n, f->code, tm); - } else { - throw_unhandled_guile_type_error(t); - } - Printf(f->code, "}\n"); - } - // Now return the value of the variable (regardless - // of evaluating or setting) - - if ((tm = Swig_typemap_lookup("varout", n, name, 0))) { - Replaceall(tm, "$result", "gswig_result"); - /* Printv(f->code,tm,"\n",NIL); */ - emit_action_code(n, f->code, tm); - } else { - throw_unhandled_guile_type_error(t); - } - Printf(f->code, "\nreturn gswig_result;\n"); - Printf(f->code, "#undef FUNC_NAME\n"); - Printf(f->code, "}\n"); - - Wrapper_print(f, f_wrappers); - - // Now add symbol to the Guile interpreter - - if (!emit_setters || GetFlag(n, "feature:immutable")) { - /* Read-only variables become a simple procedure returning the - value; read-write variables become a simple procedure with - an optional argument. */ - - if (!goops && GetFlag(n, "feature:constasvar")) { - /* need to export this function as a variable instead of a procedure */ - if (scmstub) { - /* export the function in the wrapper, and (set!) it in scmstub */ - Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, !GetFlag(n, "feature:immutable"), var_name); - Printf(scmtext, "(set! %s (%s))\n", proc_name, proc_name); - } else { - /* export the variable directly */ - Printf(f_init, "scm_c_define(\"%s\", %s(SCM_UNDEFINED));\n", proc_name, var_name); - } - - } else { - /* Export the function as normal */ - Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, !GetFlag(n, "feature:immutable"), var_name); - } - - } else { - /* Read/write variables become a procedure with setter. */ - Printf(f_init, "{ SCM p = scm_c_define_gsubr(\"%s\", 0, 1, 0, (swig_guile_proc) %s);\n", proc_name, var_name); - Printf(f_init, "scm_c_define"); - Printf(f_init, "(\"%s\", " "scm_make_procedure_with_setter(p, p)); }\n", proc_name); - } - Printf(exported_symbols, "\"%s\", ", proc_name); - - // export wrapper into goops file - if (!in_class) { // only if the variable is not part of a class - String *class_name = SwigType_typedef_resolve_all(SwigType_base(t)); - String *goops_name = goopsNameMapping(proc_name, ""); - String *primitive_name = NewString(""); - if (primRenamer) - Printv(primitive_name, "primitive:", NIL); - Printv(primitive_name, proc_name, NIL); - /* Simply re-export the procedure */ - if ((!emit_setters || GetFlag(n, "feature:immutable")) - && GetFlag(n, "feature:constasvar")) { - Printv(goopscode, "(define ", goops_name, " (", primitive_name, "))\n", NIL); - } else { - Printv(goopscode, "(define ", goops_name, " ", primitive_name, ")\n", NIL); - } - Printf(goopsexport, "%s ", goops_name); - Delete(primitive_name); - Delete(class_name); - Delete(goops_name); - } - - if (procdoc) { - /* Compute documentation */ - String *signature = NewString(""); - String *signature2 = NULL; - String *doc = NewString(""); - - if (GetFlag(n, "feature:immutable")) { - Printv(signature, proc_name, NIL); - if (GetFlag(n, "feature:constasvar")) { - Printv(doc, "Is constant ", NIL); - } else { - Printv(doc, "Returns constant ", NIL); - } - if ((tm = Getattr(n, "tmap:varout:doc"))) { - Printv(doc, tm, NIL); - } else { - String *s = SwigType_str(t, 0); - Chop(s); - Printf(doc, "<%s>", s); - Delete(s); - } - } else if (emit_setters) { - Printv(signature, proc_name, NIL); - signature2 = NewString(""); - Printv(signature2, "set! (", proc_name, ") ", NIL); - handle_documentation_typemap(signature2, NIL, n, "tmap:varin:arglist", "new-value"); - Printv(doc, "Get or set the value of the C variable, \n", NIL); - Printv(doc, "which is of type ", NIL); - handle_documentation_typemap(doc, NIL, n, "tmap:varout:doc", "$1_type"); - Printv(doc, "."); - } else { - Printv(signature, proc_name, " #:optional ", NIL); - if ((tm = Getattr(n, "tmap:varin:doc"))) { - Printv(signature, tm, NIL); - } else { - String *s = SwigType_str(t, 0); - Chop(s); - Printf(signature, "new-value <%s>", s); - Delete(s); - } - - Printv(doc, "If NEW-VALUE is provided, " "set C variable to this value.\n", NIL); - Printv(doc, "Returns variable value ", NIL); - if ((tm = Getattr(n, "tmap:varout:doc"))) { - Printv(doc, tm, NIL); - } else { - String *s = SwigType_str(t, 0); - Chop(s); - Printf(doc, "<%s>", s); - Delete(s); - } - } - write_doc(proc_name, signature, doc, signature2); - Delete(signature); - if (signature2) - Delete(signature2); - Delete(doc); - } - - } else { - Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0)); - } - Delete(var_name); - Delete(proc_name); - DelWrapper(f); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constantWrapper() - * - * We create a read-only variable. - * ------------------------------------------------------------ */ - - virtual int constantWrapper(Node *n) { - char *name = GetChar(n, "name"); - char *iname = GetChar(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - String *rawval = Getattr(n, "rawval"); - String *value = rawval ? rawval : Getattr(n, "value"); - int constasvar = GetFlag(n, "feature:constasvar"); - - - String *proc_name; - String *var_name; - Wrapper *f; - SwigType *nctype; - String *tm; - - f = NewWrapper(); - - // Make a static variable; - var_name = NewStringf("%sconst_%s", prefix, iname); - - // Strip const qualifier from type if present - - nctype = NewString(type); - if (SwigType_isconst(nctype)) { - Delete(SwigType_pop(nctype)); - } - // Build the name for scheme. - proc_name = NewString(iname); - Replaceall(proc_name, "_", "-"); - - if ((SwigType_type(nctype) == T_USER) && (!is_a_pointer(nctype))) { - Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); - Delete(var_name); - DelWrapper(f); - return SWIG_NOWRAP; - } - // See if there's a typemap - - if ((tm = Swig_typemap_lookup("constant", n, name, 0))) { - Replaceall(tm, "$value", value); - Printv(f_header, tm, "\n", NIL); - } else { - // Create variable and assign it a value - Printf(f_header, "static %s = (%s)(%s);\n", SwigType_str(type, var_name), SwigType_str(type, 0), value); - } - { - /* Hack alert: will cleanup later -- Dave */ - Node *nn = NewHash(); - Setfile(nn, Getfile(n)); - Setline(nn, Getline(n)); - Setattr(nn, "name", var_name); - Setattr(nn, "sym:name", iname); - Setattr(nn, "type", nctype); - SetFlag(nn, "feature:immutable"); - if (constasvar) { - SetFlag(nn, "feature:constasvar"); - } - variableWrapper(nn); - Delete(nn); - } - Delete(var_name); - Delete(nctype); - Delete(proc_name); - DelWrapper(f); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * classDeclaration() - * ------------------------------------------------------------ */ - virtual int classDeclaration(Node *n) { - String *class_name = NewStringf("<%s>", Getattr(n, "sym:name")); - Setattr(n, "guile:goopsclassname", class_name); - return Language::classDeclaration(n); - } - - /* ------------------------------------------------------------ - * classHandler() - * ------------------------------------------------------------ */ - virtual int classHandler(Node *n) { - /* Create new strings for building up a wrapper function */ - have_constructor = 0; - - class_name = NewString(""); - short_class_name = NewString(""); - Printv(class_name, "<", Getattr(n, "sym:name"), ">", NIL); - Printv(short_class_name, Getattr(n, "sym:name"), NIL); - Replaceall(class_name, "_", "-"); - Replaceall(short_class_name, "_", "-"); - - if (!addSymbol(class_name, n)) - return SWIG_ERROR; - - /* Handle inheritance */ - String *base_class = NewString("<"); - List *baselist = Getattr(n, "bases"); - if (baselist && Len(baselist)) { - Iterator i = First(baselist); - while (i.item) { - Printv(base_class, Getattr(i.item, "sym:name"), NIL); - i = Next(i); - if (i.item) { - Printf(base_class, "> <"); - } - } - } - Printf(base_class, ">"); - Replaceall(base_class, "_", "-"); - - Printv(goopscode, "(define-class ", class_name, " ", NIL); - Printf(goopsexport, "%s ", class_name); - - if (Len(base_class) > 2) { - Printv(goopscode, "(", base_class, ")\n", NIL); - } else { - Printv(goopscode, "(<swig>)\n", NIL); - } - SwigType *ct = NewStringf("p.%s", Getattr(n, "name")); - swigtype_ptr = SwigType_manglestr(ct); - - String *mangled_classname = Swig_name_mangle(Getattr(n, "sym:name")); - /* Export clientdata structure */ - Printf(f_runtime, "static swig_guile_clientdata _swig_guile_clientdata%s = { NULL, SCM_EOL };\n", mangled_classname); - - Printv(f_init, "SWIG_TypeClientData(SWIGTYPE", swigtype_ptr, ", (void *) &_swig_guile_clientdata", mangled_classname, ");\n", NIL); - SwigType_remember(ct); - Delete(ct); - - /* Emit all of the members */ - goops_class_methods = NewString(""); - - in_class = 1; - Language::classHandler(n); - in_class = 0; - - Printv(goopscode, " #:metaclass <swig-metaclass>\n", NIL); - - if (have_constructor) - Printv(goopscode, " #:new-function ", primRenamer ? "primitive:" : "", "new-", short_class_name, "\n", NIL); - - Printf(goopscode, ")\n%s\n", goops_class_methods); - Delete(goops_class_methods); - goops_class_methods = 0; - - - /* export class initialization function */ - if (goops) { - /* export the wrapper function */ - String *funcName = NewString(mangled_classname); - Printf(funcName, "_swig_guile_setgoopsclass"); - String *guileFuncName = NewString(funcName); - Replaceall(guileFuncName, "_", "-"); - - Printv(f_wrappers, "static SCM ", funcName, "(SCM cl) \n", NIL); - Printf(f_wrappers, "#define FUNC_NAME %s\n{\n", guileFuncName); - Printv(f_wrappers, " ((swig_guile_clientdata *)(SWIGTYPE", swigtype_ptr, "->clientdata))->goops_class = cl;\n", NIL); - Printf(f_wrappers, " return SCM_UNSPECIFIED;\n"); - Printf(f_wrappers, "}\n#undef FUNC_NAME\n\n"); - - Printf(f_init, "scm_c_define_gsubr(\"%s\", 1, 0, 0, (swig_guile_proc) %s);\n", guileFuncName, funcName); - Printf(exported_symbols, "\"%s\", ", guileFuncName); - - /* export the call to the wrapper function */ - Printf(goopscode, "(%s%s %s)\n\n", primRenamer ? "primitive:" : "", guileFuncName, class_name); - - Delete(guileFuncName); - Delete(funcName); - } - - Delete(mangled_classname); - - Delete(swigtype_ptr); - swigtype_ptr = 0; - - Delete(class_name); - Delete(short_class_name); - class_name = 0; - short_class_name = 0; - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * memberfunctionHandler() - * ------------------------------------------------------------ */ - int memberfunctionHandler(Node *n) { - String *iname = Getattr(n, "sym:name"); - String *proc = NewString(iname); - Replaceall(proc, "_", "-"); - - memberfunction_name = goopsNameMapping(proc, short_class_name); - Language::memberfunctionHandler(n); - Delete(memberfunction_name); - memberfunction_name = NULL; - Delete(proc); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * membervariableHandler() - * ------------------------------------------------------------ */ - int membervariableHandler(Node *n) { - String *iname = Getattr(n, "sym:name"); - - if (emit_setters) { - struct_member = 1; - Printf(f_init, "{\n"); - } - - Language::membervariableHandler(n); - - if (emit_setters) { - Printf(f_init, "}\n"); - struct_member = 0; - } - - String *proc = NewString(iname); - Replaceall(proc, "_", "-"); - String *goops_name = goopsNameMapping(proc, short_class_name); - - /* The slot name is never qualified with the class, - even if useclassprefix is true. */ - Printv(goopscode, " (", proc, " #:allocation #:virtual", NIL); - /* GOOPS (at least in Guile 1.6.3) only accepts closures, not - primitive procedures for slot-ref and slot-set. */ - Printv(goopscode, "\n #:slot-ref (lambda (obj) (", primRenamer ? "primitive:" : "", short_class_name, "-", proc, "-get", " obj))", NIL); - if (!GetFlag(n, "feature:immutable")) { - Printv(goopscode, "\n #:slot-set! (lambda (obj value) (", primRenamer ? "primitive:" : "", short_class_name, "-", proc, "-set", " obj value))", NIL); - } else { - Printf(goopscode, "\n #:slot-set! (lambda (obj value) (error \"Immutable slot\"))"); - } - if (emit_slot_accessors) { - if (GetFlag(n, "feature:immutable")) { - Printv(goopscode, "\n #:getter ", goops_name, NIL); - } else { - Printv(goopscode, "\n #:accessor ", goops_name, NIL); - } - Printf(goopsexport, "%s ", goops_name); - } - Printv(goopscode, ")\n", NIL); - Delete(proc); - Delete(goops_name); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constructorHandler() - * ------------------------------------------------------------ */ - int constructorHandler(Node *n) { - Language::constructorHandler(n); - have_constructor = 1; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * destructorHandler() - * ------------------------------------------------------------ */ - virtual int destructorHandler(Node *n) { - exporting_destructor = true; - Language::destructorHandler(n); - exporting_destructor = false; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * pragmaDirective() - * ------------------------------------------------------------ */ - - virtual int pragmaDirective(Node *n) { - if (!ImportMode) { - String *lang = Getattr(n, "lang"); - String *cmd = Getattr(n, "name"); - String *value = Getattr(n, "value"); - -# define store_pragma(PRAGMANAME) \ - if (Strcmp(cmd, #PRAGMANAME) == 0) { \ - if (PRAGMANAME) Delete(PRAGMANAME); \ - PRAGMANAME = value ? NewString(value) : NULL; \ - } - - if (Strcmp(lang, "guile") == 0) { - store_pragma(beforereturn) - store_pragma(return_nothing_doc) - store_pragma(return_one_doc) - store_pragma(return_multi_doc); -# undef store_pragma - } - } - return Language::pragmaDirective(n); - } - - - /* ------------------------------------------------------------ - * goopsNameMapping() - * Maps the identifier from C++ to the GOOPS based * on command - * line parameters and such. - * If class_name = "" that means the mapping is for a function or - * variable not attached to any class. - * ------------------------------------------------------------ */ - String *goopsNameMapping(String *name, const_String_or_char_ptr class_name) { - String *n = NewString(""); - - if (Strcmp(class_name, "") == 0) { - // not part of a class, so no class name to prefix - if (goopsprefix) { - Printf(n, "%s%s", goopsprefix, name); - } else { - Printf(n, "%s", name); - } - } else { - if (useclassprefix) { - Printf(n, "%s-%s", class_name, name); - } else { - if (goopsprefix) { - Printf(n, "%s%s", goopsprefix, name); - } else { - Printf(n, "%s", name); - } - } - } - return n; - } - - - /* ------------------------------------------------------------ - * validIdentifier() - * ------------------------------------------------------------ */ - - virtual int validIdentifier(String *s) { - char *c = Char(s); - /* Check whether we have an R5RS identifier. Guile supports a - superset of R5RS identifiers, but it's probably a bad idea to use - those. */ - /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */ - /* <initial> --> <letter> | <special initial> */ - if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%') - || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') - || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') - || (*c == '^') || (*c == '_') || (*c == '~'))) { - /* <peculiar identifier> --> + | - | ... */ - if ((strcmp(c, "+") == 0) - || strcmp(c, "-") == 0 || strcmp(c, "...") == 0) - return 1; - else - return 0; - } - /* <subsequent> --> <initial> | <digit> | <special subsequent> */ - while (*c) { - if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%') - || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') - || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') - || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+') - || (*c == '-') || (*c == '.') || (*c == '@'))) - return 0; - c++; - } - return 1; - } - - String *runtimeCode() { - String *s; - s = Swig_include_sys("guile_scm_run.swg"); - if (!s) { - Printf(stderr, "*** Unable to open 'guile_scm_run.swg"); - s = NewString(""); - } - return s; - } - - String *defaultExternalRuntimeFilename() { - return NewString("swigguilerun.h"); - } -}; - -/* ----------------------------------------------------------------------------- - * swig_guile() - Instantiate module - * ----------------------------------------------------------------------------- */ - -static Language *new_swig_guile() { - return new GUILE(); -} -extern "C" Language *swig_guile(void) { - return new_swig_guile(); -} diff --git a/contrib/tools/swig/Source/Modules/interface.cxx b/contrib/tools/swig/Source/Modules/interface.cxx deleted file mode 100644 index 83a5e5f8a13..00000000000 --- a/contrib/tools/swig/Source/Modules/interface.cxx +++ /dev/null @@ -1,210 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * interface.cxx - * - * This module contains support for the interface feature. - * This feature is used in language modules where the target language does not - * naturally support C++ style multiple inheritance, but does support inheritance - * from multiple interfaces. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" - -static bool interface_feature_enabled = false; - -/* ----------------------------------------------------------------------------- - * collect_interface_methods() - * - * Create a list of all the methods from the base classes of class n that are - * marked as an interface. The resulting list is thus the list of methods that - * need to be implemented in order for n to be non-abstract. - * ----------------------------------------------------------------------------- */ - -static List *collect_interface_methods(Node *n) { - List *methods = NewList(); - if (List *bases = Getattr(n, "interface:bases")) { - for (Iterator base = First(bases); base.item; base = Next(base)) { - Node *cls = base.item; - if (cls == n) - continue; - for (Node *child = firstChild(cls); child; child = nextSibling(child)) { - if (Cmp(nodeType(child), "cdecl") == 0) { - if (GetFlag(child, "feature:ignore") || Getattr(child, "interface:owner")) - continue; // skip methods propagated to bases - if (!checkAttribute(child, "kind", "function")) - continue; - if (checkAttribute(child, "storage", "static")) - continue; // accept virtual methods, non-virtual methods too... mmm??. Warn that the interface class has something that is not a virtual method? - Node *nn = copyNode(child); - Setattr(nn, "interface:owner", cls); - ParmList *parms = CopyParmList(Getattr(child, "parms")); - Setattr(nn, "parms", parms); - Delete(parms); - ParmList *throw_parm_list = Getattr(child, "throws"); - if (throw_parm_list) - Setattr(nn, "throws", CopyParmList(throw_parm_list)); - Append(methods, nn); - } - } - } - } - return methods; -} - -/* ----------------------------------------------------------------------------- - * collect_interface_bases - * ----------------------------------------------------------------------------- */ - -static void collect_interface_bases(List *bases, Node *n) { - if (GetFlag(n, "feature:interface")) { - String *name = Getattr(n, "interface:name"); - if (!Getattr(bases, name)) - Append(bases, n); - } - - if (List *baselist = Getattr(n, "bases")) { - for (Iterator base = First(baselist); base.item; base = Next(base)) { - if (!GetFlag(base.item, "feature:ignore")) { - if (GetFlag(base.item, "feature:interface")) - collect_interface_bases(bases, base.item); - } - } - } -} - -/* ----------------------------------------------------------------------------- - * collect_interface_base_classes() - * - * Create a hash containing all the classes up the inheritance hierarchy - * marked with feature:interface (including this class n). - * Stops going up the inheritance chain as soon as a class is found without - * feature:interface. - * The idea is to find all the base interfaces that a class must implement. - * ----------------------------------------------------------------------------- */ - -static void collect_interface_base_classes(Node *n) { - if (GetFlag(n, "feature:interface")) { - // check all bases are also interfaces - if (List *baselist = Getattr(n, "bases")) { - for (Iterator base = First(baselist); base.item; base = Next(base)) { - if (!GetFlag(base.item, "feature:ignore")) { - if (!GetFlag(base.item, "feature:interface")) { - Swig_error(Getfile(n), Getline(n), "Base class '%s' of '%s' is not similarly marked as an interface.\n", SwigType_namestr(Getattr(base.item, "name")), SwigType_namestr(Getattr(n, "name"))); - Exit(EXIT_FAILURE); - } - } - } - } - } - - List *interface_bases = NewList(); - collect_interface_bases(interface_bases, n); - if (Len(interface_bases) == 0) - Delete(interface_bases); - else - Setattr(n, "interface:bases", interface_bases); -} - -/* ----------------------------------------------------------------------------- - * process_interface_name() - * ----------------------------------------------------------------------------- */ - -static void process_interface_name(Node *n) { - if (GetFlag(n, "feature:interface")) { - String *interface_name = Getattr(n, "feature:interface:name"); - if (!Len(interface_name)) { - Swig_error(Getfile(n), Getline(n), "The interface feature for '%s' is missing the name attribute.\n", SwigType_namestr(Getattr(n, "name"))); - Exit(EXIT_FAILURE); - } - if (Strchr(interface_name, '%')) { - String *name = NewStringf(interface_name, Getattr(n, "sym:name")); - Setattr(n, "interface:name", name); - } else { - Setattr(n, "interface:name", interface_name); - } - } -} - -/* ----------------------------------------------------------------------------- - * Swig_interface_propagate_methods() - * - * Find all the base classes marked as an interface (with feature:interface) for - * class node n. For each of these, add all of its methods as methods of n so that - * n is not abstract. If class n is also marked as an interface, it will remain - * abstract and not have any methods added. - * ----------------------------------------------------------------------------- */ - -void Swig_interface_propagate_methods(Node *n) { - if (interface_feature_enabled) { - process_interface_name(n); - collect_interface_base_classes(n); - List *methods = collect_interface_methods(n); - bool is_interface = GetFlag(n, "feature:interface") ? true : false; - for (Iterator mi = First(methods); mi.item; mi = Next(mi)) { - if (!is_interface && GetFlag(mi.item, "abstract")) - continue; - String *this_decl = Getattr(mi.item, "decl"); - String *this_decl_resolved = SwigType_typedef_resolve_all(this_decl); - bool identically_overloaded_method = false; // true when a base class' method is implemented in n - if (SwigType_isfunction(this_decl_resolved)) { - String *name = Getattr(mi.item, "name"); - for (Node *child = firstChild(n); child; child = nextSibling(child)) { - if (Getattr(child, "interface:owner")) - break; // at the end of the list are newly appended methods - if (Cmp(nodeType(child), "cdecl") == 0) { - if (checkAttribute(child, "name", name)) { - String *decl = SwigType_typedef_resolve_all(Getattr(child, "decl")); - identically_overloaded_method = Strcmp(decl, this_decl_resolved) == 0; - Delete(decl); - if (identically_overloaded_method) - break; - } - } - } - } - Delete(this_decl_resolved); - if (!identically_overloaded_method) { - // Add method copied from base class to this derived class - Node *cn = mi.item; - Delattr(cn, "sym:overname"); - String *prefix = Getattr(n, "name"); - String *name = Getattr(cn, "name"); - String *decl = Getattr(cn, "decl"); - String *oldname = Getattr(cn, "sym:name"); - - String *symname = Swig_name_make(cn, prefix, name, decl, oldname); - if (Strcmp(symname, "$ignore") != 0) { - Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab")); - Node *on = Swig_symbol_add(symname, cn); - (void)on; - assert(on == cn); - - // Features from the copied base class method are already present, now add in features specific to the added method in the derived class - Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn); - Swig_symbol_setscope(oldscope); - appendChild(n, cn); - } - } else { - Delete(mi.item); - } - } - Delete(methods); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_interface_feature_enable() - * - * Turn on interface feature support - * ----------------------------------------------------------------------------- */ - -void Swig_interface_feature_enable() { - interface_feature_enabled = true; -} diff --git a/contrib/tools/swig/Source/Modules/java.cxx b/contrib/tools/swig/Source/Modules/java.cxx deleted file mode 100644 index 773945af207..00000000000 --- a/contrib/tools/swig/Source/Modules/java.cxx +++ /dev/null @@ -1,4979 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * java.cxx - * - * Java language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" -#include <limits.h> // for INT_MAX -#include <ctype.h> -#include "javadoc.h" - -/* Hash type used for upcalls from C/C++ */ -typedef DOH UpcallData; - -class JAVA:public Language { - static const char *usage; - const String *empty_string; - const String *public_string; - const String *protected_string; - - Hash *swig_types_hash; - File *f_begin; - File *f_runtime; - File *f_runtime_h; - File *f_header; - File *f_wrappers; - File *f_init; - File *f_directors; - File *f_directors_h; - List *filenames_list; - - bool proxy_flag; // Flag for generating proxy classes - bool nopgcpp_flag; // Flag for suppressing the premature garbage collection prevention parameter - bool native_function_flag; // Flag for when wrapping a native function - bool enum_constant_flag; // Flag for when wrapping an enum or constant - bool static_flag; // Flag for when wrapping a static functions or member variables - bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable - bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const - bool global_variable_flag; // Flag for when wrapping a global variable - bool old_variable_names; // Flag for old style variable names in the intermediary class - bool member_func_flag; // flag set when wrapping a member function - bool doxygen; //flag for converting found doxygen to javadoc - bool comment_creation_chatter; //flag for getting information about where comments were created in java.cxx - - String *imclass_name; // intermediary class name - String *module_class_name; // module class name - String *constants_interface_name; // constants interface name - String *imclass_class_code; // intermediary class code - String *proxy_class_def; - String *proxy_class_code; - String *interface_class_code; // if %feature("interface") was declared for a class, here goes the interface declaration - String *module_class_code; - String *proxy_class_name; // proxy class name - String *full_proxy_class_name;// fully qualified proxy class name when using nspace feature, otherwise same as proxy_class_name - String *full_imclass_name; // fully qualified intermediary class name when using nspace feature, otherwise same as imclass_name - String *variable_name; //Name of a variable being wrapped - String *proxy_class_constants_code; - String *module_class_constants_code; - String *enum_code; - String *package; // Optional package name - String *jnipackage; // Package name used in the JNI code - String *package_path; // Package name used internally by JNI (slashes) - String *imclass_imports; //intermediary class imports from %pragma - String *module_imports; //module imports from %pragma - String *imclass_baseclass; //inheritance for intermediary class class from %pragma - String *imclass_package; //package in which to generate the intermediary class - String *module_baseclass; //inheritance for module class from %pragma - String *imclass_interfaces; //interfaces for intermediary class class from %pragma - String *module_interfaces; //interfaces for module class from %pragma - String *imclass_class_modifiers; //class modifiers for intermediary class overridden by %pragma - String *module_class_modifiers; //class modifiers for module class overridden by %pragma - String *upcasts_code; //C++ casts for inheritance hierarchies C++ code - String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code - String *imclass_directors; // Intermediate class director code - String *destructor_call; //C++ destructor call if any - String *destructor_throws_clause; //C++ destructor throws clause if any - - // Director method stuff: - List *dmethods_seq; - Hash *dmethods_table; - int n_dmethods; - int n_directors; - int first_class_dmethod; - int curr_class_dmethod; - int nesting_depth; - - enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum }; - -public: - - /* ----------------------------------------------------------------------------- - * JAVA() - * ----------------------------------------------------------------------------- */ - - JAVA():empty_string(NewString("")), - public_string(NewString("public")), - protected_string(NewString("protected")), - swig_types_hash(NULL), - f_begin(NULL), - f_runtime(NULL), - f_runtime_h(NULL), - f_header(NULL), - f_wrappers(NULL), - f_init(NULL), - f_directors(NULL), - f_directors_h(NULL), - filenames_list(NULL), - proxy_flag(true), - nopgcpp_flag(false), - native_function_flag(false), - enum_constant_flag(false), - static_flag(false), - variable_wrapper_flag(false), - wrapping_member_flag(false), - global_variable_flag(false), - old_variable_names(false), - member_func_flag(false), - doxygen(false), - comment_creation_chatter(false), - imclass_name(NULL), - module_class_name(NULL), - constants_interface_name(NULL), - imclass_class_code(NULL), - proxy_class_def(NULL), - proxy_class_code(NULL), - interface_class_code(NULL), - module_class_code(NULL), - proxy_class_name(NULL), - full_proxy_class_name(NULL), - full_imclass_name(NULL), - variable_name(NULL), - proxy_class_constants_code(NULL), - module_class_constants_code(NULL), - enum_code(NULL), - package(NULL), - jnipackage(NULL), - package_path(NULL), - imclass_imports(NULL), - module_imports(NULL), - imclass_baseclass(NULL), - imclass_package(NULL), - module_baseclass(NULL), - imclass_interfaces(NULL), - module_interfaces(NULL), - imclass_class_modifiers(NULL), - module_class_modifiers(NULL), - upcasts_code(NULL), - imclass_cppcasts_code(NULL), - imclass_directors(NULL), - destructor_call(NULL), - destructor_throws_clause(NULL), - dmethods_seq(NULL), - dmethods_table(NULL), - n_dmethods(0), - n_directors(0), - first_class_dmethod(0), - curr_class_dmethod(0), - nesting_depth(0){ - /* for now, multiple inheritance in directors is disabled, this - should be easy to implement though */ - director_multiple_inheritance = 0; - director_language = 1; - } - - ~JAVA() { - delete doxygenTranslator; - } - - /* ----------------------------------------------------------------------------- - * constructIntermediateClassName() - * - * Construct the fully qualified name of the intermediate class and set - * the full_imclass_name attribute accordingly. - * ----------------------------------------------------------------------------- */ - void constructIntermediateClassName(Node *n) { - String *nspace = Getattr(n, "sym:nspace"); - - if (imclass_package && package) - full_imclass_name = NewStringf("%s.%s.%s", package, imclass_package, imclass_name); - else if (package && nspace) - full_imclass_name = NewStringf("%s.%s", package, imclass_name); - else if (imclass_package) - full_imclass_name = NewStringf("%s.%s", imclass_package, imclass_name); - else - full_imclass_name = NewStringf("%s", imclass_name); - - if (nspace && !package) { - String *name = Getattr(n, "name") ? Getattr(n, "name") : NewString("<unnamed>"); - Swig_warning(WARN_JAVA_NSPACE_WITHOUT_PACKAGE, Getfile(n), Getline(n), - "The nspace feature is used on '%s' without -package. " - "The generated code may not compile as Java does not support types declared in a named package accessing types declared in an unnamed package.\n", SwigType_namestr(name)); - } - } - - /* ----------------------------------------------------------------------------- - * getProxyName() - * - * Test to see if a type corresponds to something wrapped with a proxy class. - * Return NULL if not otherwise the proxy class name, fully qualified with - * package name if the nspace feature is used, unless jnidescriptor is true as - * the package name is handled differently (unfortunately for legacy reasons). - * ----------------------------------------------------------------------------- */ - - String *getProxyName(SwigType *t, bool jnidescriptor = false) { - String *proxyname = NULL; - if (proxy_flag) { - Node *n = classLookup(t); - if (n) { - proxyname = Getattr(n, "proxyname"); - if (!proxyname || jnidescriptor) { - String *nspace = Getattr(n, "sym:nspace"); - String *symname = Copy(Getattr(n, "sym:name")); - if (symname && !GetFlag(n, "feature:flatnested")) { - for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) { - if (String* name = Getattr(outer_class, "sym:name")) { - Push(symname, jnidescriptor ? "$" : "."); - Push(symname, name); - } - else - return NULL; - } - } - if (nspace) { - if (package && !jnidescriptor) - proxyname = NewStringf("%s.%s.%s", package, nspace, symname); - else - proxyname = NewStringf("%s.%s", nspace, symname); - } else { - proxyname = Copy(symname); - } - if (!jnidescriptor) { - Setattr(n, "proxyname", proxyname); // Cache it - Delete(proxyname); - } - Delete(symname); - } - } - } - return proxyname; - } - - /* ----------------------------------------------------------------------------- - * makeValidJniName() - * ----------------------------------------------------------------------------- */ - - String *makeValidJniName(const String *name) { - String *valid_jni_name = NewString(name); - Replaceall(valid_jni_name, "_", "_1"); - return valid_jni_name; - } - - /* ------------------------------------------------------------ - * main() - * ------------------------------------------------------------ */ - - virtual void main(int argc, char *argv[]) { - - SWIG_library_directory("java"); - - int doxygen_translator_flags = 0; - - // Look for certain command line options - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-package") == 0) { - if (argv[i + 1]) { - package = NewString(""); - Printf(package, argv[i + 1]); - if (Len(package) == 0) { - Delete(package); - package = 0; - } - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) { - Printf(stderr, "Deprecated command line option: %s. Proxy classes are now generated by default.\n", argv[i]); - Swig_mark_arg(i); - proxy_flag = true; - } else if ((strcmp(argv[i], "-doxygen") == 0)) { - Swig_mark_arg(i); - doxygen = true; - scan_doxygen_comments = true; - } else if ((strcmp(argv[i], "-debug-doxygen-translator") == 0)) { - Swig_mark_arg(i); - doxygen_translator_flags |= DoxygenTranslator::debug_translator; - } else if ((strcmp(argv[i], "-debug-doxygen-parser") == 0)) { - Swig_mark_arg(i); - doxygen_translator_flags |= DoxygenTranslator::debug_parser; - } else if ((strcmp(argv[i], "-noproxy") == 0)) { - Swig_mark_arg(i); - proxy_flag = false; - } else if (strcmp(argv[i], "-nopgcpp") == 0) { - Swig_mark_arg(i); - nopgcpp_flag = true; - } else if (strcmp(argv[i], "-oldvarnames") == 0) { - Swig_mark_arg(i); - old_variable_names = true; - } else if (strcmp(argv[i], "-jnic") == 0) { - Swig_mark_arg(i); - Printf(stderr, "Deprecated command line option: -jnic. C JNI calling convention now used when -c++ not specified.\n"); - } else if (strcmp(argv[i], "-nofinalize") == 0) { - Swig_mark_arg(i); - Printf(stderr, "Deprecated command line option: -nofinalize. Use the new javafinalize typemap instead.\n"); - } else if (strcmp(argv[i], "-jnicpp") == 0) { - Swig_mark_arg(i); - Printf(stderr, "Deprecated command line option: -jnicpp. C++ JNI calling convention now used when -c++ specified.\n"); - } else if (strcmp(argv[i], "-help") == 0) { - Printf(stdout, "%s\n", usage); - } - } - } - - if (doxygen) - doxygenTranslator = new JavaDocConverter(doxygen_translator_flags); - - // Add a symbol to the parser for conditional compilation - Preprocessor_define("SWIGJAVA 1", 0); - - // Add typemap definitions - SWIG_typemap_lang("java"); - SWIG_config_file("java.swg"); - - allow_overloading(); - Swig_interface_feature_enable(); - } - - /* --------------------------------------------------------------------- - * top() - * --------------------------------------------------------------------- */ - - virtual int top(Node *n) { - - // Get any options set in the module directive - Node *optionsnode = Getattr(Getattr(n, "module"), "options"); - - if (optionsnode) { - if (Getattr(optionsnode, "jniclassname")) - imclass_name = Copy(Getattr(optionsnode, "jniclassname")); - /* check if directors are enabled for this module. note: this - * is a "master" switch, without which no director code will be - * emitted. %feature("director") statements are also required - * to enable directors for individual classes or methods. - * - * use %module(directors="1") modulename at the start of the - * interface file to enable director generation. - */ - if (Getattr(optionsnode, "directors")) { - allow_directors(); - } - if (Getattr(optionsnode, "dirprot")) { - allow_dirprot(); - } - allow_allprotected(GetFlag(optionsnode, "allprotected")); - } - - /* Initialize all of the output files */ - String *outfile = Getattr(n, "outfile"); - String *outfile_h = Getattr(n, "outfile_h"); - - if (!outfile) { - Printf(stderr, "Unable to determine outfile\n"); - Exit(EXIT_FAILURE); - } - - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - - if (directorsEnabled()) { - if (!outfile_h) { - Printf(stderr, "Unable to determine outfile_h\n"); - Exit(EXIT_FAILURE); - } - f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); - if (!f_runtime_h) { - FileErrorDisplay(outfile_h); - Exit(EXIT_FAILURE); - } - } - - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - f_wrappers = NewString(""); - f_directors_h = NewString(""); - f_directors = NewString(""); - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", f_init); - Swig_register_filebyname("director", f_directors); - Swig_register_filebyname("director_h", f_directors_h); - - swig_types_hash = NewHash(); - filenames_list = NewList(); - - // Make the intermediary class and module class names. The intermediary class name can be set in the module directive. - if (!imclass_name) { - imclass_name = NewStringf("%sJNI", Getattr(n, "name")); - module_class_name = Copy(Getattr(n, "name")); - } else { - // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution - if (Cmp(imclass_name, Getattr(n, "name")) == 0) - module_class_name = NewStringf("%sModule", Getattr(n, "name")); - else - module_class_name = Copy(Getattr(n, "name")); - } - constants_interface_name = NewStringf("%sConstants", module_class_name); - - // module class and intermediary classes are always created - if (!addSymbol(imclass_name, n)) - return SWIG_ERROR; - if (!addSymbol(module_class_name, n)) - return SWIG_ERROR; - - imclass_class_code = NewString(""); - proxy_class_def = NewString(""); - proxy_class_code = NewString(""); - module_class_constants_code = NewString(""); - imclass_baseclass = NewString(""); - imclass_package = NULL; - imclass_interfaces = NewString(""); - imclass_class_modifiers = NewString(""); - module_class_code = NewString(""); - module_baseclass = NewString(""); - module_interfaces = NewString(""); - module_imports = NewString(""); - module_class_modifiers = NewString(""); - imclass_imports = NewString(""); - imclass_cppcasts_code = NewString(""); - imclass_directors = NewString(""); - upcasts_code = NewString(""); - dmethods_seq = NewList(); - dmethods_table = NewHash(); - n_dmethods = 0; - n_directors = 0; - jnipackage = NewString(""); - package_path = NewString(""); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "JAVA"); - - if (directorsEnabled()) { - Printf(f_runtime, "#define SWIG_DIRECTORS\n"); - - /* Emit initial director header and director code: */ - Swig_banner(f_directors_h); - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_class_name); - Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_class_name); - - Printf(f_directors, "\n\n"); - Printf(f_directors, "/* ---------------------------------------------------\n"); - Printf(f_directors, " * C++ director class methods\n"); - Printf(f_directors, " * --------------------------------------------------- */\n\n"); - if (outfile_h) { - String *filename = Swig_file_filename(outfile_h); - Printf(f_directors, "#include \"%s\"\n\n", filename); - Delete(filename); - } - } - - Printf(f_runtime, "\n"); - - String *wrapper_name = NewString(""); - - if (package) { - String *jniname = makeValidJniName(package); - Printv(jnipackage, jniname, NIL); - Delete(jniname); - Replaceall(jnipackage, ".", "_"); - Append(jnipackage, "_"); - Printv(package_path, package, NIL); - Replaceall(package_path, ".", "/"); - } - String *jniname = makeValidJniName(imclass_name); - Printf(wrapper_name, "Java_%s%s_%%f", jnipackage, jniname); - Delete(jniname); - - Swig_name_register("wrapper", Char(wrapper_name)); - if (old_variable_names) { - Swig_name_register("set", "set_%n%v"); - Swig_name_register("get", "get_%n%v"); - } - - Delete(wrapper_name); - - Printf(f_wrappers, "\n#ifdef __cplusplus\n"); - Printf(f_wrappers, "extern \"C\" {\n"); - Printf(f_wrappers, "#endif\n\n"); - - /* Emit code */ - Language::top(n); - - if (directorsEnabled()) { - // Insert director runtime into the f_runtime file (make it occur before %header section) - Swig_insert_file("director_common.swg", f_runtime); - Swig_insert_file("director.swg", f_runtime); - } - // Generate the intermediary class - { - String *filen = NewStringf("%s%s.java", outputDirectory(imclass_package), imclass_name); - File *f_im = NewFile(filen, "w", SWIG_output_files()); - if (!f_im) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the intermediary class file - emitBanner(f_im); - - if (imclass_package && package) - Printf(f_im, "package %s.%s;", package, imclass_package); - else if (imclass_package) - Printf(f_im, "package %s;", imclass_package); - else if (package) - Printf(f_im, "package %s;\n", package); - - if (imclass_imports) - Printf(f_im, "%s\n", imclass_imports); - - if (Len(imclass_class_modifiers) > 0) - Printf(f_im, "%s ", imclass_class_modifiers); - Printf(f_im, "%s ", imclass_name); - - if (imclass_baseclass && *Char(imclass_baseclass)) - Printf(f_im, "extends %s ", imclass_baseclass); - if (Len(imclass_interfaces) > 0) - Printv(f_im, "implements ", imclass_interfaces, " ", NIL); - Printf(f_im, "{\n"); - - // Add the intermediary class methods - Replaceall(imclass_class_code, "$module", module_class_name); - Replaceall(imclass_class_code, "$imclassname", imclass_name); - Printv(f_im, imclass_class_code, NIL); - Printv(f_im, imclass_cppcasts_code, NIL); - if (Len(imclass_directors) > 0) - Printv(f_im, "\n", imclass_directors, NIL); - - if (n_dmethods > 0) { - Putc('\n', f_im); - Printf(f_im, " private final static native void swig_module_init();\n"); - Printf(f_im, " static {\n"); - Printf(f_im, " swig_module_init();\n"); - Printf(f_im, " }\n"); - } - // Finish off the class - Printf(f_im, "}\n"); - Delete(f_im); - } - - // Generate the Java module class - { - String *filen = NewStringf("%s%s.java", SWIG_output_directory(), module_class_name); - File *f_module = NewFile(filen, "w", SWIG_output_files()); - if (!f_module) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the module class file - emitBanner(f_module); - - if (package) - Printf(f_module, "package %s;\n", package); - - if (module_imports) - Printf(f_module, "%s\n", module_imports); - - if (doxygen && doxygenTranslator->hasDocumentation(n)) { - String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0); - if (comment_creation_chatter) - Printf(f_module, "/* This was generated from top() */\n"); - Printv(f_module, Char(doxygen_comments), NIL); - Delete(doxygen_comments); - } - if (Len(module_class_modifiers) > 0) - Printf(f_module, "%s ", module_class_modifiers); - Printf(f_module, "%s ", module_class_name); - - if (module_baseclass && *Char(module_baseclass)) - Printf(f_module, "extends %s ", module_baseclass); - if (Len(module_interfaces) > 0) { - if (Len(module_class_constants_code) != 0) - Printv(f_module, "implements ", constants_interface_name, ", ", module_interfaces, " ", NIL); - else - Printv(f_module, "implements ", module_interfaces, " ", NIL); - } else { - if (Len(module_class_constants_code) != 0) - Printv(f_module, "implements ", constants_interface_name, " ", NIL); - } - Printf(f_module, "{\n"); - - Replaceall(module_class_code, "$module", module_class_name); - Replaceall(module_class_constants_code, "$module", module_class_name); - - Replaceall(module_class_code, "$imclassname", imclass_name); - Replaceall(module_class_constants_code, "$imclassname", imclass_name); - - // Add the wrapper methods - Printv(f_module, module_class_code, NIL); - - // Finish off the class - Printf(f_module, "}\n"); - Delete(f_module); - } - - // Generate the Java constants interface - if (Len(module_class_constants_code) != 0) { - String *filen = NewStringf("%s%s.java", SWIG_output_directory(), constants_interface_name); - File *f_module = NewFile(filen, "w", SWIG_output_files()); - if (!f_module) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the Java constants interface file - emitBanner(f_module); - - if (package) - Printf(f_module, "package %s;\n", package); - - if (module_imports) - Printf(f_module, "%s\n", module_imports); - - Printf(f_module, "public interface %s {\n", constants_interface_name); - - // Write out all the global constants - Printv(f_module, module_class_constants_code, NIL); - - // Finish off the Java interface - Printf(f_module, "}\n"); - Delete(f_module); - } - - if (upcasts_code) - Printv(f_wrappers, upcasts_code, NIL); - - emitDirectorUpcalls(); - - Printf(f_wrappers, "#ifdef __cplusplus\n"); - Printf(f_wrappers, "}\n"); - Printf(f_wrappers, "#endif\n"); - - // Output a Java type wrapper class for each SWIG type - for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) { - emitTypeWrapperClass(swig_type.key, swig_type.item); - } - - // Check for overwriting file problems on filesystems that are case insensitive - Iterator it1; - Iterator it2; - for (it1 = First(filenames_list); it1.item; it1 = Next(it1)) { - String *item1_lower = Swig_string_lower(it1.item); - for (it2 = Next(it1); it2.item; it2 = Next(it2)) { - String *item2_lower = Swig_string_lower(it2.item); - if (it1.item && it2.item) { - if (Strcmp(item1_lower, item2_lower) == 0) { - Swig_warning(WARN_LANG_PORTABILITY_FILENAME, input_file, line_number, - "Portability warning: File %s will be overwritten by %s on case insensitive filesystems such as " - "Windows' FAT32 and NTFS unless the class/module name is renamed\n", it1.item, it2.item); - } - } - Delete(item2_lower); - } - Delete(item1_lower); - } - - Delete(swig_types_hash); - swig_types_hash = NULL; - Delete(filenames_list); - filenames_list = NULL; - Delete(imclass_name); - imclass_name = NULL; - Delete(imclass_class_code); - imclass_class_code = NULL; - Delete(proxy_class_def); - proxy_class_def = NULL; - Delete(proxy_class_code); - proxy_class_code = NULL; - Delete(module_class_constants_code); - module_class_constants_code = NULL; - Delete(imclass_baseclass); - imclass_baseclass = NULL; - Delete(imclass_package); - imclass_package = NULL; - Delete(imclass_interfaces); - imclass_interfaces = NULL; - Delete(imclass_class_modifiers); - imclass_class_modifiers = NULL; - Delete(module_class_name); - module_class_name = NULL; - Delete(constants_interface_name); - constants_interface_name = NULL; - Delete(module_class_code); - module_class_code = NULL; - Delete(module_baseclass); - module_baseclass = NULL; - Delete(module_interfaces); - module_interfaces = NULL; - Delete(module_imports); - module_imports = NULL; - Delete(module_class_modifiers); - module_class_modifiers = NULL; - Delete(imclass_imports); - imclass_imports = NULL; - Delete(imclass_cppcasts_code); - imclass_cppcasts_code = NULL; - Delete(imclass_directors); - imclass_directors = NULL; - Delete(upcasts_code); - upcasts_code = NULL; - Delete(package); - package = NULL; - Delete(jnipackage); - jnipackage = NULL; - Delete(package_path); - package_path = NULL; - Delete(dmethods_seq); - dmethods_seq = NULL; - Delete(dmethods_table); - dmethods_table = NULL; - n_dmethods = 0; - - /* Close all of the files */ - Dump(f_header, f_runtime); - - if (directorsEnabled()) { - Dump(f_directors, f_runtime); - Dump(f_directors_h, f_runtime_h); - - Printf(f_runtime_h, "\n"); - Printf(f_runtime_h, "#endif\n"); - - Delete(f_runtime_h); - f_runtime_h = NULL; - Delete(f_directors); - f_directors = NULL; - Delete(f_directors_h); - f_directors_h = NULL; - } - - Dump(f_wrappers, f_runtime); - Wrapper_pretty_print(f_init, f_runtime); - Delete(f_header); - Delete(f_wrappers); - Delete(f_init); - Dump(f_runtime, f_begin); - Delete(f_runtime); - Delete(f_begin); - return SWIG_OK; - } - - /* ----------------------------------------------------------------------------- - * emitBanner() - * ----------------------------------------------------------------------------- */ - - void emitBanner(File *f) { - Printf(f, "/* ----------------------------------------------------------------------------\n"); - Swig_banner_target_lang(f, " *"); - Printf(f, " * ----------------------------------------------------------------------------- */\n\n"); - } - - /*----------------------------------------------------------------------- - * Add new director upcall signature - *----------------------------------------------------------------------*/ - - UpcallData *addUpcallMethod(String *imclass_method, String *class_method, String *imclass_desc, String *class_desc, String *decl) { - String *key = NewStringf("%s|%s", imclass_method, decl); - - ++curr_class_dmethod; - - String *imclass_methodidx = NewStringf("%d", n_dmethods); - String *class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod); - n_dmethods++; - - Hash *new_udata = NewHash(); - Append(dmethods_seq, new_udata); - Setattr(dmethods_table, key, new_udata); - - Setattr(new_udata, "method", Copy(class_method)); - Setattr(new_udata, "fdesc", Copy(class_desc)); - Setattr(new_udata, "imclass_method", Copy(imclass_method)); - Setattr(new_udata, "imclass_fdesc", Copy(imclass_desc)); - Setattr(new_udata, "imclass_methodidx", imclass_methodidx); - Setattr(new_udata, "class_methodidx", class_methodidx); - Setattr(new_udata, "decl", Copy(decl)); - - Delete(key); - return new_udata; - } - - /*----------------------------------------------------------------------- - * Get director upcall signature - *----------------------------------------------------------------------*/ - - UpcallData *getUpcallMethodData(String *director_class, String *decl) { - String *key = NewStringf("%s|%s", director_class, decl); - UpcallData *udata = Getattr(dmethods_table, key); - - Delete(key); - return udata; - } - - /* ---------------------------------------------------------------------- - * nativeWrapper() - * ---------------------------------------------------------------------- */ - - virtual int nativeWrapper(Node *n) { - String *wrapname = Getattr(n, "wrap:name"); - - if (!addSymbol(wrapname, n, imclass_name)) - return SWIG_ERROR; - - if (Getattr(n, "type")) { - Swig_save("nativeWrapper", n, "name", NIL); - Setattr(n, "name", wrapname); - native_function_flag = true; - functionWrapper(n); - Swig_restore(n); - native_function_flag = false; - } else { - Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name")); - } - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * functionWrapper() - * ---------------------------------------------------------------------- */ - - virtual int functionWrapper(Node *n) { - String *symname = Getattr(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - String *tm; - Parm *p; - int i; - String *c_return_type = NewString(""); - String *im_return_type = NewString(""); - String *cleanup = NewString(""); - String *outarg = NewString(""); - String *body = NewString(""); - int num_arguments = 0; - int gencomma = 0; - bool is_void_return; - String *overloaded_name = getOverloadedName(n); - String *nondir_args = NewString(""); - bool is_destructor = (Cmp(Getattr(n, "nodeType"), "destructor") == 0); - - if (!Getattr(n, "sym:overloaded")) { - if (!addSymbol(symname, n, imclass_name)) - return SWIG_ERROR; - } - - /* - The rest of this function deals with generating the intermediary class wrapper function (that wraps - a c/c++ function) and generating the JNI c code. Each Java wrapper function has a - matching JNI c function call. - */ - - // A new wrapper function object - Wrapper *f = NewWrapper(); - - // Make a wrapper name for this function - String *jniname = makeValidJniName(overloaded_name); - String *wname = Swig_name_wrapper(jniname); - - Delete(jniname); - - /* Attach the non-standard typemaps to the parameter list. */ - Swig_typemap_attach_parms("jni", l, f); - Swig_typemap_attach_parms("jtype", l, f); - Swig_typemap_attach_parms("jstype", l, f); - - /* Get return types */ - if ((tm = Swig_typemap_lookup("jni", n, "", 0))) { - Printf(c_return_type, "%s", tm); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(t, 0)); - } - - if ((tm = Swig_typemap_lookup("jtype", n, "", 0))) { - Printf(im_return_type, "%s", tm); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(t, 0)); - } - - is_void_return = (Cmp(c_return_type, "void") == 0); - if (!is_void_return) - Wrapper_add_localv(f, "jresult", c_return_type, "jresult = 0", NIL); - - Printv(f->def, "SWIGEXPORT ", c_return_type, " JNICALL ", wname, "(JNIEnv *jenv, jclass jcls", NIL); - - // Usually these function parameters are unused - The code below ensures - // that compilers do not issue such a warning if configured to do so. - - Printv(f->code, " (void)jenv;\n", NIL); - Printv(f->code, " (void)jcls;\n", NIL); - - // Emit all of the local variables for holding arguments. - emit_parameter_variables(l, f); - - /* Attach the standard typemaps */ - emit_attach_parmmaps(l, f); - - // Parameter overloading - Setattr(n, "wrap:parms", l); - Setattr(n, "wrap:name", wname); - - // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java - if (Getattr(n, "sym:overloaded")) { - // Emit warnings for the few cases that can't be overloaded in Java and give up on generating wrapper - Swig_overload_check(n); - if (Getattr(n, "overload:ignore")) { - DelWrapper(f); - return SWIG_OK; - } - } - - Printf(imclass_class_code, " public final static native %s %s(", im_return_type, overloaded_name); - - num_arguments = emit_num_arguments(l); - - // Now walk the function parameter list and generate code to get arguments - for (i = 0, p = l; i < num_arguments; i++) { - - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *ln = Getattr(p, "lname"); - String *im_param_type = NewString(""); - String *c_param_type = NewString(""); - String *arg = NewString(""); - - Printf(arg, "j%s", ln); - - /* Get the JNI C types of the parameter */ - if ((tm = Getattr(p, "tmap:jni"))) { - Printv(c_param_type, tm, NIL); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Get the intermediary class parameter types of the parameter */ - if ((tm = Getattr(p, "tmap:jtype"))) { - Printv(im_param_type, tm, NIL); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Add parameter to intermediary class method */ - if (gencomma) - Printf(imclass_class_code, ", "); - Printf(imclass_class_code, "%s %s", im_param_type, arg); - - // Add parameter to C function - Printv(f->def, ", ", c_param_type, " ", arg, NIL); - - ++gencomma; - - // Premature garbage collection prevention parameter - if (!is_destructor) { - String *pgc_parameter = prematureGarbageCollectionPreventionParameter(pt, p); - if (pgc_parameter) { - Printf(imclass_class_code, ", %s %s_", pgc_parameter, arg); - Printf(f->def, ", jobject %s_", arg); - Printf(f->code, " (void)%s_;\n", arg); - } - } - // Get typemap for this argument - if ((tm = Getattr(p, "tmap:in"))) { - addThrows(n, "tmap:in", p); - Replaceall(tm, "$arg", arg); /* deprecated? */ - Replaceall(tm, "$input", arg); - Setattr(p, "emit:input", arg); - - Printf(nondir_args, "%s\n", tm); - - p = Getattr(p, "tmap:in:next"); - } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); - p = nextSibling(p); - } - - Delete(im_param_type); - Delete(c_param_type); - Delete(arg); - } - - Printv(f->code, nondir_args, NIL); - Delete(nondir_args); - - /* Insert constraint checking code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - addThrows(n, "tmap:check", p); - Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */ - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert cleanup code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:freearg"))) { - addThrows(n, "tmap:freearg", p); - Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */ - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(cleanup, tm, "\n", NIL); - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert argument output code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - addThrows(n, "tmap:argout", p); - Replaceall(tm, "$arg", Getattr(p, "emit:input")); /* deprecated? */ - Replaceall(tm, "$result", "jresult"); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - // Get any Java exception classes in the throws typemap - ParmList *throw_parm_list = NULL; - if ((throw_parm_list = Getattr(n, "catchlist"))) { - Swig_typemap_attach_parms("throws", throw_parm_list, f); - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - addThrows(n, "tmap:throws", p); - } - } - } - - // Now write code to make the function call - if (!native_function_flag) { - - Swig_director_emit_dynamic_cast(n, f); - String *actioncode = emit_action(n); - - // Handle exception classes specified in the "except" feature's "throws" attribute - addThrows(n, "feature:except", n); - - /* Return value if necessary */ - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { - addThrows(n, "tmap:out", n); - Replaceall(tm, "$result", "jresult"); - - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "1"); - else - Replaceall(tm, "$owner", "0"); - - Printf(f->code, "%s", tm); - if (Len(tm)) - Printf(f->code, "\n"); - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name")); - } - emit_return_variable(n, t, f); - } - - /* Output argument output code */ - Printv(f->code, outarg, NIL); - - /* Output cleanup code */ - Printv(f->code, cleanup, NIL); - - /* Look to see if there is any newfree cleanup code */ - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - addThrows(n, "tmap:newfree", n); - Printf(f->code, "%s\n", tm); - } - } - - /* See if there is any return cleanup code */ - if (!native_function_flag) { - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - addThrows(n, "tmap:ret", n); - Printf(f->code, "%s\n", tm); - } - } - - /* Finish C function and intermediary class function definitions */ - Printf(imclass_class_code, ")"); - generateThrowsClause(n, imclass_class_code); - Printf(imclass_class_code, ";\n"); - - Printf(f->def, ") {"); - - if (!is_void_return) - Printv(f->code, " return jresult;\n", NIL); - Printf(f->code, "}\n"); - - /* Substitute the cleanup code */ - Replaceall(f->code, "$cleanup", cleanup); - - /* Substitute the function name */ - Replaceall(f->code, "$symname", symname); - - /* Contract macro modification */ - Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, "); - - if (!is_void_return) - Replaceall(f->code, "$null", "0"); - else - Replaceall(f->code, "$null", ""); - - /* Dump the function out */ - if (!native_function_flag) - Wrapper_print(f, f_wrappers); - - if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) { - moduleClassFunctionHandler(n); - } - - /* - * Generate the proxy class getters/setters for public member variables. - * Not for enums and constants. - */ - if (proxy_flag && wrapping_member_flag && !enum_constant_flag) { - // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name - bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) != 0; - - String *getter_setter_name = NewString(""); - if (!getter_flag) - Printf(getter_setter_name, "set"); - else - Printf(getter_setter_name, "get"); - Putc(toupper((int) *Char(variable_name)), getter_setter_name); - Printf(getter_setter_name, "%s", Char(variable_name) + 1); - - Setattr(n, "proxyfuncname", getter_setter_name); - Setattr(n, "imfuncname", symname); - - proxyClassFunctionHandler(n); - Delete(getter_setter_name); - } - - Delete(c_return_type); - Delete(im_return_type); - Delete(cleanup); - Delete(outarg); - Delete(body); - Delete(overloaded_name); - DelWrapper(f); - return SWIG_OK; - } - - /* ----------------------------------------------------------------------- - * variableWrapper() - * ----------------------------------------------------------------------- */ - - virtual int variableWrapper(Node *n) { - variable_wrapper_flag = true; - Language::variableWrapper(n); /* Default to functions */ - variable_wrapper_flag = false; - return SWIG_OK; - } - - /* ----------------------------------------------------------------------- - * globalvariableHandler() - * ------------------------------------------------------------------------ */ - - virtual int globalvariableHandler(Node *n) { - - variable_name = Getattr(n, "sym:name"); - global_variable_flag = true; - int ret = Language::globalvariableHandler(n); - global_variable_flag = false; - return ret; - } - - String *getCurrentScopeName(String *nspace) { - String *scope = 0; - if (nspace || getCurrentClass()) { - scope = NewString(""); - if (nspace) - Printf(scope, "%s", nspace); - if (Node* cls = getCurrentClass()) { - if (Node *outer = Getattr(cls, "nested:outer")) { - String *outerClassesPrefix = Copy(Getattr(outer, "sym:name")); - for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) { - Push(outerClassesPrefix, "."); - Push(outerClassesPrefix, Getattr(outer, "sym:name")); - } - Printv(scope, nspace ? "." : "", outerClassesPrefix, ".", proxy_class_name, NIL); - Delete(outerClassesPrefix); - } else - Printv(scope, nspace ? "." : "", proxy_class_name, NIL); - } - } - return scope; - } - - /* ---------------------------------------------------------------------- - * enumDeclaration() - * - * C/C++ enums can be mapped in one of 4 ways, depending on the java:enum feature specified: - * 1) Simple enums - simple constant within the proxy class or module class - * 2) Typeunsafe enums - simple constant in a Java class (class named after the c++ enum name) - * 3) Typesafe enum - typesafe enum pattern (class named after the c++ enum name) - * 4) Proper enums - proper Java enum - * Anonymous enums always default to 1) - * ---------------------------------------------------------------------- */ - - virtual int enumDeclaration(Node *n) { - - if (!ImportMode) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call - if (proxy_flag && !is_wrapping_class()) { - // Global enums / enums in a namespace - assert(!full_imclass_name); - constructIntermediateClassName(n); - } - - enum_code = NewString(""); - String *symname = Getattr(n, "sym:name"); - String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code; - EnumFeature enum_feature = decodeEnumFeature(n); - String *typemap_lookup_type = Getattr(n, "name"); - - if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) { - // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum - - if (doxygen && doxygenTranslator->hasDocumentation(n)) { - String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0); - if (comment_creation_chatter) - Printf(enum_code, "/* This was generated from enumDeclaration() */\n"); - Printv(enum_code, Char(doxygen_comments), NIL); - Delete(doxygen_comments); - } - - String *scope = getCurrentScopeName(nspace); - if (!addSymbol(symname, n, scope)) - return SWIG_ERROR; - - // Pure Java baseclass and interfaces - const String *pure_baseclass = typemapLookup(n, "javabase", typemap_lookup_type, WARN_NONE); - const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE); - - // Emit the enum - Printv(enum_code, typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers (enum modifiers really) - " ", symname, *Char(pure_baseclass) ? // Bases - " extends " : "", pure_baseclass, *Char(pure_interfaces) ? // Interfaces - " implements " : "", pure_interfaces, " {\n", NIL); - if (proxy_flag && is_wrapping_class()) - Replaceall(enum_code, "$static ", "static "); - else - Replaceall(enum_code, "$static ", ""); - Delete(scope); - } else { - if (symname && !Getattr(n, "unnamedinstance")) - Printf(constants_code, " // %s \n", symname); - // Translate and write javadoc comment for the enum itself if flagged - if (doxygen && doxygenTranslator->hasDocumentation(n)) { - String *doxygen_comments = doxygenTranslator->getDocumentation(n, " "); - if (comment_creation_chatter) - Printf(constants_code, "/* This was generated from enumDeclaration() */\n"); - Printf(constants_code, Char(doxygen_comments)); - Printf(constants_code, "\n"); - Delete(doxygen_comments); - } - } - - // Emit each enum item - Language::enumDeclaration(n); - - if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) { - // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum - // Finish the enum declaration - // Typemaps are used to generate the enum definition in a similar manner to proxy classes. - Printv(enum_code, (enum_feature == ProperEnum) ? ";\n" : "", typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class - typemapLookup(n, "javacode", typemap_lookup_type, WARN_NONE), // extra Java code - "}", NIL); - - Replaceall(enum_code, "$javaclassname", symname); - - // Substitute $enumvalues - intended usage is for typesafe enums - if (Getattr(n, "enumvalues")) - Replaceall(enum_code, "$enumvalues", Getattr(n, "enumvalues")); - else - Replaceall(enum_code, "$enumvalues", ""); - - if (proxy_flag && is_wrapping_class()) { - // Enums defined within the C++ class are defined within the proxy class - - // Add extra indentation - Replaceall(enum_code, "\n", "\n "); - Replaceall(enum_code, " \n", "\n"); - Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL); - } else { - // Global enums are defined in their own file - String *output_directory = outputDirectory(nspace); - String *filen = NewStringf("%s%s.java", output_directory, symname); - File *f_enum = NewFile(filen, "w", SWIG_output_files()); - if (!f_enum) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the enum file - emitBanner(f_enum); - - if (package || nspace) { - Printf(f_enum, "package "); - if (package) - Printv(f_enum, package, nspace ? "." : "", NIL); - if (nspace) - Printv(f_enum, nspace, NIL); - Printf(f_enum, ";\n"); - } - - Printv(f_enum, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE), // Import statements - "\n", enum_code, "\n", NIL); - - Printf(f_enum, "\n"); - Delete(f_enum); - Delete(output_directory); - } - } else { - // Wrap C++ enum with simple constant - Printf(enum_code, "\n"); - if (proxy_flag && is_wrapping_class()) - Printv(proxy_class_constants_code, enum_code, NIL); - else - Printv(module_class_constants_code, enum_code, NIL); - } - - Delete(enum_code); - enum_code = NULL; - - if (proxy_flag && !is_wrapping_class()) { - Delete(full_imclass_name); - full_imclass_name = 0; - } - } - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * enumvalueDeclaration() - * ---------------------------------------------------------------------- */ - - virtual int enumvalueDeclaration(Node *n) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL); - String *symname = Getattr(n, "sym:name"); - String *value = Getattr(n, "value"); - String *name = Getattr(n, "name"); - Node *parent = parentNode(n); - int unnamedinstance = GetFlag(parent, "unnamedinstance"); - String *parent_name = Getattr(parent, "name"); - String *nspace = getNSpace(); - String *newsymname = 0; - String *tmpValue; - - // Strange hack from parent method - if (value) - tmpValue = NewString(value); - else - tmpValue = NewString(name); - // Note that this is used in enumValue() amongst other places - Setattr(n, "value", tmpValue); - - // Deal with enum values that are not int - int swigtype = SwigType_type(Getattr(n, "type")); - if (swigtype == T_BOOL) { - const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0"; - Setattr(n, "enumvalue", val); - } else if (swigtype == T_CHAR) { - String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue")); - Setattr(n, "enumvalue", val); - Delete(val); - } - - { - EnumFeature enum_feature = decodeEnumFeature(parent); - - if ((enum_feature == SimpleEnum) && GetFlag(parent, "scopedenum")) { - newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname); - symname = newsymname; - } - - // Add to language symbol table - String *scope = 0; - if (unnamedinstance || !parent_name || enum_feature == SimpleEnum) { - String *enumClassPrefix = getEnumClassPrefix(); - if (enumClassPrefix) { - scope = NewString(""); - if (nspace) - Printf(scope, "%s.", nspace); - Printf(scope, "%s", enumClassPrefix); - } else { - scope = Copy(constants_interface_name); - } - } else { - scope = getCurrentScopeName(nspace); - if (!scope) - scope = Copy(Getattr(parent, "sym:name")); - else - Printf(scope, ".%s", Getattr(parent, "sym:name")); - } - if (!addSymbol(symname, n, scope)) - return SWIG_ERROR; - - if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) { - if (!GetFlag(n, "firstenumitem")) - Printf(enum_code, ",\n"); - } - - // Translate and write javadoc comment if flagged - if (doxygen && doxygenTranslator->hasDocumentation(n)) { - String *doxygen_comments = doxygenTranslator->getDocumentation(n, " "); - if (comment_creation_chatter) - Printf(enum_code, "/* This was generated from enumvalueDeclaration() */\n"); - Printv(enum_code, Char(doxygen_comments), NIL); - Delete(doxygen_comments); - } - - if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) { - // Wrap (non-anonymous) C/C++ enum with a proper Java enum - // Emit the enum item. - Printf(enum_code, " %s", symname); - if (Getattr(n, "enumvalue")) { - String *value = enumValue(n); - Printf(enum_code, "(%s)", value); - Delete(value); - } - } else { - // Wrap C/C++ enums with constant integers or use the typesafe enum pattern - SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum "); - Setattr(n, "type", typemap_lookup_type); - const String *tm = typemapLookup(n, "jstype", typemap_lookup_type, WARN_JAVA_TYPEMAP_JSTYPE_UNDEF); - - String *return_type = Copy(tm); - substituteClassname(typemap_lookup_type, return_type); - const String *methodmods = Getattr(n, "feature:java:methodmodifiers"); - methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - - if ((enum_feature == TypesafeEnum) && parent_name && !unnamedinstance) { - // Wrap (non-anonymous) enum using the typesafe enum pattern - if (Getattr(n, "enumvalue")) { - String *value = enumValue(n); - Printf(enum_code, " %s final static %s %s = new %s(\"%s\", %s);\n", methodmods, return_type, symname, return_type, symname, value); - Delete(value); - } else { - Printf(enum_code, " %s final static %s %s = new %s(\"%s\");\n", methodmods, return_type, symname, return_type, symname); - } - } else { - // Simple integer constants - // Note these are always generated for anonymous enums, no matter what enum_feature is specified - // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later - String *value = enumValue(n); - Printf(enum_code, " %s final static %s %s = %s;\n", methodmods, return_type, symname, value); - Delete(value); - } - Delete(return_type); - } - - // Add the enum value to the comma separated list being constructed in the enum declaration. - String *enumvalues = Getattr(parent, "enumvalues"); - if (!enumvalues) - Setattr(parent, "enumvalues", Copy(symname)); - else - Printv(enumvalues, ", ", symname, NIL); - Delete(scope); - } - - Delete(newsymname); - Delete(tmpValue); - Swig_restore(n); - return SWIG_OK; - } - - /* ----------------------------------------------------------------------- - * constantWrapper() - * Used for wrapping constants - #define or %constant. - * Also for inline initialised const static primitive type member variables (short, int, double, enums etc). - * Java static final variables are generated for these. - * If the %javaconst(1) feature is used then the C constant value is used to initialise the Java final variable. - * If not, a JNI method is generated to get the C constant value for initialisation of the Java final variable. - * However, if the %javaconstvalue feature is used, it overrides all other ways to generate the initialisation. - * Also note that this method might be called for wrapping enum items (when the enum is using %javaconst(0)). - * ------------------------------------------------------------------------ */ - - virtual int constantWrapper(Node *n) { - String *symname = Getattr(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - SwigType *valuetype = Getattr(n, "valuetype"); - ParmList *l = Getattr(n, "parms"); - String *tm; - String *return_type = NewString(""); - String *constants_code = NewString(""); - Swig_save("constantWrapper", n, "value", NIL); - - // Translate and write javadoc comment if flagged - if (doxygen && doxygenTranslator->hasDocumentation(n)) { - String *doxygen_comments = doxygenTranslator->getDocumentation(n, " "); - if (comment_creation_chatter) - Printf(constants_code, "/* This was generated from constantWrapper() */\n"); - Printv(constants_code, Char(doxygen_comments), NIL); - Delete(doxygen_comments); - } - - bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0); - - const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname; - if (!is_enum_item) { - String *scope = 0; - if (proxy_class_name) { - String *nspace = getNSpace(); - scope = NewString(""); - if (nspace) - Printf(scope, "%s.", nspace); - Printf(scope, "%s", proxy_class_name); - } else { - scope = Copy(constants_interface_name); - } - if (!addSymbol(itemname, n, scope)) - return SWIG_ERROR; - Delete(scope); - } - - // The %javaconst feature determines how the constant value is obtained - int const_feature_flag = GetFlag(n, "feature:java:const"); - - /* Adjust the enum type for the Swig_typemap_lookup. - * We want the same jstype typemap for all the enum items so we use the enum type (parent node). */ - if (is_enum_item) { - t = Getattr(parentNode(n), "enumtype"); - Setattr(n, "type", t); - } - - /* Attach the non-standard typemaps to the parameter list. */ - Swig_typemap_attach_parms("jstype", l, NULL); - - /* Get Java return types */ - bool classname_substituted_flag = false; - - if ((tm = Swig_typemap_lookup("jstype", n, "", 0))) { - classname_substituted_flag = substituteClassname(t, tm); - Printf(return_type, "%s", tm); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0)); - } - - // Add the stripped quotes back in - String *new_value = NewString(""); - if (SwigType_type(t) == T_STRING) { - Printf(new_value, "\"%s\"", Copy(Getattr(n, "value"))); - Setattr(n, "value", new_value); - } else if (SwigType_type(t) == T_CHAR) { - Printf(new_value, "\'%s\'", Copy(Getattr(n, "value"))); - Setattr(n, "value", new_value); - } - - const String *methodmods = Getattr(n, "feature:java:methodmodifiers"); - methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - - Printf(constants_code, " %s final static %s %s = ", methodmods, return_type, itemname); - - // Check for the %javaconstvalue feature - String *value = Getattr(n, "feature:java:constvalue"); - - if (value) { - Printf(constants_code, "%s;\n", value); - } else if (!const_feature_flag) { - // Default enum and constant handling will work with any type of C constant and initialises the Java variable from C through a JNI call. - - if (classname_substituted_flag) { - if (SwigType_isenum(t)) { - // This handles wrapping of inline initialised const enum static member variables (not when wrapping enum items - ignored later on) - Printf(constants_code, "%s.swigToEnum(%s.%s());\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname)); - } else { - // This handles function pointers using the %constant directive - Printf(constants_code, "new %s(%s.%s(), false);\n", return_type, full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname)); - } - } else { - Printf(constants_code, "%s.%s();\n", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname)); - } - - // Each constant and enum value is wrapped with a separate JNI function call - SetFlag(n, "feature:immutable"); - enum_constant_flag = true; - variableWrapper(n); - enum_constant_flag = false; - } else { - // Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code - if (Getattr(n, "wrappedasconstant")) { - if (SwigType_type(valuetype) == T_CHAR) - Printf(constants_code, "\'%(escape)s\';\n", Getattr(n, "staticmembervariableHandler:value")); - else - Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value")); - } else { - Printf(constants_code, "%s;\n", Getattr(n, "value")); - } - } - - // Emit the generated code to appropriate place - // Enums only emit the intermediate and JNI methods, so no proxy or module class wrapper methods needed - if (!is_enum_item) { - if (proxy_flag && wrapping_member_flag) - Printv(proxy_class_constants_code, constants_code, NIL); - else - Printv(module_class_constants_code, constants_code, NIL); - } - // Cleanup - Swig_restore(n); - Delete(new_value); - Delete(return_type); - Delete(constants_code); - return SWIG_OK; - } - - /* ----------------------------------------------------------------------------- - * insertDirective() - * ----------------------------------------------------------------------------- */ - - virtual int insertDirective(Node *n) { - int ret = SWIG_OK; - String *code = Getattr(n, "code"); - String *section = Getattr(n, "section"); - Replaceall(code, "$module", module_class_name); - Replaceall(code, "$imclassname", imclass_name); - - if (!ImportMode && (Cmp(section, "proxycode") == 0)) { - if (proxy_class_code) { - Swig_typemap_replace_embedded_typemap(code, n); - int offset = Len(code) > 0 && *Char(code) == '\n' ? 1 : 0; - Printv(proxy_class_code, Char(code) + offset, "\n", NIL); - } - } else { - ret = Language::insertDirective(n); - } - return ret; - } - - /* ----------------------------------------------------------------------------- - * pragmaDirective() - * - * Valid Pragmas: - * jniclassbase - base (extends) for the intermediary class - * jniclasspackage - package in which to generate the intermediary class - * jniclassclassmodifiers - class modifiers for the intermediary class - * jniclasscode - text (java code) is copied verbatim to the intermediary class - * jniclassimports - import statements for the intermediary class - * jniclassinterfaces - interface (implements) for the intermediary class - * - * modulebase - base (extends) for the module class - * moduleclassmodifiers - class modifiers for the module class - * modulecode - text (java code) is copied verbatim to the module class - * moduleimports - import statements for the module class - * moduleinterfaces - interface (implements) for the module class - * - * ----------------------------------------------------------------------------- */ - - virtual int pragmaDirective(Node *n) { - if (!ImportMode) { - String *lang = Getattr(n, "lang"); - String *code = Getattr(n, "name"); - String *value = Getattr(n, "value"); - - if (Strcmp(lang, "java") == 0) { - - String *strvalue = NewString(value); - Replaceall(strvalue, "\\\"", "\""); - - if (Strcmp(code, "jniclassbase") == 0) { - Delete(imclass_baseclass); - imclass_baseclass = Copy(strvalue); - } else if (Strcmp(code, "jniclasspackage") == 0) { - Delete(imclass_package); - imclass_package = Copy(strvalue); - String *imclass_class_package_jniname = makeValidJniName(imclass_package); - Printv(jnipackage, imclass_class_package_jniname, NIL); - Delete(imclass_class_package_jniname); - Replaceall(jnipackage, NSPACE_SEPARATOR, "_"); - Append(jnipackage, "_"); - - String *wrapper_name = NewString(""); - String *imclass_class_jniname = makeValidJniName(imclass_name); - Printf(wrapper_name, "Java_%s%s_%%f", jnipackage, imclass_class_jniname); - Delete(imclass_class_jniname); - - Swig_name_unregister("wrapper"); - Swig_name_register("wrapper", Char(wrapper_name)); - - Delete(wrapper_name); - } else if (Strcmp(code, "jniclassclassmodifiers") == 0) { - Delete(imclass_class_modifiers); - imclass_class_modifiers = Copy(strvalue); - } else if (Strcmp(code, "jniclasscode") == 0) { - Printf(imclass_class_code, "%s\n", strvalue); - } else if (Strcmp(code, "jniclassimports") == 0) { - Delete(imclass_imports); - imclass_imports = Copy(strvalue); - } else if (Strcmp(code, "jniclassinterfaces") == 0) { - Delete(imclass_interfaces); - imclass_interfaces = Copy(strvalue); - } else if (Strcmp(code, "modulebase") == 0) { - Delete(module_baseclass); - module_baseclass = Copy(strvalue); - } else if (Strcmp(code, "moduleclassmodifiers") == 0) { - Delete(module_class_modifiers); - module_class_modifiers = Copy(strvalue); - } else if (Strcmp(code, "modulecode") == 0) { - Printf(module_class_code, "%s\n", strvalue); - } else if (Strcmp(code, "moduleimports") == 0) { - Delete(module_imports); - module_imports = Copy(strvalue); - } else if (Strcmp(code, "moduleinterfaces") == 0) { - Delete(module_interfaces); - module_interfaces = Copy(strvalue); - } else if (Strcmp(code, "moduleimport") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use the moduleimports pragma.\n"); - } else if (Strcmp(code, "moduleinterface") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use the moduleinterfaces pragma.\n"); - } else if (Strcmp(code, "modulemethodmodifiers") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use %%javamethodmodifiers.\n"); - } else if (Strcmp(code, "allshadowimport") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaimports).\n"); - } else if (Strcmp(code, "allshadowcode") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javacode).\n"); - } else if (Strcmp(code, "allshadowbase") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javabase).\n"); - } else if (Strcmp(code, "allshadowinterface") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javainterfaces).\n"); - } else if (Strcmp(code, "allshadowclassmodifiers") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n"); - } else if (proxy_flag) { - if (Strcmp(code, "shadowcode") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javacode).\n"); - } else if (Strcmp(code, "shadowimport") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaimports).\n"); - } else if (Strcmp(code, "shadowbase") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javabase).\n"); - } else if (Strcmp(code, "shadowinterface") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javainterfaces).\n"); - } else if (Strcmp(code, "shadowclassmodifiers") == 0) { - Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n"); - } else { - Swig_error(input_file, line_number, "Unrecognized pragma.\n"); - } - } else { - Swig_error(input_file, line_number, "Unrecognized pragma.\n"); - } - Delete(strvalue); - } - } - return Language::pragmaDirective(n); - } - - /* ----------------------------------------------------------------------------- - * getQualifiedInterfaceName() - * ----------------------------------------------------------------------------- */ - - String *getQualifiedInterfaceName(Node *n) { - String *ret = Getattr(n, "interface:qname"); - if (!ret) { - String *nspace = Getattr(n, "sym:nspace"); - String *symname = Getattr(n, "interface:name"); - if (nspace) { - if (package) - ret = NewStringf("%s.%s.%s", package, nspace, symname); - else - ret = NewStringf("%s.%s", nspace, symname); - } else { - ret = Copy(symname); - } - Setattr(n, "interface:qname", ret); - } - return ret; - } - - /* ----------------------------------------------------------------------------- - * getInterfaceName() - * ----------------------------------------------------------------------------- */ - - String *getInterfaceName(SwigType *t, bool qualified) { - String *interface_name = NULL; - if (proxy_flag) { - Node *n = classLookup(t); - if (n && Getattr(n, "interface:name")) - interface_name = qualified ? getQualifiedInterfaceName(n) : Getattr(n, "interface:name"); - } - return interface_name; - } - - /* ----------------------------------------------------------------------------- - * addInterfaceNameAndUpcasts() - * ----------------------------------------------------------------------------- */ - - void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, List *base_list, SwigType *c_classname) { - for (Iterator it = First(base_list); it.item; it = Next(it)) { - Node *base = it.item; - SwigType *c_baseclassname = Getattr(base, "name"); - String *interface_name = Getattr(base, "interface:name"); - if (Len(interface_list)) - Append(interface_list, ", "); - Append(interface_list, interface_name); - - Node *attributes = NewHash(); - String *interface_code = Copy(typemapLookup(base, "javainterfacecode", Getattr(base, "classtypeobj"), WARN_JAVA_TYPEMAP_INTERFACECODE_UNDEF, attributes)); - String *cptr_method_name = 0; - if (interface_code) { - Replaceall(interface_code, "$interfacename", interface_name); - Printv(interface_upcasts, interface_code, NIL); - cptr_method_name = Copy(Getattr(attributes, "tmap:javainterfacecode:cptrmethod")); - } - if (!cptr_method_name) - cptr_method_name = NewStringf("%s_GetInterfaceCPtr", interface_name); - Replaceall(cptr_method_name, ".", "_"); - Replaceall(cptr_method_name, "$interfacename", interface_name); - - String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); - - Delete(upcast_method_name); - Delete(cptr_method_name); - Delete(interface_code); - } - } - - /* ----------------------------------------------------------------------------- - * upcastsCode() - * - * Add code for C++ casting to base class - * ----------------------------------------------------------------------------- */ - - void upcastsCode(SwigType *smart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) { - String *jniname = makeValidJniName(upcast_method_name); - String *wname = Swig_name_wrapper(jniname); - - Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method_name); - - String *classname = SwigType_namestr(c_classname); - String *baseclassname = SwigType_namestr(c_baseclassname); - if (smart) { - String *smartnamestr = SwigType_namestr(smart); - String *bsmartnamestr = SwigType_namestr(smart); - - // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates - SwigType *rclassname = SwigType_typedef_resolve_all(classname); - SwigType *rbaseclassname = SwigType_typedef_resolve_all(baseclassname); - Replaceall(bsmartnamestr, rclassname, rbaseclassname); - - Printv(upcasts_code, - "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", - " jlong baseptr = 0;\n" - " ", smartnamestr, " *argp1;\n" - " (void)jenv;\n" - " (void)jcls;\n" - " argp1 = *(", smartnamestr, " **)&jarg1;\n" - " *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n" - " return baseptr;\n" - "}\n", "\n", NIL); - - Delete(rbaseclassname); - Delete(rclassname); - Delete(bsmartnamestr); - Delete(smartnamestr); - } else { - Printv(upcasts_code, - "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", - " jlong baseptr = 0;\n" - " (void)jenv;\n" - " (void)jcls;\n" - " *(", baseclassname, " **)&baseptr = *(", classname, " **)&jarg1;\n" - " return baseptr;\n" - "}\n", "\n", NIL); - } - - Delete(baseclassname); - Delete(classname); - Delete(wname); - Delete(jniname); - } - - /* ----------------------------------------------------------------------------- - * emitProxyClassDefAndCPPCasts() - * ----------------------------------------------------------------------------- */ - - void emitProxyClassDefAndCPPCasts(Node *n) { - SwigType *c_classname = Getattr(n, "name"); - SwigType *c_baseclassname = NULL; - String *baseclass = NULL; - String *interface_list = NewStringEmpty(); - String *interface_upcasts = NewStringEmpty(); - SwigType *typemap_lookup_type = Getattr(n, "classtypeobj"); - bool feature_director = Swig_directorclass(n) ? true : false; - bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested"); - SwigType *smart = Swig_cparse_smartptr(n); - - // Inheritance from pure Java classes - Node *attributes = NewHash(); - const String *pure_baseclass = typemapLookup(n, "javabase", typemap_lookup_type, WARN_NONE, attributes); - bool purebase_replace = GetFlag(attributes, "tmap:javabase:replace") ? true : false; - bool purebase_notderived = GetFlag(attributes, "tmap:javabase:notderived") ? true : false; - Delete(attributes); - - // C++ inheritance - if (!purebase_replace) { - List *baselist = Getattr(n, "bases"); - if (baselist) { - Iterator base = First(baselist); - while (base.item) { - if (!(GetFlag(base.item, "feature:ignore") || GetFlag(base.item, "feature:interface"))) { - SwigType *baseclassname = Getattr(base.item, "name"); - if (!c_baseclassname) { - String *name = getProxyName(baseclassname); - if (name) { - c_baseclassname = baseclassname; - baseclass = name; - } - } else { - /* Warn about multiple inheritance for additional base class(es) */ - String *proxyclassname = Getattr(n, "classtypeobj"); - Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s, base %s ignored. Multiple inheritance is not supported in Java.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname)); - } - } - base = Next(base); - } - } - } - - List *interface_bases = Getattr(n, "interface:bases"); - if (interface_bases) - addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname); - - bool derived = baseclass != 0; - if (derived && purebase_notderived) - pure_baseclass = empty_string; - const String *wanted_base = baseclass ? baseclass : pure_baseclass; - - if (purebase_replace) { - wanted_base = pure_baseclass; - derived = false; - baseclass = NULL; - if (purebase_notderived) - Swig_error(Getfile(n), Getline(n), "The javabase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type); - } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) { - Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s, base %s ignored. Multiple inheritance is not supported in Java. " - "Perhaps you need one of the 'replace' or 'notderived' attributes in the javabase typemap?\n", typemap_lookup_type, pure_baseclass); - } - - // Pure Java interfaces - const String *pure_interfaces = typemapLookup(n, "javainterfaces", typemap_lookup_type, WARN_NONE); - - if (*Char(interface_list) && *Char(pure_interfaces)) - Append(interface_list, ", "); - Append(interface_list, pure_interfaces); - // Start writing the proxy class - if (!has_outerclass) // Import statements - Printv(proxy_class_def, typemapLookup(n, "javaimports", typemap_lookup_type, WARN_NONE),"\n", NIL); - - // Translate and write javadoc comment if flagged - if (doxygen && doxygenTranslator->hasDocumentation(n)) { - String *doxygen_comments = doxygenTranslator->getDocumentation(n, 0); - if (comment_creation_chatter) - Printf(proxy_class_def, "/* This was generated from emitProxyClassDefAndCPPCasts() */\n"); - Printv(proxy_class_def, Char(doxygen_comments), NIL); - Delete(doxygen_comments); - } - - if (has_outerclass) - Printv(proxy_class_def, "static ", NIL); // C++ nested classes correspond to static java classes - Printv(proxy_class_def, typemapLookup(n, "javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers - " $javaclassname", // Class name and bases - (*Char(wanted_base)) ? " extends " : "", wanted_base, *Char(interface_list) ? // Pure Java interfaces - " implements " : "", interface_list, " {", derived ? typemapLookup(n, "javabody_derived", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF) : // main body of class - typemapLookup(n, "javabody", typemap_lookup_type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class - NIL); - - // C++ destructor is wrapped by the delete method - // Note that the method name is specified in a typemap attribute called methodname - String *destruct = NewString(""); - const String *tm = NULL; - attributes = NewHash(); - const String *destruct_methodname = NULL; - const String *destruct_methodmodifiers = NULL; - const String *destruct_parameters = NULL; - if (derived) { - tm = typemapLookup(n, "javadestruct_derived", typemap_lookup_type, WARN_NONE, attributes); - destruct_methodname = Getattr(attributes, "tmap:javadestruct_derived:methodname"); - destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct_derived:methodmodifiers"); - destruct_parameters = Getattr(attributes, "tmap:javadestruct_derived:parameters"); - } else { - tm = typemapLookup(n, "javadestruct", typemap_lookup_type, WARN_NONE, attributes); - destruct_methodname = Getattr(attributes, "tmap:javadestruct:methodname"); - destruct_methodmodifiers = Getattr(attributes, "tmap:javadestruct:methodmodifiers"); - destruct_parameters = Getattr(attributes, "tmap:javadestruct:parameters"); - } - if (tm && *Char(tm)) { - if (!destruct_methodname) { - Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in javadestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name); - } - if (!destruct_methodmodifiers) { - Swig_error(Getfile(n), Getline(n), "No methodmodifiers attribute defined in javadestruct%s typemap for %s.\n", (derived ? "_derived" : ""), proxy_class_name); - } - if (!destruct_parameters) - destruct_parameters = empty_string; - } - // Emit the finalize and delete methods - if (tm) { - // Finalize method - if (*Char(destructor_call)) { - Printv(proxy_class_def, typemapLookup(n, "javafinalize", typemap_lookup_type, WARN_NONE), NIL); - } - // delete method - Printv(destruct, tm, NIL); - if (*Char(destructor_call)) - Replaceall(destruct, "$jnicall", destructor_call); - else - Replaceall(destruct, "$jnicall", "throw new UnsupportedOperationException(\"C++ destructor does not have public access\")"); - if (*Char(destruct)) { - Printv(proxy_class_def, "\n ", NIL); - const String *methodmods = Getattr(n, "destructmethodmodifiers"); - if (methodmods) - Printv(proxy_class_def, methodmods, NIL); - else - Printv(proxy_class_def, destruct_methodmodifiers, NIL); - Printv(proxy_class_def, " void ", destruct_methodname, "(", destruct_parameters, ")", destructor_throws_clause, " ", destruct, "\n", NIL); - } - } - if (*Char(interface_upcasts)) - Printv(proxy_class_def, interface_upcasts, NIL); - - /* Insert directordisconnect typemap, if this class has directors enabled */ - /* Also insert the swigTakeOwnership and swigReleaseOwnership methods */ - if (feature_director) { - String *destruct_jnicall, *release_jnicall, *take_jnicall; - String *changeown_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "change_ownership"); - - destruct_jnicall = NewStringf("%s()", destruct_methodname); - release_jnicall = NewStringf("%s.%s(this, swigCPtr, false)", full_imclass_name, changeown_method_name); - take_jnicall = NewStringf("%s.%s(this, swigCPtr, true)", full_imclass_name, changeown_method_name); - - emitCodeTypemap(n, false, typemap_lookup_type, "directordisconnect", "methodname", destruct_jnicall); - emitCodeTypemap(n, false, typemap_lookup_type, "directorowner_release", "methodname", release_jnicall); - emitCodeTypemap(n, false, typemap_lookup_type, "directorowner_take", "methodname", take_jnicall); - - Delete(destruct_jnicall); - Delete(changeown_method_name); - Delete(release_jnicall); - Delete(take_jnicall); - } - - Delete(interface_upcasts); - Delete(interface_list); - Delete(attributes); - Delete(destruct); - - // Emit extra user code - Printv(proxy_class_def, typemapLookup(n, "javacode", typemap_lookup_type, WARN_NONE), // extra Java code - "\n", NIL); - - if (derived) { - String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); - upcastsCode(smart, upcast_method_name, c_classname, c_baseclassname); - Delete(upcast_method_name); - } - - Delete(smart); - } - - /* ---------------------------------------------------------------------- - * emitInterfaceDeclaration() - * ---------------------------------------------------------------------- */ - - void emitInterfaceDeclaration(Node *n, String *interface_name, File *f_interface, String *nspace) { - if (package || nspace) { - Printf(f_interface, "package "); - if (package) - Printv(f_interface, package, nspace ? "." : "", NIL); - if (nspace) - Printv(f_interface, nspace, NIL); - Printf(f_interface, ";\n"); - } - - Printv(f_interface, typemapLookup(n, "javaimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL); - Printv(f_interface, typemapLookup(n, "javainterfacemodifiers", Getattr(n, "classtypeobj"), WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF), NIL); - Printf(f_interface, " %s", interface_name); - if (List *baselist = Getattr(n, "bases")) { - String *bases = 0; - for (Iterator base = First(baselist); base.item; base = Next(base)) { - if (GetFlag(base.item, "feature:ignore") || !GetFlag(base.item, "feature:interface")) - continue; // TODO: warn about skipped non-interface bases - String *base_iname = Getattr(base.item, "interface:name"); - if (!bases) - bases = Copy(base_iname); - else { - Append(bases, ", "); - Append(bases, base_iname); - } - } - if (bases) { - Printv(f_interface, " extends ", bases, NIL); - Delete(bases); - } - } - Printf(f_interface, " {\n"); - - Node *attributes = NewHash(); - String *interface_code = Copy(typemapLookup(n, "javainterfacecode", Getattr(n, "classtypeobj"), WARN_JAVA_TYPEMAP_INTERFACECODE_UNDEF, attributes)); - if (interface_code) { - String *interface_declaration = Copy(Getattr(attributes, "tmap:javainterfacecode:declaration")); - if (interface_declaration) { - Replaceall(interface_declaration, "$interfacename", interface_name); - Printv(f_interface, interface_declaration, NIL); - Delete(interface_declaration); - } - Delete(interface_code); - } - } - - /* ---------------------------------------------------------------------- - * classDeclaration() - * ---------------------------------------------------------------------- */ - - int classDeclaration(Node *n) { - return Language::classDeclaration(n); - } - - /* ---------------------------------------------------------------------- - * classHandler() - * ---------------------------------------------------------------------- */ - - virtual int classHandler(Node *n) { - File *f_proxy = NULL; - File *f_interface = NULL; - String *old_proxy_class_name = proxy_class_name; - String *old_full_proxy_class_name = full_proxy_class_name; - String *old_full_imclass_name = full_imclass_name; - String *old_destructor_call = destructor_call; - String *old_destructor_throws_clause = destructor_throws_clause; - String *old_proxy_class_constants_code = proxy_class_constants_code; - String *old_proxy_class_def = proxy_class_def; - String *old_proxy_class_code = proxy_class_code; - bool has_outerclass = Getattr(n, "nested:outer") && !GetFlag(n, "feature:flatnested"); - String *old_interface_class_code = interface_class_code; - interface_class_code = 0; - - if (proxy_flag) { - proxy_class_name = NewString(Getattr(n, "sym:name")); - String *nspace = getNSpace(); - constructIntermediateClassName(n); - - String *outerClassesPrefix = 0; - if (Node *outer = Getattr(n, "nested:outer")) { - outerClassesPrefix = Copy(Getattr(outer, "sym:name")); - for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) { - Push(outerClassesPrefix, "."); - Push(outerClassesPrefix, Getattr(outer, "sym:name")); - } - } - if (!nspace) { - full_proxy_class_name = outerClassesPrefix ? NewStringf("%s.%s", outerClassesPrefix, proxy_class_name) : NewStringf("%s", proxy_class_name); - - if (Cmp(proxy_class_name, imclass_name) == 0) { - Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name); - Exit(EXIT_FAILURE); - } - - if (Cmp(proxy_class_name, module_class_name) == 0) { - Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name); - Exit(EXIT_FAILURE); - } - } else { - if (outerClassesPrefix) { - if (package) - full_proxy_class_name = NewStringf("%s.%s.%s.%s", package, nspace, outerClassesPrefix, proxy_class_name); - else - full_proxy_class_name = NewStringf("%s.%s.%s", nspace, outerClassesPrefix, proxy_class_name); - } else { - if (package) - full_proxy_class_name = NewStringf("%s.%s.%s", package, nspace, proxy_class_name); - else - full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name); - } - } - - String *interface_name = GetFlag(n, "feature:interface") ? Getattr(n, "interface:name") : 0; - if (outerClassesPrefix) { - String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix; - if (!addSymbol(proxy_class_name, n, fnspace)) - return SWIG_ERROR; - if (interface_name && !addInterfaceSymbol(interface_name, n, fnspace)) - return SWIG_ERROR; - if (nspace) - Delete(fnspace); - Delete(outerClassesPrefix); - } else { - if (!addSymbol(proxy_class_name, n, nspace)) - return SWIG_ERROR; - if (interface_name && !addInterfaceSymbol(interface_name, n, nspace)) - return SWIG_ERROR; - } - - // Each outer proxy class goes into a separate file - if (!has_outerclass) { - String *output_directory = outputDirectory(nspace); - String *filen = NewStringf("%s%s.java", output_directory, proxy_class_name); - f_proxy = NewFile(filen, "w", SWIG_output_files()); - if (!f_proxy) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - Delete(output_directory); - - // Start writing out the proxy class file - emitBanner(f_proxy); - - if (package || nspace) { - Printf(f_proxy, "package "); - if (package) - Printv(f_proxy, package, nspace ? "." : "", NIL); - if (nspace) - Printv(f_proxy, nspace, NIL); - Printf(f_proxy, ";\n"); - } - } - else - ++nesting_depth; - - proxy_class_def = NewString(""); - proxy_class_code = NewString(""); - destructor_call = NewString(""); - destructor_throws_clause = NewString(""); - proxy_class_constants_code = NewString(""); - - if (GetFlag(n, "feature:interface")) { - interface_class_code = NewString(""); - String *output_directory = outputDirectory(nspace); - String *filen = NewStringf("%s%s.java", output_directory, interface_name); - f_interface = NewFile(filen, "w", SWIG_output_files()); - if (!f_interface) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Append(filenames_list, filen); // file name ownership goes to the list - emitBanner(f_interface); - emitInterfaceDeclaration(n, interface_name, interface_class_code, nspace); - Delete(filen); - Delete(output_directory); - } - } - - Language::classHandler(n); - - if (proxy_flag) { - emitProxyClassDefAndCPPCasts(n); - - String *javaclazzname = Swig_name_member(getNSpace(), getClassPrefix(), ""); // mangled full proxy class name - - Replaceall(proxy_class_def, "$javaclassname", proxy_class_name); - Replaceall(proxy_class_code, "$javaclassname", proxy_class_name); - Replaceall(proxy_class_constants_code, "$javaclassname", proxy_class_name); - Replaceall(interface_class_code, "$javaclassname", proxy_class_name); - - Replaceall(proxy_class_def, "$javaclazzname", javaclazzname); - Replaceall(proxy_class_code, "$javaclazzname", javaclazzname); - Replaceall(proxy_class_constants_code, "$javaclazzname", javaclazzname); - Replaceall(interface_class_code, "$javaclazzname", javaclazzname); - - Replaceall(proxy_class_def, "$module", module_class_name); - Replaceall(proxy_class_code, "$module", module_class_name); - Replaceall(proxy_class_constants_code, "$module", module_class_name); - Replaceall(interface_class_code, "$module", module_class_name); - - Replaceall(proxy_class_def, "$imclassname", full_imclass_name); - Replaceall(proxy_class_code, "$imclassname", full_imclass_name); - Replaceall(proxy_class_constants_code, "$imclassname", full_imclass_name); - Replaceall(interface_class_code, "$imclassname", full_imclass_name); - - if (!has_outerclass) - Printv(f_proxy, proxy_class_def, proxy_class_code, NIL); - else { - Swig_offset_string(proxy_class_def, nesting_depth); - Append(old_proxy_class_code, proxy_class_def); - Swig_offset_string(proxy_class_code, nesting_depth); - Append(old_proxy_class_code, proxy_class_code); - } - - // Write out all the constants - if (Len(proxy_class_constants_code) != 0) { - if (!has_outerclass) - Printv(f_proxy, proxy_class_constants_code, NIL); - else { - Swig_offset_string(proxy_class_constants_code, nesting_depth); - Append(old_proxy_class_code, proxy_class_constants_code); - } - } - - if (!has_outerclass) { - Printf(f_proxy, "}\n"); - Delete(f_proxy); - f_proxy = NULL; - } else { - for (int i = 0; i < nesting_depth; ++i) - Append(old_proxy_class_code, " "); - Append(old_proxy_class_code, "}\n\n"); - --nesting_depth; - } - - if (f_interface) { - Printv(f_interface, interface_class_code, "}\n", NIL); - Delete(f_interface); - f_interface = 0; - } - - emitDirectorExtraMethods(n); - - Delete(interface_class_code); - interface_class_code = old_interface_class_code; - Delete(javaclazzname); - Delete(proxy_class_name); - proxy_class_name = old_proxy_class_name; - Delete(full_proxy_class_name); - full_proxy_class_name = old_full_proxy_class_name; - Delete(full_imclass_name); - full_imclass_name = old_full_imclass_name; - Delete(destructor_call); - destructor_call = old_destructor_call; - Delete(destructor_throws_clause); - destructor_throws_clause = old_destructor_throws_clause; - Delete(proxy_class_constants_code); - proxy_class_constants_code = old_proxy_class_constants_code; - Delete(proxy_class_def); - proxy_class_def = old_proxy_class_def; - Delete(proxy_class_code); - proxy_class_code = old_proxy_class_code; - } - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * memberfunctionHandler() - * ---------------------------------------------------------------------- */ - - virtual int memberfunctionHandler(Node *n) { - member_func_flag = true; - Language::memberfunctionHandler(n); - - if (proxy_flag) { - String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name); - Setattr(n, "proxyfuncname", Getattr(n, "sym:name")); - Setattr(n, "imfuncname", intermediary_function_name); - proxyClassFunctionHandler(n); - Delete(overloaded_name); - } - member_func_flag = false; - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * staticmemberfunctionHandler() - * ---------------------------------------------------------------------- */ - - virtual int staticmemberfunctionHandler(Node *n) { - - static_flag = true; - member_func_flag = true; - Language::staticmemberfunctionHandler(n); - - if (proxy_flag) { - String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name); - Setattr(n, "proxyfuncname", Getattr(n, "sym:name")); - Setattr(n, "imfuncname", intermediary_function_name); - proxyClassFunctionHandler(n); - Delete(overloaded_name); - } - static_flag = false; - member_func_flag = false; - - return SWIG_OK; - } - - /* ----------------------------------------------------------------------------- - * proxyClassFunctionHandler() - * - * Function called for creating a Java wrapper function around a c++ function in the - * proxy class. Used for both static and non-static C++ class functions. - * C++ class static functions map to Java static functions. - * Two extra attributes in the Node must be available. These are "proxyfuncname" - - * the name of the Java class proxy function, which in turn will call "imfuncname" - - * the intermediary (JNI) function name in the intermediary class. - * ----------------------------------------------------------------------------- */ - - void proxyClassFunctionHandler(Node *n) { - SwigType *t = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - String *intermediary_function_name = Getattr(n, "imfuncname"); - String *proxy_function_name = Getattr(n, "proxyfuncname"); - String *tm; - Parm *p; - int i; - String *imcall = NewString(""); - String *return_type = NewString(""); - String *function_code = NewString(""); - bool setter_flag = false; - String *pre_code = NewString(""); - String *post_code = NewString(""); - bool is_interface = GetFlag(parentNode(n), "feature:interface") && !checkAttribute(n, "kind", "variable") - && !static_flag && Getattr(n, "interface:owner") == 0; - - if (!proxy_flag) - return; - - // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java - if (Getattr(n, "overload:ignore")) - return; - - // Don't generate proxy method for additional explicitcall method used in directors - if (GetFlag(n, "explicitcall")) - return; - - if (l) { - if (SwigType_type(Getattr(l, "type")) == T_VOID) { - l = nextSibling(l); - } - } - - /* Attach the non-standard typemaps to the parameter list */ - Swig_typemap_attach_parms("in", l, NULL); - Swig_typemap_attach_parms("jtype", l, NULL); - Swig_typemap_attach_parms("jstype", l, NULL); - Swig_typemap_attach_parms("javain", l, NULL); - - /* Get return types */ - if ((tm = Swig_typemap_lookup("jstype", n, "", 0))) { - // Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type - SwigType *covariant = Getattr(n, "covariant"); - substituteClassname(covariant ? covariant : t, tm); - Printf(return_type, "%s", tm); - if (covariant) - Swig_warning(WARN_JAVA_COVARIANT_RET, input_file, line_number, - "Covariant return types not supported in Java. Proxy method will return %s.\n", SwigType_str(covariant, 0)); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0)); - } - - if (wrapping_member_flag && !enum_constant_flag) { - // For wrapping member variables (Javabean setter) - setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, getClassPrefix(), variable_name))) == 0); - } - - // Translate and write javadoc comment if flagged - if (doxygen && doxygenTranslator->hasDocumentation(n)) { - String *doxygen_comments = doxygenTranslator->getDocumentation(n, " "); - if (comment_creation_chatter) - Printf(function_code, "/* This was generated from proxyclassfunctionhandler() */\n"); - Printv(function_code, Char(doxygen_comments), NIL); - Delete(doxygen_comments); - } - - /* Start generating the proxy function */ - const String *methodmods = Getattr(n, "feature:java:methodmodifiers"); - methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - Printf(function_code, " %s ", methodmods); - if (static_flag) - Printf(function_code, "static "); - Printf(function_code, "%s %s(", return_type, proxy_function_name); - - if (is_interface) - Printf(interface_class_code, " %s %s(", return_type, proxy_function_name); - - Printv(imcall, full_imclass_name, ".$imfuncname(", NIL); - if (!static_flag) { - Printf(imcall, "swigCPtr"); - - String *this_type = Copy(getClassType()); - String *name = NewString("jself"); - String *qualifier = Getattr(n, "qualifier"); - if (qualifier) - SwigType_push(this_type, qualifier); - SwigType_add_pointer(this_type); - Parm *this_parm = NewParm(this_type, name, n); - Swig_typemap_attach_parms("jtype", this_parm, NULL); - Swig_typemap_attach_parms("jstype", this_parm, NULL); - - if (prematureGarbageCollectionPreventionParameter(this_type, this_parm)) - Printf(imcall, ", this"); - - Delete(this_parm); - Delete(name); - Delete(this_type); - } - - emit_mark_varargs(l); - - int gencomma = !static_flag; - - /* Output each parameter */ - for (i = 0, p = l; p; i++) { - - /* Ignored varargs */ - if (checkAttribute(p, "varargs:ignore", "1")) { - p = nextSibling(p); - continue; - } - - /* Ignored parameters */ - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - continue; - } - - /* Ignore the 'this' argument for variable wrappers */ - if (!(variable_wrapper_flag && i == 0) || static_flag) { - SwigType *pt = Getattr(p, "type"); - String *param_type = NewString(""); - - /* Get the Java parameter type */ - if ((tm = Getattr(p, "tmap:jstype"))) { - substituteClassname(pt, tm); - Printf(param_type, "%s", tm); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - if (gencomma) - Printf(imcall, ", "); - - String *arg = makeParameterName(n, p, i, setter_flag); - - // Use typemaps to transform type used in Java proxy wrapper (in proxy class) to type used in JNI function (in intermediary class) - if ((tm = Getattr(p, "tmap:javain"))) { - addThrows(n, "tmap:javain", p); - substituteClassname(pt, tm); - Replaceall(tm, "$javainput", arg); - String *pre = Getattr(p, "tmap:javain:pre"); - if (pre) { - substituteClassname(pt, pre); - Replaceall(pre, "$javainput", arg); - if (Len(pre_code) > 0) - Printf(pre_code, "\n"); - Printv(pre_code, pre, NIL); - } - String *post = Getattr(p, "tmap:javain:post"); - if (post) { - substituteClassname(pt, post); - Replaceall(post, "$javainput", arg); - if (Len(post_code) > 0) - Printf(post_code, "\n"); - Printv(post_code, post, NIL); - } - Printv(imcall, tm, NIL); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Add parameter to proxy function */ - if (gencomma >= 2) { - Printf(function_code, ", "); - if (is_interface) - Printf(interface_class_code, ", "); - } - gencomma = 2; - Printf(function_code, "%s %s", param_type, arg); - if (is_interface) - Printf(interface_class_code, "%s %s", param_type, arg); - - if (prematureGarbageCollectionPreventionParameter(pt, p)) { - String *pgcppname = Getattr(p, "tmap:javain:pgcppname"); - if (pgcppname) { - String *argname = Copy(pgcppname); - Replaceall(argname, "$javainput", arg); - Printf(imcall, ", %s", argname); - Delete(argname); - } else { - Printf(imcall, ", %s", arg); - } - } - - Delete(arg); - Delete(param_type); - } - p = Getattr(p, "tmap:in:next"); - } - - Printf(imcall, ")"); - Printf(function_code, ")"); - - // Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in proxy class) - if ((tm = Swig_typemap_lookup("javaout", n, "", 0))) { - addThrows(n, "tmap:javaout", n); - bool is_pre_code = Len(pre_code) > 0; - bool is_post_code = Len(post_code) > 0; - if (is_pre_code || is_post_code) { - Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap - if (is_post_code) { - Insert(tm, 0, "\n try "); - Printv(tm, " finally {\n", post_code, "\n }", NIL); - } else { - Insert(tm, 0, "\n "); - } - if (is_pre_code) { - Insert(tm, 0, pre_code); - Insert(tm, 0, "\n"); - } - Insert(tm, 0, "{"); - Printf(tm, "\n }"); - } - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "true"); - else - Replaceall(tm, "$owner", "false"); - substituteClassname(t, tm); - - // For director methods: generate code to selectively make a normal polymorphic call or - // an explicit method call - needed to prevent infinite recursion calls in director methods. - Node *explicit_n = Getattr(n, "explicitcallnode"); - if (explicit_n) { - String *ex_overloaded_name = getOverloadedName(explicit_n); - String *ex_intermediary_function_name = Swig_name_member(getNSpace(), getClassPrefix(), ex_overloaded_name); - - String *ex_imcall = Copy(imcall); - Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name); - Replaceall(imcall, "$imfuncname", intermediary_function_name); - - String *excode = NewString(""); - if (!Cmp(return_type, "void")) - Printf(excode, "if (getClass() == %s.class) %s; else %s", proxy_class_name, imcall, ex_imcall); - else - Printf(excode, "(getClass() == %s.class) ? %s : %s", proxy_class_name, imcall, ex_imcall); - - Clear(imcall); - Printv(imcall, excode, NIL); - Delete(ex_overloaded_name); - Delete(excode); - } else { - Replaceall(imcall, "$imfuncname", intermediary_function_name); - } - - Replaceall(tm, "$imfuncname", intermediary_function_name); - Replaceall(tm, "$jnicall", imcall); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0)); - } - - if (is_interface) { - Printf(interface_class_code, ")"); - generateThrowsClause(n, interface_class_code); - Printf(interface_class_code, ";\n"); - } - generateThrowsClause(n, function_code); - Printf(function_code, " %s\n\n", tm ? tm : empty_string); - Printv(proxy_class_code, function_code, NIL); - - Delete(pre_code); - Delete(post_code); - Delete(function_code); - Delete(return_type); - Delete(imcall); - } - - /* ---------------------------------------------------------------------- - * constructorHandler() - * ---------------------------------------------------------------------- */ - - virtual int constructorHandler(Node *n) { - - ParmList *l = Getattr(n, "parms"); - String *tm; - Parm *p; - int i; - String *function_code = NewString(""); - String *helper_code = NewString(""); // Holds code for the constructor helper method generated only when the javain typemap has code in the pre or post attributes - String *helper_args = NewString(""); - String *pre_code = NewString(""); - String *post_code = NewString(""); - String *im_return_type = NewString(""); - bool feature_director = (parentNode(n) && Swig_directorclass(n)); - - Language::constructorHandler(n); - - // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java - if (Getattr(n, "overload:ignore")) - return SWIG_OK; - - if (proxy_flag) { - String *overloaded_name = getOverloadedName(n); - String *mangled_overname = Swig_name_construct(getNSpace(), overloaded_name); - String *imcall = NewString(""); - - const String *methodmods = Getattr(n, "feature:java:methodmodifiers"); - methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - - tm = Getattr(n, "tmap:jtype"); // typemaps were attached earlier to the node - Printf(im_return_type, "%s", tm); - - // Translate and write javadoc comment if flagged - if (doxygen && doxygenTranslator->hasDocumentation(n)) { - String *doxygen_comments = doxygenTranslator->getDocumentation(n, " "); - if (comment_creation_chatter) - Printf(function_code, "/* This was generated from constructionhandler() */\n"); - Printv(function_code, Char(doxygen_comments), NIL); - Delete(doxygen_comments); - } - - Printf(function_code, " %s %s(", methodmods, proxy_class_name); - Printf(helper_code, " static private %s SwigConstruct%s(", im_return_type, proxy_class_name); - - Printv(imcall, full_imclass_name, ".", mangled_overname, "(", NIL); - - /* Attach the non-standard typemaps to the parameter list */ - Swig_typemap_attach_parms("in", l, NULL); - Swig_typemap_attach_parms("jtype", l, NULL); - Swig_typemap_attach_parms("jstype", l, NULL); - Swig_typemap_attach_parms("javain", l, NULL); - - emit_mark_varargs(l); - - int gencomma = 0; - - /* Output each parameter */ - for (i = 0, p = l; p; i++) { - - /* Ignored varargs */ - if (checkAttribute(p, "varargs:ignore", "1")) { - p = nextSibling(p); - continue; - } - - /* Ignored parameters */ - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - continue; - } - - SwigType *pt = Getattr(p, "type"); - String *param_type = NewString(""); - - /* Get the Java parameter type */ - if ((tm = Getattr(p, "tmap:jstype"))) { - substituteClassname(pt, tm); - Printf(param_type, "%s", tm); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - if (gencomma) - Printf(imcall, ", "); - - String *arg = makeParameterName(n, p, i, false); - - // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in JNI function (in intermediary class) - if ((tm = Getattr(p, "tmap:javain"))) { - addThrows(n, "tmap:javain", p); - substituteClassname(pt, tm); - Replaceall(tm, "$javainput", arg); - String *pre = Getattr(p, "tmap:javain:pre"); - if (pre) { - substituteClassname(pt, pre); - Replaceall(pre, "$javainput", arg); - if (Len(pre_code) > 0) - Printf(pre_code, "\n"); - Printv(pre_code, pre, NIL); - } - String *post = Getattr(p, "tmap:javain:post"); - if (post) { - substituteClassname(pt, post); - Replaceall(post, "$javainput", arg); - if (Len(post_code) > 0) - Printf(post_code, "\n"); - Printv(post_code, post, NIL); - } - Printv(imcall, tm, NIL); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Add parameter to proxy function */ - if (gencomma) { - Printf(function_code, ", "); - Printf(helper_code, ", "); - Printf(helper_args, ", "); - } - Printf(function_code, "%s %s", param_type, arg); - Printf(helper_code, "%s %s", param_type, arg); - Printf(helper_args, "%s", arg); - ++gencomma; - - if (prematureGarbageCollectionPreventionParameter(pt, p)) { - String *pgcppname = Getattr(p, "tmap:javain:pgcppname"); - if (pgcppname) { - String *argname = Copy(pgcppname); - Replaceall(argname, "$javainput", arg); - Printf(imcall, ", %s", argname); - Delete(argname); - } else { - Printf(imcall, ", %s", arg); - } - } - - Delete(arg); - Delete(param_type); - p = Getattr(p, "tmap:in:next"); - } - - Printf(imcall, ")"); - - Printf(function_code, ")"); - Printf(helper_code, ")"); - generateThrowsClause(n, function_code); - - /* Insert the javaconstruct typemap, doing the replacement for $directorconnect, as needed */ - Hash *attributes = NewHash(); - String *typemap_lookup_type = Getattr(getCurrentClass(), "classtypeobj"); - String *construct_tm = Copy(typemapLookup(n, "javaconstruct", typemap_lookup_type, - WARN_JAVA_TYPEMAP_JAVACONSTRUCT_UNDEF, attributes)); - if (construct_tm) { - if (!feature_director) { - Replaceall(construct_tm, "$directorconnect", ""); - } else { - String *connect_attr = Getattr(attributes, "tmap:javaconstruct:directorconnect"); - - if (connect_attr) { - Replaceall(construct_tm, "$directorconnect", connect_attr); - } else { - Swig_warning(WARN_JAVA_NO_DIRECTORCONNECT_ATTR, input_file, line_number, "\"directorconnect\" attribute missing in %s \"javaconstruct\" typemap.\n", - Getattr(n, "name")); - Replaceall(construct_tm, "$directorconnect", ""); - } - } - - Printv(function_code, " ", construct_tm, "\n", NIL); - } - - bool is_pre_code = Len(pre_code) > 0; - bool is_post_code = Len(post_code) > 0; - if (is_pre_code || is_post_code) { - generateThrowsClause(n, helper_code); - Printf(helper_code, " {\n"); - if (is_pre_code) { - Printv(helper_code, pre_code, "\n", NIL); - } - if (is_post_code) { - Printf(helper_code, " try {\n"); - Printv(helper_code, " return ", imcall, ";\n", NIL); - Printv(helper_code, " } finally {\n", post_code, "\n }", NIL); - } else { - Printv(helper_code, " return ", imcall, ";", NIL); - } - Printf(helper_code, "\n }\n"); - String *helper_name = NewStringf("%s.SwigConstruct%s(%s)", proxy_class_name, proxy_class_name, helper_args); - Printv(proxy_class_code, helper_code, "\n", NIL); - Replaceall(function_code, "$imcall", helper_name); - Delete(helper_name); - } else { - Replaceall(function_code, "$imcall", imcall); - } - - Printv(proxy_class_code, function_code, "\n", NIL); - - Delete(helper_args); - Delete(im_return_type); - Delete(pre_code); - Delete(post_code); - Delete(construct_tm); - Delete(attributes); - Delete(overloaded_name); - Delete(imcall); - } - - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * destructorHandler() - * ---------------------------------------------------------------------- */ - - virtual int destructorHandler(Node *n) { - Language::destructorHandler(n); - String *symname = Getattr(n, "sym:name"); - - if (proxy_flag) { - Printv(destructor_call, full_imclass_name, ".", Swig_name_destroy(getNSpace(), symname), "(swigCPtr)", NIL); - generateThrowsClause(n, destructor_throws_clause); - const String *methodmods = Getattr(n, "feature:java:methodmodifiers"); - if (methodmods) - Setattr(getCurrentClass(), "destructmethodmodifiers", methodmods); - } - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * membervariableHandler() - * ---------------------------------------------------------------------- */ - - virtual int membervariableHandler(Node *n) { - variable_name = Getattr(n, "sym:name"); - wrapping_member_flag = true; - variable_wrapper_flag = true; - Language::membervariableHandler(n); - wrapping_member_flag = false; - variable_wrapper_flag = false; - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * staticmembervariableHandler() - * ---------------------------------------------------------------------- */ - - virtual int staticmembervariableHandler(Node *n) { - variable_name = Getattr(n, "sym:name"); - wrapping_member_flag = true; - static_flag = true; - Language::staticmembervariableHandler(n); - wrapping_member_flag = false; - static_flag = false; - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * memberconstantHandler() - * ---------------------------------------------------------------------- */ - - virtual int memberconstantHandler(Node *n) { - variable_name = Getattr(n, "sym:name"); - wrapping_member_flag = true; - Language::memberconstantHandler(n); - wrapping_member_flag = false; - return SWIG_OK; - } - - /* ----------------------------------------------------------------------------- - * getOverloadedName() - * ----------------------------------------------------------------------------- */ - - String *getOverloadedName(Node *n) { - - /* Although JNI functions are designed to handle overloaded Java functions, - * a Java long is used for all classes in the SWIG intermediary class. - * The intermediary class methods are thus mangled when overloaded to give - * a unique name. */ - String *overloaded_name = NewStringf("%s", Getattr(n, "sym:name")); - - if (Getattr(n, "sym:overloaded")) { - Printv(overloaded_name, Getattr(n, "sym:overname"), NIL); - } - - return overloaded_name; - } - - /* ----------------------------------------------------------------------------- - * moduleClassFunctionHandler() - * ----------------------------------------------------------------------------- */ - - void moduleClassFunctionHandler(Node *n) { - SwigType *t = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - String *tm; - Parm *p; - int i; - String *imcall = NewString(""); - String *return_type = NewString(""); - String *function_code = NewString(""); - int num_arguments = 0; - String *overloaded_name = getOverloadedName(n); - String *func_name = NULL; - bool setter_flag = false; - String *pre_code = NewString(""); - String *post_code = NewString(""); - - // Translate and write javadoc comment if flagged - if (doxygen && doxygenTranslator->hasDocumentation(n)) { - String *doxygen_comments = doxygenTranslator->getDocumentation(n, " "); - if (comment_creation_chatter) - Printf(function_code, "/* This was generated from moduleClassFunctionHandler() */\n"); - Printv(function_code, doxygen_comments, NIL); - Delete(doxygen_comments); - } - - if (l) { - if (SwigType_type(Getattr(l, "type")) == T_VOID) { - l = nextSibling(l); - } - } - - /* Attach the non-standard typemaps to the parameter list */ - Swig_typemap_attach_parms("jstype", l, NULL); - Swig_typemap_attach_parms("javain", l, NULL); - - /* Get return types */ - if ((tm = Swig_typemap_lookup("jstype", n, "", 0))) { - substituteClassname(t, tm); - Printf(return_type, "%s", tm); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 0)); - } - - /* Change function name for global variables */ - if (proxy_flag && global_variable_flag) { - // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name - func_name = NewString(""); - setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), variable_name)) == 0); - if (setter_flag) - Printf(func_name, "set"); - else - Printf(func_name, "get"); - Putc(toupper((int) *Char(variable_name)), func_name); - Printf(func_name, "%s", Char(variable_name) + 1); - } else { - func_name = Copy(Getattr(n, "sym:name")); - } - - /* Start generating the function */ - const String *methodmods = Getattr(n, "feature:java:methodmodifiers"); - methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - Printf(function_code, " %s static %s %s(", methodmods, return_type, func_name); - Printv(imcall, imclass_name, ".", overloaded_name, "(", NIL); - - /* Get number of required and total arguments */ - num_arguments = emit_num_arguments(l); - - bool global_or_member_variable = global_variable_flag || (wrapping_member_flag && !enum_constant_flag); - int gencomma = 0; - - /* Output each parameter */ - for (i = 0, p = l; i < num_arguments; i++) { - - /* Ignored parameters */ - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *param_type = NewString(""); - - /* Get the Java parameter type */ - if ((tm = Getattr(p, "tmap:jstype"))) { - substituteClassname(pt, tm); - Printf(param_type, "%s", tm); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt, 0)); - } - - if (gencomma) - Printf(imcall, ", "); - - String *arg = makeParameterName(n, p, i, global_or_member_variable); - - // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in JNI function (in intermediary class) - if ((tm = Getattr(p, "tmap:javain"))) { - addThrows(n, "tmap:javain", p); - substituteClassname(pt, tm); - Replaceall(tm, "$javainput", arg); - String *pre = Getattr(p, "tmap:javain:pre"); - if (pre) { - substituteClassname(pt, pre); - Replaceall(pre, "$javainput", arg); - if (Len(pre_code) > 0) - Printf(pre_code, "\n"); - Printv(pre_code, pre, NIL); - } - String *post = Getattr(p, "tmap:javain:post"); - if (post) { - substituteClassname(pt, post); - Replaceall(post, "$javainput", arg); - if (Len(post_code) > 0) - Printf(post_code, "\n"); - Printv(post_code, post, NIL); - } - Printv(imcall, tm, NIL); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt, 0)); - } - - /* Add parameter to module class function */ - if (gencomma >= 2) - Printf(function_code, ", "); - gencomma = 2; - Printf(function_code, "%s %s", param_type, arg); - - if (prematureGarbageCollectionPreventionParameter(pt, p)) { - String *pgcppname = Getattr(p, "tmap:javain:pgcppname"); - if (pgcppname) { - String *argname = Copy(pgcppname); - Replaceall(argname, "$javainput", arg); - Printf(imcall, ", %s", argname); - Delete(argname); - } else { - Printf(imcall, ", %s", arg); - } - } - - p = Getattr(p, "tmap:in:next"); - Delete(arg); - Delete(param_type); - } - - Printf(imcall, ")"); - Printf(function_code, ")"); - - // Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in module class) - if ((tm = Swig_typemap_lookup("javaout", n, "", 0))) { - addThrows(n, "tmap:javaout", n); - bool is_pre_code = Len(pre_code) > 0; - bool is_post_code = Len(post_code) > 0; - if (is_pre_code || is_post_code) { - Replaceall(tm, "\n ", "\n "); // add extra indentation to code in typemap - if (is_post_code) { - Insert(tm, 0, "\n try "); - Printv(tm, " finally {\n", post_code, "\n }", NIL); - } else { - Insert(tm, 0, "\n "); - } - if (is_pre_code) { - Insert(tm, 0, pre_code); - Insert(tm, 0, "\n"); - } - Insert(tm, 0, "{"); - Printf(tm, "\n }"); - } - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "true"); - else - Replaceall(tm, "$owner", "false"); - substituteClassname(t, tm); - Replaceall(tm, "$imfuncname", overloaded_name); - Replaceall(tm, "$jnicall", imcall); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0)); - } - - generateThrowsClause(n, function_code); - Printf(function_code, " %s\n\n", tm ? tm : empty_string); - Printv(module_class_code, function_code, NIL); - - Delete(pre_code); - Delete(post_code); - Delete(function_code); - Delete(return_type); - Delete(imcall); - Delete(func_name); - } - - /*---------------------------------------------------------------------- - * replaceSpecialVariables() - *--------------------------------------------------------------------*/ - - virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) { - (void)method; - SwigType *type = Getattr(parm, "type"); - substituteClassname(type, tm); - } - - /*---------------------------------------------------------------------- - * decodeEnumFeature() - * Decode the possible enum features, which are one of: - * %javaenum(simple) - * %javaenum(typeunsafe) - default - * %javaenum(typesafe) - * %javaenum(proper) - *--------------------------------------------------------------------*/ - - EnumFeature decodeEnumFeature(Node *n) { - EnumFeature enum_feature = TypeunsafeEnum; - String *feature = Getattr(n, "feature:java:enum"); - if (feature) { - if (Cmp(feature, "simple") == 0) - enum_feature = SimpleEnum; - else if (Cmp(feature, "typesafe") == 0) - enum_feature = TypesafeEnum; - else if (Cmp(feature, "proper") == 0) - enum_feature = ProperEnum; - } - return enum_feature; - } - - /* ----------------------------------------------------------------------- - * enumValue() - * This method will return a string with an enum value to use in Java generated - * code. If the %javaconst feature is not used, the string will contain the intermediary - * class call to obtain the enum value. The intermediary class and JNI methods to obtain - * the enum value will be generated. Otherwise the C/C++ enum value will be used if there - * is one and hopefully it will compile as Java code - e.g. 20 as in: enum E{e=20}; - * The %javaconstvalue feature overrides all other ways to generate the constant value. - * The caller must delete memory allocated for the returned string. - * ------------------------------------------------------------------------ */ - - String *enumValue(Node *n) { - String *symname = Getattr(n, "sym:name"); - - // Check for the %javaconstvalue feature - String *value = Getattr(n, "feature:java:constvalue"); - - if (!value) { - // The %javaconst feature determines how the constant value is obtained - int const_feature_flag = GetFlag(n, "feature:java:const"); - - if (const_feature_flag) { - // Use the C syntax to make a true Java constant and hope that it compiles as Java code - value = Getattr(n, "enumvalue") ? Copy(Getattr(n, "enumvalue")) : Copy(Getattr(n, "enumvalueex")); - } else { - String *newsymname = 0; - if (!getCurrentClass() || !proxy_flag) { - String *enumClassPrefix = getEnumClassPrefix(); - if (enumClassPrefix) { - // A global scoped enum - newsymname = Swig_name_member(0, enumClassPrefix, symname); - symname = newsymname; - } - } - - // Get the enumvalue from a JNI call - if (!getCurrentClass() || !cparse_cplusplus || !proxy_flag) { - // Strange hack to change the name - Setattr(n, "name", Getattr(n, "value")); /* for wrapping of enums in a namespace when emit_action is used */ - constantWrapper(n); - value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname)); - } else { - memberconstantHandler(n); - value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), Swig_name_member(0, getEnumClassPrefix(), symname))); - } - Delete(newsymname); - } - } - return value; - } - - /* ----------------------------------------------------------------------------- - * getEnumName() - * - * If jnidescriptor is set, inner class names are separated with '$' otherwise a '.' - * and the package is also not added to the name. - * ----------------------------------------------------------------------------- */ - - String *getEnumName(SwigType *t, bool jnidescriptor) { - Node *enumname = NULL; - Node *n = enumLookup(t); - if (n) { - enumname = Getattr(n, "enumname"); - if (!enumname || jnidescriptor) { - String *symname = Getattr(n, "sym:name"); - if (symname) { - // Add in class scope when referencing enum if not a global enum - String *scopename_prefix = Swig_scopename_prefix(Getattr(n, "name")); - String *proxyname = 0; - if (scopename_prefix) { - proxyname = getProxyName(scopename_prefix, jnidescriptor); - } - if (proxyname) { - const char *class_separator = jnidescriptor ? "$" : "."; - enumname = NewStringf("%s%s%s", proxyname, class_separator, symname); - } else { - // global enum or enum in a namespace - String *nspace = Getattr(n, "sym:nspace"); - if (nspace) { - if (package && !jnidescriptor) - enumname = NewStringf("%s.%s.%s", package, nspace, symname); - else - enumname = NewStringf("%s.%s", nspace, symname); - } else { - enumname = Copy(symname); - } - } - if (!jnidescriptor) { - Setattr(n, "enumname", enumname); // Cache it - Delete(enumname); - } - Delete(scopename_prefix); - } - } - } - - return enumname; - } - - /* ----------------------------------------------------------------------------- - * substituteClassname() - * - * Substitute the special variable $javaclassname with the proxy class name for classes/structs/unions - * that SWIG knows about. Also substitutes enums with enum name. - * Otherwise use the $descriptor name for the Java class name. Note that the $&javaclassname substitution - * is the same as a $&descriptor substitution, ie one pointer added to descriptor name. - * Note that the path separator is a '.' unless jnidescriptor is set. - * Inputs: - * pt - parameter type - * tm - typemap contents that might contain the special variable to be replaced - * jnidescriptor - if set, inner class names are separated with '$' otherwise a '/' is used for the path separator - * Outputs: - * tm - typemap contents complete with the special variable substitution - * Return: - * substitution_performed - flag indicating if a substitution was performed - * ----------------------------------------------------------------------------- */ - - bool substituteClassname(SwigType *pt, String *tm, bool jnidescriptor = false) { - bool substitution_performed = false; - SwigType *type = Copy(SwigType_typedef_resolve_all(pt)); - SwigType *strippedtype = SwigType_strip_qualifiers(type); - - if (Strstr(tm, "$javaclassname")) { - SwigType *classnametype = Copy(strippedtype); - substituteClassnameSpecialVariable(classnametype, tm, "$javaclassname", jnidescriptor); - substitution_performed = true; - Delete(classnametype); - } - if (Strstr(tm, "$*javaclassname")) { - SwigType *classnametype = Copy(strippedtype); - Delete(SwigType_pop(classnametype)); - if (Len(classnametype) > 0) { - substituteClassnameSpecialVariable(classnametype, tm, "$*javaclassname", jnidescriptor); - substitution_performed = true; - } - Delete(classnametype); - } - if (Strstr(tm, "$&javaclassname")) { - SwigType *classnametype = Copy(strippedtype); - SwigType_add_pointer(classnametype); - substituteClassnameSpecialVariable(classnametype, tm, "$&javaclassname", jnidescriptor); - substitution_performed = true; - Delete(classnametype); - } - if (Strstr(tm, "$javainterfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$javainterfacename", jnidescriptor, true); - substitution_performed = true; - Delete(interfacenametype); - } - if (Strstr(tm, "$*javainterfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - Delete(SwigType_pop(interfacenametype)); - if (Len(interfacenametype) > 0) { - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*javainterfacename", jnidescriptor, true); - substitution_performed = true; - } - Delete(interfacenametype); - } - if (Strstr(tm, "$&javainterfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - SwigType_add_pointer(interfacenametype); - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&javainterfacename", jnidescriptor, true); - substitution_performed = true; - Delete(interfacenametype); - } - if (Strstr(tm, "$interfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$interfacename", jnidescriptor, false); - substitution_performed = true; - Delete(interfacenametype); - } - if (Strstr(tm, "$*interfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - Delete(SwigType_pop(interfacenametype)); - if (Len(interfacenametype) > 0) { - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$*interfacename", jnidescriptor, false); - substitution_performed = true; - } - Delete(interfacenametype); - } - if (Strstr(tm, "$&interfacename")) { - SwigType *interfacenametype = Copy(strippedtype); - SwigType_add_pointer(interfacenametype); - substituteInterfacenameSpecialVariable(interfacenametype, tm, "$&interfacename", jnidescriptor, false); - substitution_performed = true; - Delete(interfacenametype); - } - - Delete(strippedtype); - Delete(type); - - return substitution_performed; - } - - /* ----------------------------------------------------------------------------- - * substituteClassnameSpecialVariable() - * ----------------------------------------------------------------------------- */ - - void substituteClassnameSpecialVariable(SwigType *classnametype, String *tm, const char *classnamespecialvariable, bool jnidescriptor) { - String *replacementname; - - if (SwigType_isenum(classnametype)) { - String *enumname = getEnumName(classnametype, jnidescriptor); - if (enumname) { - replacementname = Copy(enumname); - } else { - bool anonymous_enum = (Cmp(classnametype, "enum ") == 0); - if (anonymous_enum) { - replacementname = NewString("int"); - } else { - // An unknown enum - one that has not been parsed (neither a C enum forward reference nor a definition) or an ignored enum - replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype)); - Replace(replacementname, "enum ", "", DOH_REPLACE_ANY); - Setattr(swig_types_hash, replacementname, classnametype); - } - } - } else { - String *classname = getProxyName(classnametype, jnidescriptor); // getProxyName() works for pointers to classes too - if (classname) { - replacementname = Copy(classname); - } else { - // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved. - replacementname = NewStringf("SWIGTYPE%s", SwigType_manglestr(classnametype)); - - // Add to hash table so that the type wrapper classes can be created later - Setattr(swig_types_hash, replacementname, classnametype); - } - } - if (jnidescriptor) - Replaceall(replacementname,".","/"); - Replaceall(tm, classnamespecialvariable, replacementname); - - Delete(replacementname); - } - - /* ----------------------------------------------------------------------------- - * substituteInterfacenameSpecialVariable() - * ----------------------------------------------------------------------------- */ - - void substituteInterfacenameSpecialVariable(SwigType *interfacenametype, String *tm, const char *interfacenamespecialvariable, bool jnidescriptor, bool qualified) { - - String *interfacename = getInterfaceName(interfacenametype/*, jnidescriptor*/, qualified); - if (interfacename) { - String *replacementname = Copy(interfacename); - - if (jnidescriptor) - Replaceall(replacementname,".","/"); - Replaceall(tm, interfacenamespecialvariable, replacementname); - - Delete(replacementname); - } - } - - /* ----------------------------------------------------------------------------- - * emitTypeWrapperClass() - * ----------------------------------------------------------------------------- */ - - void emitTypeWrapperClass(String *classname, SwigType *type) { - Node *n = NewHash(); - Setfile(n, input_file); - Setline(n, line_number); - - String *swigtype = NewString(""); - String *filen = NewStringf("%s%s.java", SWIG_output_directory(), classname); - File *f_swigtype = NewFile(filen, "w", SWIG_output_files()); - if (!f_swigtype) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the type wrapper class file - emitBanner(f_swigtype); - - if (package) - Printf(f_swigtype, "package %s;\n", package); - - // Pure Java baseclass and interfaces - const String *pure_baseclass = typemapLookup(n, "javabase", type, WARN_NONE); - const String *pure_interfaces = typemapLookup(n, "javainterfaces", type, WARN_NONE); - - // Emit the class - Printv(swigtype, typemapLookup(n, "javaimports", type, WARN_NONE), // Import statements - "\n", typemapLookup(n, "javaclassmodifiers", type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers - " $javaclassname", // Class name and bases - *Char(pure_baseclass) ? " extends " : "", pure_baseclass, *Char(pure_interfaces) ? // Interfaces - " implements " : "", pure_interfaces, " {", typemapLookup(n, "javabody", type, WARN_JAVA_TYPEMAP_JAVABODY_UNDEF), // main body of class - typemapLookup(n, "javacode", type, WARN_NONE), // extra Java code - "}\n", "\n", NIL); - - Replaceall(swigtype, "$javaclassname", classname); - Replaceall(swigtype, "$module", module_class_name); - Replaceall(swigtype, "$imclassname", imclass_name); - - // For unknown enums - Replaceall(swigtype, "$static ", ""); - Replaceall(swigtype, "$enumvalues", ""); - - Printv(f_swigtype, swigtype, NIL); - - Delete(f_swigtype); - Delete(swigtype); - Delete(n); - } - - /* ----------------------------------------------------------------------------- - * typemapLookup() - * n - for input only and must contain info for Getfile(n) and Getline(n) to work - * tmap_method - typemap method name - * type - typemap type to lookup - * warning - warning number to issue if no typemaps found - * typemap_attributes - the typemap attributes are attached to this node and will - * also be used for temporary storage if non null - * return is never NULL, unlike Swig_typemap_lookup() - * ----------------------------------------------------------------------------- */ - - const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0) { - Node *node = !typemap_attributes ? NewHash() : typemap_attributes; - Setattr(node, "type", type); - Setfile(node, Getfile(n)); - Setline(node, Getline(n)); - const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0); - if (!tm) { - tm = empty_string; - if (warning != WARN_NONE) - Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0)); - } - if (!typemap_attributes) - Delete(node); - return tm; - } - - /* ----------------------------------------------------------------------------- - * addThrows() - * - * Adds exception classes to a throws list. The throws list is the list of classes - * that will form the Java throws clause. Mainly for checked exceptions. - * ----------------------------------------------------------------------------- */ - - void addThrows(Node *n, const String *attribute, Node *parameter) { - // Get the comma separated exception classes for the throws clause - held in typemap/feature's "throws" attribute - String *throws_attribute = NewStringf("%s:throws", attribute); - String *throws = Getattr(parameter, throws_attribute); - - if (throws && Len(throws) > 0) { - String *throws_list = Getattr(n, "java:throwslist"); - if (!throws_list) { - throws_list = NewList(); - Setattr(n, "java:throwslist", throws_list); - } - // Put the exception classes in the throws clause into a temporary List - List *temp_classes_list = Split(throws, ',', INT_MAX); - - // Add the exception classes to the node throws list, but don't duplicate if already in list - if (temp_classes_list && Len(temp_classes_list) > 0) { - for (Iterator cls = First(temp_classes_list); cls.item; cls = Next(cls)) { - String *exception_class = NewString(cls.item); - Replaceall(exception_class, " ", ""); // remove spaces - Replaceall(exception_class, "\t", ""); // remove tabs - if (Len(exception_class) > 0) { - // $javaclassname substitution - SwigType *pt = Getattr(parameter, "type"); - substituteClassname(pt, exception_class); - - // Don't duplicate the Java exception class in the throws clause - bool found_flag = false; - for (Iterator item = First(throws_list); item.item; item = Next(item)) { - if (Strcmp(item.item, exception_class) == 0) - found_flag = true; - } - if (!found_flag) - Append(throws_list, exception_class); - } - Delete(exception_class); - } - } - Delete(temp_classes_list); - } - Delete(throws_attribute); - } - - /* ----------------------------------------------------------------------------- - * generateThrowsClause() - * - * Generates throws clause for checked exception - * ----------------------------------------------------------------------------- */ - - void generateThrowsClause(Node *n, String *code) { - // Add the throws clause into code - List *throws_list = Getattr(n, "java:throwslist"); - if (throws_list) { - Iterator cls = First(throws_list); - Printf(code, " throws %s", cls.item); - while ((cls = Next(cls)).item) - Printf(code, ", %s", cls.item); - } - } - - /* ----------------------------------------------------------------------------- - * prematureGarbageCollectionPreventionParameter() - * - * Get the proxy class name for use in an additional generated parameter. The - * additional parameter is added to a native method call purely to prevent - * premature garbage collection of proxy classes which pass their C++ class pointer - * in a Java long to the JNI layer. - * ----------------------------------------------------------------------------- */ - - String *prematureGarbageCollectionPreventionParameter(SwigType *t, Parm *p) { - String *pgcpp_java_type = 0; - String *jtype = NewString(Getattr(p, "tmap:jtype")); - - // Strip C comments - String *stripped_jtype = Swig_strip_c_comments(jtype); - if (stripped_jtype) { - Delete(jtype); - jtype = stripped_jtype; - } - - // Remove whitespace - Replaceall(jtype, " ", ""); - Replaceall(jtype, "\t", ""); - - if (Cmp(jtype, "long") == 0) { - if (proxy_flag) { - if (!GetFlag(p, "tmap:jtype:nopgcpp") && !nopgcpp_flag) { - String *interface_name = getInterfaceName(t, true); - pgcpp_java_type = interface_name ? interface_name : getProxyName(t); - if (!pgcpp_java_type) { - // Look for proxy class parameters passed to C++ layer using non-default typemaps, ie not one of above types - String *jstype = NewString(Getattr(p, "tmap:jstype")); - if (jstype) { - Hash *classes = getClassHash(); - if (classes) { - // Strip C comments - String *stripped_jstype = Swig_strip_c_comments(jstype); - if (stripped_jstype) { - Delete(jstype); - jstype = stripped_jstype; - } - // Remove whitespace - Replaceall(jstype, " ", ""); - Replaceall(jstype, "\t", ""); - - Iterator ki; - for (ki = First(classes); ki.key; ki = Next(ki)) { - Node *cls = ki.item; - if (cls && !Getattr(cls, "feature:ignore")) { - String *symname = Getattr(cls, "sym:name"); - if (symname && Strcmp(symname, jstype) == 0) { - pgcpp_java_type = symname; - } - } - } - } - } - Delete(jstype); - } - } - } - } - Delete(jtype); - return pgcpp_java_type; - } - - /* ----------------------------------------------------------------------------- - * outputDirectory() - * - * Return the directory to use for generating Java classes/enums and create the - * subdirectory (does not create if language specific outdir does not exist). - * ----------------------------------------------------------------------------- */ - - String *outputDirectory(String *nspace) { - String *output_directory = Copy(SWIG_output_directory()); - if (nspace) { - String *nspace_subdirectory = Copy(nspace); - Replaceall(nspace_subdirectory, ".", SWIG_FILE_DELIMITER); - String *newdir_error = Swig_new_subdirectory(output_directory, nspace_subdirectory); - if (newdir_error) { - Printf(stderr, "%s\n", newdir_error); - Delete(newdir_error); - Exit(EXIT_FAILURE); - } - Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0); - Delete(nspace_subdirectory); - } - return output_directory; - } - - /*---------------------------------------------------------------------- - * Start of director methods - *--------------------------------------------------------------------*/ - - /*---------------------------------------------------------------------- - * getUpcallJNIMethod() - *--------------------------------------------------------------------*/ - - String *getUpcallJNIMethod(String *descrip) { - static struct { - char code; - const char *method; - } upcall_methods[] = { - { - 'B', "CallStaticByteMethod"}, { - 'C', "CallStaticCharMethod"}, { - 'D', "CallStaticDoubleMethod"}, { - 'F', "CallStaticFloatMethod"}, { - 'I', "CallStaticIntMethod"}, { - 'J', "CallStaticLongMethod"}, { - 'L', "CallStaticObjectMethod"}, { - 'S', "CallStaticShortMethod"}, { - 'V', "CallStaticVoidMethod"}, { - 'Z', "CallStaticBooleanMethod"}, { - '[', "CallStaticObjectMethod"} - }; - - char code; - int i; - - code = *Char(descrip); - for (i = 0; i < (int) (sizeof(upcall_methods) / sizeof(upcall_methods[0])); ++i) - if (code == upcall_methods[i].code) - return NewString(upcall_methods[i].method); - return NULL; - } - - /*---------------------------------------------------------------------- - * emitDirectorUpcalls() - *--------------------------------------------------------------------*/ - - void emitDirectorUpcalls() { - if (n_dmethods) { - Wrapper *w = NewWrapper(); - String *jni_imclass_name = makeValidJniName(imclass_name); - String *swig_module_init = NewString("swig_module_init"); - String *swig_module_init_jni = makeValidJniName(swig_module_init); - String *dmethod_data = NewString(""); - int n_methods = 0; - Iterator udata_iter; - - udata_iter = First(dmethods_seq); - while (udata_iter.item) { - UpcallData *udata = udata_iter.item; - Printf(dmethod_data, " { \"%s\", \"%s\" }", Getattr(udata, "imclass_method"), Getattr(udata, "imclass_fdesc")); - ++n_methods; - - udata_iter = Next(udata_iter); - - if (udata_iter.item) - Putc(',', dmethod_data); - Putc('\n', dmethod_data); - } - - Printf(f_runtime, "namespace Swig {\n"); - Printf(f_runtime, " namespace {\n"); - Printf(f_runtime, " jclass jclass_%s = NULL;\n", imclass_name); - Printf(f_runtime, " jmethodID director_method_ids[%d];\n", n_methods); - Printf(f_runtime, " }\n"); - Printf(f_runtime, "}\n"); - - Printf(w->def, "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls) {", jnipackage, jni_imclass_name, swig_module_init_jni); - Printf(w->code, "static struct {\n"); - Printf(w->code, " const char *method;\n"); - Printf(w->code, " const char *signature;\n"); - Printf(w->code, "} methods[%d] = {\n", n_methods); - Printv(w->code, dmethod_data, NIL); - Printf(w->code, "};\n"); - - Wrapper_add_local(w, "i", "int i"); - - Printf(w->code, "Swig::jclass_%s = (jclass) jenv->NewGlobalRef(jcls);\n", imclass_name); - Printf(w->code, "if (!Swig::jclass_%s) return;\n", imclass_name); - Printf(w->code, "for (i = 0; i < (int) (sizeof(methods)/sizeof(methods[0])); ++i) {\n"); - Printf(w->code, " Swig::director_method_ids[i] = jenv->GetStaticMethodID(jcls, methods[i].method, methods[i].signature);\n"); - Printf(w->code, " if (!Swig::director_method_ids[i]) return;\n"); - Printf(w->code, "}\n"); - - Printf(w->code, "}\n"); - - Wrapper_print(w, f_wrappers); - Delete(dmethod_data); - Delete(swig_module_init_jni); - Delete(swig_module_init); - Delete(jni_imclass_name); - DelWrapper(w); - } - } - - /*---------------------------------------------------------------------- - * emitDirectorExtraMethods() - * - * This is where the director connect method is generated. - *--------------------------------------------------------------------*/ - void emitDirectorExtraMethods(Node *n) { - if (!Swig_directorclass(n)) - return; - - // Output the director connect method: - String *jni_imclass_name = makeValidJniName(imclass_name); - String *norm_name = SwigType_namestr(Getattr(n, "name")); - String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect"); - String *swig_director_connect_jni = makeValidJniName(swig_director_connect); - String *smartptr = Getattr(n, "feature:smartptr"); - String *dirClassName = directorClassName(n); - Wrapper *code_wrap; - - Printf(imclass_class_code, " public final static native void %s(%s obj, long cptr, boolean mem_own, boolean weak_global);\n", - swig_director_connect, full_proxy_class_name); - - code_wrap = NewWrapper(); - Printf(code_wrap->def, - "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jswig_mem_own, " - "jboolean jweak_global) {\n", jnipackage, jni_imclass_name, swig_director_connect_jni); - - if (smartptr) { - Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", smartptr, smartptr); - Printf(code_wrap->code, " (void)jcls;\n"); - Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n"); - Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n"); - Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName); - } - else { - Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name); - Printf(code_wrap->code, " (void)jcls;\n"); - Printf(code_wrap->code, " %s *director = static_cast<%s *>(obj);\n", dirClassName, dirClassName); - } - - Printf(code_wrap->code, " director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself), " - "(jswig_mem_own == JNI_TRUE), (jweak_global == JNI_TRUE));\n"); - Printf(code_wrap->code, "}\n"); - - Wrapper_print(code_wrap, f_wrappers); - DelWrapper(code_wrap); - - Delete(swig_director_connect_jni); - Delete(swig_director_connect); - - // Output the swigReleaseOwnership, swigTakeOwnership methods: - String *changeown_method_name = Swig_name_member(getNSpace(), getClassPrefix(), "change_ownership"); - String *changeown_jnimethod_name = makeValidJniName(changeown_method_name); - - Printf(imclass_class_code, " public final static native void %s(%s obj, long cptr, boolean take_or_release);\n", changeown_method_name, full_proxy_class_name); - - code_wrap = NewWrapper(); - Printf(code_wrap->def, - "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) {\n", - jnipackage, jni_imclass_name, changeown_jnimethod_name); - - if (Len(smartptr)) { - Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", smartptr, smartptr); - Printf(code_wrap->code, " // Keep a local instance of the smart pointer around while we are using the raw pointer\n"); - Printf(code_wrap->code, " // Avoids using smart pointer specific API.\n"); - Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj->operator->());\n", dirClassName, dirClassName); - } else { - Printf(code_wrap->code, " %s *obj = *((%s **)&objarg);\n", norm_name, norm_name); - Printf(code_wrap->code, " %s *director = dynamic_cast<%s *>(obj);\n", dirClassName, dirClassName); - } - - Printf(code_wrap->code, " (void)jcls;\n"); - Printf(code_wrap->code, " if (director) {\n"); - Printf(code_wrap->code, " director->swig_java_change_ownership(jenv, jself, jtake_or_release ? true : false);\n"); - Printf(code_wrap->code, " }\n"); - Printf(code_wrap->code, "}\n"); - - Wrapper_print(code_wrap, f_wrappers); - DelWrapper(code_wrap); - - Delete(changeown_method_name); - Delete(changeown_jnimethod_name); - Delete(norm_name); - Delete(dirClassName); - Delete(jni_imclass_name); - } - - /*---------------------------------------------------------------------- - * emitCodeTypemap() - * - * Output a code typemap that uses $methodname and $jnicall, as used - * in the directordisconnect, director_release and director_take - * typemaps. - *--------------------------------------------------------------------*/ - - void emitCodeTypemap(Node *n, bool derived, SwigType *lookup_type, const String *typemap, const String *methodname, const String *jnicall) { - const String *tm = NULL; - Node *tmattrs = NewHash(); - String *lookup_tmname = NewString(typemap); - String *method_attr_name; - String *method_attr; - - if (derived) { - Append(lookup_tmname, "_derived"); - } - - tm = typemapLookup(n, lookup_tmname, lookup_type, WARN_NONE, tmattrs); - method_attr_name = NewStringf("tmap:%s:%s", lookup_tmname, methodname); - method_attr = Getattr(tmattrs, method_attr_name); - - if (*Char(tm)) { - if (method_attr) { - String *codebody = Copy(tm); - Replaceall(codebody, "$methodname", method_attr); - Replaceall(codebody, "$jnicall", jnicall); - Append(proxy_class_def, codebody); - Delete(codebody); - } else { - Swig_error(input_file, line_number, "No %s method name attribute for %s\n", lookup_tmname, proxy_class_name); - } - } else { - Swig_error(input_file, line_number, "No %s typemap for %s\n", lookup_tmname, proxy_class_name); - } - - Delete(tmattrs); - Delete(lookup_tmname); - // Delete(method_attr); - } - - /* ----------------------------------------------------------------------------- - * substitutePackagePath() - * - * Replace $packagepath using the javapackage typemap associated with passed - * parm or global package if p is 0. "$packagepath/" is replaced with "" if - * no package is set. Note that the path separator is a '/'. - * ----------------------------------------------------------------------------- */ - - void substitutePackagePath(String *text, Parm *p) { - String *pkg_path= 0; - - if (p) - pkg_path = Swig_typemap_lookup("javapackage", p, "", 0); - if (!pkg_path || Len(pkg_path) == 0) - pkg_path = Copy(package_path); - - if (Len(pkg_path) > 0) { - Replaceall(pkg_path, ".", "/"); - Replaceall(text, "$packagepath", pkg_path); - } else { - Replaceall(text, "$packagepath/", empty_string); - Replaceall(text, "$packagepath", empty_string); - } - Delete(pkg_path); - } - - /* --------------------------------------------------------------- - * Canonicalize the JNI field descriptor - * - * Replace the $packagepath and $javaclassname family of special - * variables with the desired package and Java proxy name as - * required in the JNI field descriptors. - * - * !!SFM!! If $packagepath occurs in the field descriptor, but - * package_path isn't set (length == 0), then strip it and the - * optional trailing '/' from the resulting name. - * - * --------------------------------------------------------------- */ - - String *canonicalizeJNIDescriptor(String *descriptor_in, Parm *p) { - SwigType *type = Getattr(p, "type"); - String *descriptor_out = Copy(descriptor_in); - - substituteClassname(type, descriptor_out, true); - substitutePackagePath(descriptor_out, p); - - return descriptor_out; - } - - /* --------------------------------------------------------------- - * classDirectorMethod() - * - * Emit a virtual director method to pass a method call on to the - * underlying Java object. - * - * --------------------------------------------------------------- */ - - int classDirectorMethod(Node *n, Node *parent, String *super) { - String *c_classname = Getattr(parent, "name"); - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - SwigType *returntype = Getattr(n, "type"); - String *overloaded_name = getOverloadedName(n); - String *storage = Getattr(n, "storage"); - String *value = Getattr(n, "value"); - String *decl = Getattr(n, "decl"); - String *declaration = NewString(""); - String *tm; - Parm *p; - int i; - Wrapper *w = NewWrapper(); - ParmList *l = Getattr(n, "parms"); - bool is_void = !(Cmp(returntype, "void")); - String *qualified_return = 0; - bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0"))); - int status = SWIG_OK; - bool output_director = true; - String *dirclassname = directorClassName(parent); - String *qualified_name = NewStringf("%s::%s", dirclassname, name); - String *jnidesc = NewString(""); - String *classdesc = NewString(""); - String *jniret_desc = NewString(""); - String *classret_desc = NewString(""); - SwigType *c_ret_type = NULL; - String *jupcall_args = NewString("swigjobj"); - String *imclass_dmethod; - String *callback_def = NewString(""); - String *callback_code = NewString(""); - String *imcall_args = NewString(""); - int classmeth_off = curr_class_dmethod - first_class_dmethod; - bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; - String *qualified_classname = getProxyName(getClassName()); - - // Kludge Alert: functionWrapper sets sym:overload properly, but it - // isn't at this point, so we have to manufacture it ourselves. At least - // we're consistent with the sym:overload name in functionWrapper. (?? when - // does the overloaded method name get set?) - - imclass_dmethod = NewStringf("%s", Swig_name_member(getNSpace(), dirclassname, overloaded_name)); - - qualified_return = SwigType_rcaststr(returntype, "c_result"); - - if (!is_void && (!ignored_method || pure_virtual)) { - if (!SwigType_isclass(returntype)) { - if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { - String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); - Delete(construct_result); - } else { - String *base_typename = SwigType_base(returntype); - String *resolved_typename = SwigType_typedef_resolve_all(base_typename); - Symtab *symtab = Getattr(n, "sym:symtab"); - Node *typenode = Swig_symbol_clookup(resolved_typename, symtab); - - if (SwigType_ispointer(returntype) || (typenode && Getattr(typenode, "abstracts"))) { - /* initialize pointers to something sane. Same for abstract - classes when a reference is returned. */ - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); - } else { - /* If returning a reference, initialize the pointer to a sane - default - if a Java exception occurs, then the pointer returns - something other than a NULL-initialized reference. */ - SwigType *noref_type = SwigType_del_reference(Copy(returntype)); - String *noref_ltype = SwigType_lstr(noref_type, 0); - String *return_ltype = SwigType_lstr(returntype, 0); - - Wrapper_add_localv(w, "result_default", "static", noref_ltype, "result_default", NIL); - Wrapper_add_localv(w, "c_result", return_ltype, "c_result", NIL); - Printf(w->code, "result_default = SwigValueInit< %s >();\n", noref_ltype); - Printf(w->code, "c_result = &result_default;\n"); - Delete(return_ltype); - Delete(noref_ltype); - Delete(noref_type); - } - - Delete(base_typename); - Delete(resolved_typename); - } - } else { - SwigType *vt; - - vt = cplus_value_type(returntype); - if (!vt) { - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), NIL); - } else { - Wrapper_add_localv(w, "c_result", SwigType_lstr(vt, "c_result"), NIL); - Delete(vt); - } - } - } - - /* Create the intermediate class wrapper */ - tm = Swig_typemap_lookup("jtype", n, "", 0); - if (tm) { - Printf(callback_def, " public static %s %s(%s jself", tm, imclass_dmethod, qualified_classname); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(returntype, 0)); - } - - String *cdesc = NULL; - SwigType *covariant = Getattr(n, "covariant"); - SwigType *adjustedreturntype = covariant ? covariant : returntype; - Parm *adjustedreturntypeparm = NewParmNode(adjustedreturntype, n); - - if (Swig_typemap_lookup("directorin", adjustedreturntypeparm, "", 0) - && (cdesc = Getattr(adjustedreturntypeparm, "tmap:directorin:descriptor"))) { - - // Note that in the case of polymorphic (covariant) return types, the - // method's return type is changed to be the base of the C++ return - // type - String *jnidesc_canon = canonicalizeJNIDescriptor(cdesc, adjustedreturntypeparm); - Append(classret_desc, jnidesc_canon); - Delete(jnidesc_canon); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - /* Get the JNI field descriptor for this return type, add the JNI field descriptor - to jniret_desc */ - if ((c_ret_type = Swig_typemap_lookup("jni", n, "", 0))) { - Parm *tp = NewParmNode(c_ret_type, n); - - if (!is_void && !ignored_method) { - String *jretval_decl = NewStringf("%s jresult", c_ret_type); - Wrapper_add_localv(w, "jresult", jretval_decl, "= 0", NIL); - Delete(jretval_decl); - } - - String *jdesc = NULL; - if (Swig_typemap_lookup("directorin", tp, "", 0) - && (jdesc = Getattr(tp, "tmap:directorin:descriptor"))) { - - // Objects marshalled passing a Java class across JNI boundary use jobject - the nouse flag indicates this - // We need the specific Java class name instead of the generic 'Ljava/lang/Object;' - if (GetFlag(tp, "tmap:directorin:nouse")) - jdesc = cdesc; - String *jnidesc_canon = canonicalizeJNIDescriptor(jdesc, tp); - Append(jniret_desc, jnidesc_canon); - Delete(jnidesc_canon); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, - "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(c_ret_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - Delete(tp); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - Delete(adjustedreturntypeparm); - - Swig_director_parms_fixup(l); - - /* Attach the standard typemaps */ - Swig_typemap_attach_parms("out", l, 0); - Swig_typemap_attach_parms("jni", l, 0); - Swig_typemap_attach_parms("jtype", l, 0); - Swig_typemap_attach_parms("directorin", l, w); - Swig_typemap_attach_parms("javadirectorin", l, 0); - Swig_typemap_attach_parms("directorargout", l, w); - - if (!ignored_method) { - /* Add Java environment pointer to wrapper */ - String *jenvstr = NewString("jenv"); - String *jobjstr = NewString("swigjobj"); - - Wrapper_add_localv(w, "swigjnienv", "JNIEnvWrapper", "swigjnienv(this)", NIL, NIL); - Wrapper_add_localv(w, jenvstr, "JNIEnv *", jenvstr, "= swigjnienv.getJNIEnv()", NIL); - Wrapper_add_localv(w, jobjstr, "jobject", jobjstr, "= (jobject) NULL", NIL); - Delete(jenvstr); - Delete(jobjstr); - - /* Preamble code */ - Printf(w->code, "if (!swig_override[%d]) {\n", classmeth_off); - } - - if (!pure_virtual) { - String *super_call = Swig_method_call(super, l); - if (is_void) { - Printf(w->code, "%s;\n", super_call); - if (!ignored_method) - Printf(w->code, "return;\n"); - } else { - Printf(w->code, "return %s;\n", super_call); - } - Delete(super_call); - } else { - Printf(w->code, "SWIG_JavaThrowException(JNIEnvWrapper(this).getJNIEnv(), SWIG_JavaDirectorPureVirtual, "); - Printf(w->code, "\"Attempted to invoke pure virtual method %s::%s.\");\n", SwigType_namestr(c_classname), SwigType_namestr(name)); - - /* Make sure that we return something in the case of a pure - * virtual method call for syntactical reasons. */ - if (!is_void) - Printf(w->code, "return %s;", qualified_return); - else if (!ignored_method) - Printf(w->code, "return;\n"); - } - - if (!ignored_method) { - Printf(w->code, "}\n"); - Printf(w->code, "swigjobj = swig_get_self(jenv);\n"); - Printf(w->code, "if (swigjobj && jenv->IsSameObject(swigjobj, NULL) == JNI_FALSE) {\n"); - } - - /* Start the Java field descriptor for the intermediate class's upcall (insert jself object) */ - Parm *tp = NewParmNode(c_classname, n); - String *jdesc; - - if ((tm = Swig_typemap_lookup("directorin", tp, "", 0)) - && (jdesc = Getattr(tp, "tmap:directorin:descriptor"))) { - String *jni_canon = canonicalizeJNIDescriptor(jdesc, tp); - Append(jnidesc, jni_canon); - Delete(jni_canon); - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, - "No or improper directorin typemap for type %s for use in %s::%s (skipping director method)\n", - SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - Delete(tp); - - /* Go through argument list, convert from native to Java */ - for (i = 0, p = l; p; ++i) { - /* Is this superfluous? */ - while (checkAttribute(p, "tmap:directorin:numinputs", "0")) { - p = Getattr(p, "tmap:directorin:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *ln = makeParameterName(n, p, i, false); - String *c_param_type = NULL; - String *c_decl = NewString(""); - String *arg = NewString(""); - - Printf(arg, "j%s", ln); - - /* Add various typemap's 'throws' clauses */ - addThrows(n, "tmap:directorin", p); - addThrows(n, "tmap:out", p); - - /* And add to the upcall args */ - Printf(jupcall_args, ", %s", arg); - - /* Get parameter's intermediary C type */ - if ((c_param_type = Getattr(p, "tmap:jni"))) { - Parm *tp = NewParm(c_param_type, Getattr(p, "name"), n); - String *desc_tm = NULL, *jdesc = NULL, *cdesc = NULL; - - /* Add to local variables */ - Printf(c_decl, "%s %s", c_param_type, arg); - if (!ignored_method) - Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL); - - /* Add input marshalling code and update JNI field descriptor */ - if ((desc_tm = Swig_typemap_lookup("directorin", tp, "", 0)) - && (jdesc = Getattr(tp, "tmap:directorin:descriptor")) - && (tm = Getattr(p, "tmap:directorin")) - && (cdesc = Getattr(p, "tmap:directorin:descriptor"))) { - - // Objects marshalled by passing a Java class across the JNI boundary use jobject as the JNI type - - // the nouse flag indicates this. We need the specific Java class name instead of the generic 'Ljava/lang/Object;' - if (GetFlag(tp, "tmap:directorin:nouse")) - jdesc = cdesc; - String *jni_canon = canonicalizeJNIDescriptor(jdesc, tp); - Append(jnidesc, jni_canon); - Delete(jni_canon); - - Setattr(p, "emit:directorinput", arg); - Replaceall(tm, "$input", arg); - Replaceall(tm, "$owner", "0"); - - if (Len(tm)) - if (!ignored_method) - Printf(w->code, "%s\n", tm); - - /* Add parameter to the intermediate class code if generating the - * intermediate's upcall code */ - if ((tm = Getattr(p, "tmap:jtype"))) { - String *din = Copy(Getattr(p, "tmap:javadirectorin")); - addThrows(n, "tmap:javadirectorin", p); - - if (din) { - Replaceall(din, "$module", module_class_name); - Replaceall(din, "$imclassname", imclass_name); - substituteClassname(pt, din); - Replaceall(din, "$jniinput", ln); - - if (i > 0) - Printf(imcall_args, ", "); - Printf(callback_def, ", %s %s", tm, ln); - - if (Cmp(din, ln)) { - Printv(imcall_args, din, NIL); - } else - Printv(imcall_args, ln, NIL); - - jni_canon = canonicalizeJNIDescriptor(cdesc, p); - Append(classdesc, jni_canon); - Delete(jni_canon); - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF, input_file, line_number, "No javadirectorin typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - p = Getattr(p, "tmap:directorin:next"); - - Delete(desc_tm); - } else { - if (!desc_tm) { - Swig_warning(WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF, input_file, line_number, - "No or improper directorin typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(c_param_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - p = nextSibling(p); - } else if (!jdesc) { - Swig_warning(WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC, input_file, line_number, - "Missing JNI descriptor in directorin typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(c_param_type, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - p = Getattr(p, "tmap:directorin:next"); - } else if (!tm) { - Swig_warning(WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF, input_file, line_number, - "No or improper directorin typemap defined for argument %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - p = nextSibling(p); - } else if (!cdesc) { - Swig_warning(WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC, input_file, line_number, - "Missing JNI descriptor in directorin typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - p = Getattr(p, "tmap:directorin:next"); - } - - output_director = false; - } - - } else { - Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s for use in %s::%s (skipping director method)\n", - SwigType_str(pt, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - p = nextSibling(p); - } - - Delete(arg); - Delete(c_decl); - Delete(ln); - } - - /* header declaration, start wrapper definition */ - String *target; - SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type"); - target = Swig_method_decl(rtype, decl, qualified_name, l, 0); - Printf(w->def, "%s", target); - Delete(qualified_name); - Delete(target); - target = Swig_method_decl(rtype, decl, name, l, 1); - Printf(declaration, " virtual %s", target); - Delete(target); - - // Add any exception specifications to the methods in the director class - // Get any Java exception classes in the throws typemap - ParmList *throw_parm_list = NULL; - - // May need to add Java throws clause to director methods if %catches defined - // Get any Java exception classes in the throws typemap - ParmList *catches_list = Getattr(n, "catchlist"); - if (catches_list) { - Swig_typemap_attach_parms("throws", catches_list, 0); - Swig_typemap_attach_parms("directorthrows", catches_list, 0); - for (p = catches_list; p; p = nextSibling(p)) { - addThrows(n, "tmap:throws", p); - } - } - - if (Getattr(n, "noexcept")) { - Append(w->def, " noexcept"); - Append(declaration, " noexcept"); - } - if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { - int gencomma = 0; - - Append(w->def, " throw("); - Append(declaration, " throw("); - - if (throw_parm_list) { - Swig_typemap_attach_parms("throws", throw_parm_list, 0); - Swig_typemap_attach_parms("directorthrows", throw_parm_list, 0); - } - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - // %catches replaces the specified exception specification - if (!catches_list) { - addThrows(n, "tmap:throws", p); - } - - if (gencomma++) { - Append(w->def, ", "); - Append(declaration, ", "); - } - - Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0)); - Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0)); - } - } - - Append(w->def, ")"); - Append(declaration, ")"); - } - - Append(w->def, " {"); - Append(declaration, ";\n"); - - /* Emit the intermediate class's upcall to the actual class */ - - String *upcall = NewStringf("jself.%s(%s)", symname, imcall_args); - - // Handle exception classes specified in the "except" feature's "throws" attribute - addThrows(n, "feature:except", n); - - if (!is_void) { - if ((tm = Swig_typemap_lookup("javadirectorout", n, "", 0))) { - addThrows(n, "tmap:javadirectorout", n); - substituteClassname(returntype, tm); - Replaceall(tm, "$javacall", upcall); - - Printf(callback_code, " return %s;\n", tm); - } - - if ((tm = Swig_typemap_lookup("out", n, "", 0))) - addThrows(n, "tmap:out", n); - - Delete(tm); - } else - Printf(callback_code, " %s;\n", upcall); - - Printf(callback_code, " }\n"); - Delete(upcall); - - /* Finish off the inherited upcall's definition */ - Putc(')', callback_def); - generateThrowsClause(n, callback_def); - Printf(callback_def, " {\n"); - - if (!ignored_method) { - /* Emit the actual upcall through */ - String *imclass_desc = NewStringf("(%s)%s", jnidesc, jniret_desc); - String *class_desc = NewStringf("(%s)%s", classdesc, classret_desc); - UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, imclass_desc, class_desc, decl); - String *methid = Getattr(udata, "imclass_methodidx"); - String *methop = getUpcallJNIMethod(jniret_desc); - - if (!is_void) - Printf(w->code, "jresult = (%s) ", c_ret_type); - - Printf(w->code, "jenv->%s(Swig::jclass_%s, Swig::director_method_ids[%s], %s);\n", methop, imclass_name, methid, jupcall_args); - - // Generate code to handle any Java exception thrown by director delegation - directorExceptHandler(n, catches_list ? catches_list : throw_parm_list, w); - - if (!is_void) { - String *jresult_str = NewString("jresult"); - String *result_str = NewString("c_result"); - - /* Copy jresult into c_result... */ - if ((tm = Swig_typemap_lookup("directorout", n, result_str, w))) { - addThrows(n, "tmap:directorout", n); - Replaceall(tm, "$input", jresult_str); - Replaceall(tm, "$result", result_str); - Printf(w->code, "%s\n", tm); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, - "Unable to use return type %s used in %s::%s (skipping director method)\n", - SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - output_director = false; - } - - Delete(jresult_str); - Delete(result_str); - } - - /* Marshal outputs */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:directorargout"))) { - addThrows(n, "tmap:directorargout", p); - Replaceall(tm, "$result", makeParameterName(n, p, i, false)); - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NIL); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } - } - - Delete(imclass_desc); - Delete(class_desc); - - /* Terminate wrapper code */ - Printf(w->code, "} else {\n"); - Printf(w->code, "SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, \"null upcall object in %s::%s \");\n", - SwigType_namestr(c_classname), SwigType_namestr(name)); - Printf(w->code, "}\n"); - - Printf(w->code, "if (swigjobj) jenv->DeleteLocalRef(swigjobj);\n"); - - if (!is_void) - Printf(w->code, "return %s;", qualified_return); - } - - Printf(w->code, "}"); - - // We expose virtual protected methods via an extra public inline method which makes a straight call to the wrapped class' method - String *inline_extra_method = NewString(""); - if (dirprot_mode() && !is_public(n) && !pure_virtual) { - Printv(inline_extra_method, declaration, NIL); - String *extra_method_name = NewStringf("%sSwigPublic", name); - Replaceall(inline_extra_method, name, extra_method_name); - Replaceall(inline_extra_method, ";\n", " {\n "); - if (!is_void) - Printf(inline_extra_method, "return "); - String *methodcall = Swig_method_call(super, l); - Printv(inline_extra_method, methodcall, ";\n }\n", NIL); - Delete(methodcall); - Delete(extra_method_name); - } - - /* emit the director method */ - if (status == SWIG_OK && output_director) { - if (!is_void) { - Replaceall(w->code, "$null", qualified_return); - } else { - Replaceall(w->code, "$null", ""); - } - if (!GetFlag(n, "feature:ignore")) - Printv(imclass_directors, callback_def, callback_code, NIL); - if (!Getattr(n, "defaultargs")) { - Replaceall(w->code, "$symname", symname); - Wrapper_print(w, f_directors); - Printv(f_directors_h, declaration, NIL); - Printv(f_directors_h, inline_extra_method, NIL); - } - } - - Delete(inline_extra_method); - Delete(qualified_return); - Delete(jnidesc); - Delete(c_ret_type); - Delete(jniret_desc); - Delete(declaration); - Delete(callback_def); - Delete(callback_code); - DelWrapper(w); - - return status; - } - - /* ------------------------------------------------------------ - * directorExceptHandler() - * - * Emit code to map Java exceptions back to C++ exceptions when - * feature("director:except") is applied to a method node. - * This is generated after the Java method upcall. - * ------------------------------------------------------------ */ - - void directorExceptHandler(Node *n, ParmList *throw_parm_list, Wrapper *w) { - - String *directorexcept = Getattr(n, "feature:director:except"); - if (!directorexcept) { - directorexcept = NewString(""); - Printf(directorexcept, "jthrowable $error = jenv->ExceptionOccurred();\n"); - Printf(directorexcept, "if ($error) {"); - Printf(directorexcept, "$directorthrowshandlers\n"); - Printf(directorexcept, " Swig::DirectorException::raise(jenv, $error);\n"); - Printf(directorexcept, "}\n"); - } else { - directorexcept = Copy(directorexcept); - } - - // Can explicitly disable director:except by setting to "" or "0" - if (Len(directorexcept) > 0 && Cmp(directorexcept, "0") != 0) { - - // Replace $packagepath - substitutePackagePath(directorexcept, 0); - - // Replace $directorthrowshandlers with any defined typemap handlers (or nothing) - if (Strstr(directorexcept, "$directorthrowshandlers")) { - String *directorthrowshandlers_code = NewString(""); - - for (Parm *p = throw_parm_list; p; p = nextSibling(p)) { - String *tm = Getattr(p, "tmap:directorthrows"); - - if (tm) { - // replace $packagepath/$javaclassname - String *directorthrows = canonicalizeJNIDescriptor(tm, p); - Printv(directorthrowshandlers_code, directorthrows, NIL); - Delete(directorthrows); - } else { - String *t = Getattr(p,"type"); - Swig_warning(WARN_TYPEMAP_DIRECTORTHROWS_UNDEF, Getfile(n), Getline(n), "No directorthrows typemap defined for %s\n", SwigType_str(t, 0)); - } - } - Replaceall(directorexcept, "$directorthrowshandlers", directorthrowshandlers_code); - Delete(directorthrowshandlers_code); - } - - Replaceall(directorexcept, "$error", "swigerror"); - Printf(w->code, " %s\n", directorexcept); - } - Delete(directorexcept); - } - - /* ------------------------------------------------------------ - * directorPrefixArgs() - * ------------------------------------------------------------ */ - - void directorPrefixArgs(Node *n) { - Parm *p; - - /* Need to prepend 'jenv' to the director constructor's argument list */ - - String *jenv_type = NewString("JNIEnv"); - - SwigType_add_pointer(jenv_type); - - p = NewParm(jenv_type, NewString("jenv"), n); - Setattr(p, "arg:byname", "1"); - set_nextSibling(p, NULL); - - Setattr(n, "director:prefix_args", p); - } - - /* ------------------------------------------------------------ - * classDirectorConstructor() - * ------------------------------------------------------------ */ - - int classDirectorConstructor(Node *n) { - Node *parent = parentNode(n); - String *decl = Getattr(n, "decl"); - String *supername = Swig_class_name(parent); - String *dirclassname = directorClassName(parent); - String *sub = NewString(""); - Parm *p; - ParmList *superparms = Getattr(n, "parms"); - ParmList *parms; - int argidx = 0; - - /* Assign arguments to superclass's parameters, if not already done */ - for (p = superparms; p; p = nextSibling(p)) { - String *pname = Getattr(p, "name"); - - if (!pname) { - pname = NewStringf("arg%d", argidx++); - Setattr(p, "name", pname); - } - } - - /* insert jenv prefix argument */ - parms = CopyParmList(superparms); - - String *jenv_type = NewString("JNIEnv"); - SwigType_add_pointer(jenv_type); - p = NewParm(jenv_type, NewString("jenv"), n); - set_nextSibling(p, parms); - parms = p; - - directorPrefixArgs(n); - - if (!Getattr(n, "defaultargs")) { - /* constructor */ - { - String *basetype = Getattr(parent, "classtype"); - String *target = Swig_method_decl(0, decl, dirclassname, parms, 0); - String *call = Swig_csuperclass_call(0, basetype, superparms); - String *classtype = SwigType_namestr(Getattr(n, "name")); - - Printf(f_directors, "%s::%s : %s, %s {\n", dirclassname, target, call, Getattr(parent, "director:ctor")); - Printf(f_directors, "}\n\n"); - - Delete(classtype); - Delete(target); - Delete(call); - } - - /* constructor header */ - { - String *target = Swig_method_decl(0, decl, dirclassname, parms, 1); - Printf(f_directors_h, " %s;\n", target); - Delete(target); - } - } - - Delete(sub); - Delete(supername); - Delete(jenv_type); - Delete(parms); - Delete(dirclassname); - return Language::classDirectorConstructor(n); - } - - /* ------------------------------------------------------------ - * classDirectorDefaultConstructor() - * ------------------------------------------------------------ */ - - int classDirectorDefaultConstructor(Node *n) { - String *classname = Swig_class_name(n); - String *classtype = SwigType_namestr(Getattr(n, "name")); - String *dirClassName = directorClassName(n); - Wrapper *w = NewWrapper(); - - Printf(w->def, "%s::%s(JNIEnv *jenv) : %s {", dirClassName, dirClassName, Getattr(n, "director:ctor")); - Printf(w->code, "}\n"); - Wrapper_print(w, f_directors); - - Printf(f_directors_h, " %s(JNIEnv *jenv);\n", dirClassName); - DelWrapper(w); - Delete(classtype); - Delete(classname); - Delete(dirClassName); - directorPrefixArgs(n); - return Language::classDirectorDefaultConstructor(n); - } - - - /* ------------------------------------------------------------ - * classDirectorInit() - * ------------------------------------------------------------ */ - - int classDirectorInit(Node *n) { - Delete(none_comparison); - none_comparison = NewString(""); // not used - - Delete(director_ctor_code); - director_ctor_code = NewString("$director_new"); - - directorDeclaration(n); - - Printf(f_directors_h, "%s {\n", Getattr(n, "director:decl")); - Printf(f_directors_h, "\npublic:\n"); - Printf(f_directors_h, " void swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global);\n"); - - /* Keep track of the director methods for this class */ - first_class_dmethod = curr_class_dmethod = n_dmethods; - - return Language::classDirectorInit(n); - } - - /* ---------------------------------------------------------------------- - * classDirectorDestructor() - * ---------------------------------------------------------------------- */ - - int classDirectorDestructor(Node *n) { - Node *current_class = getCurrentClass(); - String *full_classname = Getattr(current_class, "name"); - String *classname = Swig_class_name(current_class); - String *dirClassName = directorClassName(current_class); - Wrapper *w = NewWrapper(); - - if (Getattr(n, "noexcept")) { - Printf(f_directors_h, " virtual ~%s() noexcept;\n", dirClassName); - Printf(w->def, "%s::~%s() noexcept {\n", dirClassName, dirClassName); - } else if (Getattr(n, "throw")) { - Printf(f_directors_h, " virtual ~%s() throw();\n", dirClassName); - Printf(w->def, "%s::~%s() throw() {\n", dirClassName, dirClassName); - } else { - Printf(f_directors_h, " virtual ~%s();\n", dirClassName); - Printf(w->def, "%s::~%s() {\n", dirClassName, dirClassName); - } - - /* Ensure that correct directordisconnect typemap's method name is called - * here: */ - - Node *disconn_attr = NewHash(); - String *disconn_methodname = NULL; - - typemapLookup(n, "directordisconnect", full_classname, WARN_NONE, disconn_attr); - disconn_methodname = Getattr(disconn_attr, "tmap:directordisconnect:methodname"); - - Printv(w->code, " swig_disconnect_director_self(\"", disconn_methodname, "\");\n", "}\n", NIL); - - Wrapper_print(w, f_directors); - - DelWrapper(w); - Delete(disconn_attr); - Delete(classname); - Delete(dirClassName); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * classDirectorEnd() - * ------------------------------------------------------------ */ - - int classDirectorEnd(Node *n) { - String *full_classname = Getattr(n, "name"); - String *classname = getProxyName(full_classname, true); - String *director_classname = directorClassName(n); - String *internal_classname; - - Wrapper *w = NewWrapper(); - - if (Len(package_path) > 0) - internal_classname = NewStringf("%s/%s", package_path, classname); - else - internal_classname = NewStringf("%s", classname); - - // If the namespace is multiple levels, the result of getNSpace() will have inserted - // .'s to delimit namespaces, so we need to replace those with /'s - Replace(internal_classname, NSPACE_SEPARATOR, "/", DOH_REPLACE_ANY); - - Printf(w->def, "void %s::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global) {", director_classname); - - Printf(w->def, "static jclass baseclass = swig_new_global_ref(jenv, \"%s\");\n", internal_classname); - Printf(w->def, "if (!baseclass) return;\n"); - - if (first_class_dmethod != curr_class_dmethod) { - Printf(w->def, "static SwigDirectorMethod methods[] = {\n"); - - for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) { - UpcallData *udata = Getitem(dmethods_seq, i); - - Printf(w->def, "SwigDirectorMethod(jenv, baseclass, \"%s\", \"%s\")", Getattr(udata, "method"), Getattr(udata, "fdesc")); - if (i != curr_class_dmethod - 1) - Putc(',', w->def); - Putc('\n', w->def); - } - - Printf(w->def, "};"); - } - - Printf(w->code, "if (swig_set_self(jenv, jself, swig_mem_own, weak_global)) {\n"); - - int n_methods = curr_class_dmethod - first_class_dmethod; - - if (n_methods) { - /* Emit the swig_overrides() method and the swig_override array */ - Printf(f_directors_h, "public:\n"); - Printf(f_directors_h, " bool swig_overrides(int n) {\n"); - Printf(f_directors_h, " return (n < %d ? swig_override[n] : false);\n", n_methods); - Printf(f_directors_h, " }\n"); - Printf(f_directors_h, "protected:\n"); - Printf(f_directors_h, " Swig::BoolArray<%d> swig_override;\n", n_methods); - - /* Emit the code to look up the class's methods, initialize the override array */ - - Printf(w->code, " bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true);\n"); - Printf(w->code, " for (int i = 0; i < %d; ++i) {\n", n_methods); - // Generally, derived classes have a mix of overridden and - // non-overridden methods and it is worth making a GetMethodID - // check during initialization to determine if each method is - // overridden, thus avoiding unnecessary calls into Java. - // - // On the other hand, when derived classes are - // expected to override all director methods then the - // GetMethodID calls are inefficient, and it is better to let - // the director unconditionally call up into Java. The resulting code - // will still behave correctly (though less efficiently) when Java - // code doesn't override a given method. - // - // The assumeoverride feature on a director controls whether or not - // overrides are assumed. - if (GetFlag(n, "feature:director:assumeoverride")) { - Printf(w->code, " swig_override[i] = derived;\n"); - } else { - Printf(w->code, " swig_override[i] = false;\n"); - Printf(w->code, " if (derived) {\n"); - Printf(w->code, " jmethodID methid = jenv->GetMethodID(jcls, methods[i].name, methods[i].desc);\n"); - Printf(w->code, " swig_override[i] = methods[i].methid && (methid != methods[i].methid);\n"); - Printf(w->code, " jenv->ExceptionClear();\n"); - Printf(w->code, " }\n"); - } - Printf(w->code, "}\n"); - } else { - Printf(f_directors_h, "public:\n"); - Printf(f_directors_h, " bool swig_overrides(int n) {\n"); - Printf(f_directors_h, " return false;\n"); - Printf(f_directors_h, " }\n"); - } - - Printf(f_directors_h, "};\n\n"); - Printf(w->code, "}\n"); - Printf(w->code, "}\n"); - - Wrapper_print(w, f_directors); - - DelWrapper(w); - Delete(internal_classname); - - return Language::classDirectorEnd(n); - } - - /* -------------------------------------------------------------------- - * classDirectorDisown() - * ------------------------------------------------------------------*/ - - virtual int classDirectorDisown(Node *n) { - (void) n; - return SWIG_OK; - } - - /*---------------------------------------------------------------------- - * extraDirectorProtectedCPPMethodsRequired() - *--------------------------------------------------------------------*/ - - bool extraDirectorProtectedCPPMethodsRequired() const { - return false; - } - - /*---------------------------------------------------------------------- - * directorDeclaration() - * - * Generate the director class's declaration - * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {" - *--------------------------------------------------------------------*/ - - void directorDeclaration(Node *n) { - String *base = Getattr(n, "classtype"); - String *class_ctor = NewString("Swig::Director(jenv)"); - - String *directorname = directorClassName(n); - String *declaration = Swig_class_declaration(n, directorname); - - Printf(declaration, " : public %s, public Swig::Director", base); - - // Stash stuff for later. - Setattr(n, "director:decl", declaration); - Setattr(n, "director:ctor", class_ctor); - } - - /*---------------------------------------------------------------------- - * nestedClassesSupport() - *--------------------------------------------------------------------*/ - - NestedClassSupport nestedClassesSupport() const { - return NCS_Full; - } -}; /* class JAVA */ - -/* ----------------------------------------------------------------------------- - * swig_java() - Instantiate module - * ----------------------------------------------------------------------------- */ - -static Language *new_swig_java() { - return new JAVA(); -} -extern "C" Language *swig_java(void) { - return new_swig_java(); -} - -/* ----------------------------------------------------------------------------- - * Static member variables - * ----------------------------------------------------------------------------- */ - -const char *JAVA::usage = "\ -Java Options (available with -java)\n\ - -doxygen - Convert C++ doxygen comments to JavaDoc comments in proxy classes\n\ - -debug-doxygen-parser - Display doxygen parser module debugging information\n\ - -debug-doxygen-translator - Display doxygen translator module debugging information\n\ - -nopgcpp - Suppress premature garbage collection prevention parameter\n\ - -noproxy - Generate the low-level functional interface instead\n\ - of proxy classes\n\ - -oldvarnames - Old intermediary method names for variable wrappers\n\ - -package <name> - Set name of the Java package to <name>\n\ -\n"; diff --git a/contrib/tools/swig/Source/Modules/javascript.cxx b/contrib/tools/swig/Source/Modules/javascript.cxx deleted file mode 100644 index 17effc220fa..00000000000 --- a/contrib/tools/swig/Source/Modules/javascript.cxx +++ /dev/null @@ -1,2490 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * javascript.cxx - * - * Javascript language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" - -/** - * Enables extra debugging information in typemaps. - */ -static bool js_template_enable_debug = false; - -#define ERR_MSG_ONLY_ONE_ENGINE_PLEASE "Only one engine can be specified at a time." - -// keywords used for state variables -#define NAME "name" -#define NAME_MANGLED "name_mangled" -#define TYPE "type" -#define TYPE_MANGLED "type_mangled" -#define WRAPPER_NAME "wrapper" -#define IS_IMMUTABLE "is_immutable" -#define IS_STATIC "is_static" -#define IS_ABSTRACT "is_abstract" -#define GETTER "getter" -#define SETTER "setter" -#define PARENT "parent" -#define PARENT_MANGLED "parent_mangled" -#define CTOR "ctor" -#define CTOR_WRAPPERS "ctor_wrappers" -#define CTOR_DISPATCHERS "ctor_dispatchers" -#define DTOR "dtor" -#define ARGCOUNT "wrap:argc" -#define HAS_TEMPLATES "has_templates" -#define FORCE_CPP "force_cpp" -#define RESET true - -// keys for global state variables -#define CREATE_NAMESPACES "create_namespaces" -#define REGISTER_NAMESPACES "register_namespaces" -#define INITIALIZER "initializer" - -// keys for class scoped state variables -#define MEMBER_VARIABLES "member_variables" -#define MEMBER_FUNCTIONS "member_functions" -#define STATIC_FUNCTIONS "static_functions" -#define STATIC_VARIABLES "static_variables" - - -/** - * A convenience class to manage state variables for emitters. - * The implementation delegates to SWIG Hash DOHs and provides - * named sub-hashes for class, variable, and function states. - */ -class JSEmitterState { - -public: - JSEmitterState(); - ~JSEmitterState(); - DOH *globals(); - DOH *globals(const char *key, DOH *initial = 0); - DOH *clazz(bool reset = false); - DOH *clazz(const char *key, DOH *initial = 0); - DOH *function(bool reset = false); - DOH *function(const char *key, DOH *initial = 0); - DOH *variable(bool reset = false); - DOH *variable(const char *key, DOH *initial = 0); - static int IsSet(DOH *val); - -private: - DOH *getState(const char *key, bool reset = false); - Hash *globalHash; -}; - -/** - * A convenience class that wraps a code snippet used as template - * for code generation. - */ -class Template { - -public: - Template(const String *code); - Template(const String *code, const String *templateName); - Template(const Template & other); - ~Template(); - String *str(); - Template & replace(const String *pattern, const String *repl); - Template & print(DOH *doh); - Template & pretty_print(DOH *doh); - void operator=(const Template & t); - Template & trim(); - -private: - String *code; - String *templateName; -}; - -/** - * JSEmitter represents an abstraction of javascript code generators - * for different javascript engines. - **/ -class JSEmitter { - -protected: - - typedef JSEmitterState State; - - enum MarshallingMode { - Setter, - Getter, - Ctor, - Function - }; - -public: - - enum JSEngine { - JavascriptCore, - V8, - NodeJS - }; - - JSEmitter(JSEngine engine); - - virtual ~ JSEmitter(); - - /** - * Opens output files and temporary output DOHs. - */ - virtual int initialize(Node *n); - - /** - * Writes all collected code into the output file(s). - */ - virtual int dump(Node *n) = 0; - - /** - * Cleans up all open output DOHs. - */ - virtual int close() = 0; - - /** - * Switches the context for code generation. - * - * Classes, global variables and global functions may need to - * be registered in certain static tables. - * This method should be used to switch output DOHs correspondingly. - */ - virtual int switchNamespace(Node *); - - /** - * Invoked at the beginning of the classHandler. - */ - virtual int enterClass(Node *); - - /** - * Invoked at the end of the classHandler. - */ - virtual int exitClass(Node *) { - return SWIG_OK; - } - - /** - * Invoked at the beginning of the variableHandler. - */ - virtual int enterVariable(Node *); - - /** - * Invoked at the end of the variableHandler. - */ - virtual int exitVariable(Node *) { - return SWIG_OK; - } - - /** - * Invoked at the beginning of the functionHandler. - */ - virtual int enterFunction(Node *); - - /** - * Invoked at the end of the functionHandler. - */ - virtual int exitFunction(Node *) { - return SWIG_OK; - } - - /** - * Invoked by functionWrapper callback after call to Language::functionWrapper. - */ - virtual int emitWrapperFunction(Node *n); - - /** - * Invoked by nativeWrapper callback - */ - virtual int emitNativeFunction(Node *n); - - /** - * Invoked from constantWrapper after call to Language::constantWrapper. - **/ - virtual int emitConstant(Node *n); - - /** - * Registers a given code snippet for a given key name. - * - * This method is called by the fragmentDirective handler - * of the JAVASCRIPT language module. - **/ - int registerTemplate(const String *name, const String *code); - - /** - * Retrieve the code template registered for a given name. - */ - Template getTemplate(const String *name); - - State & getState(); - -protected: - - /** - * Generates code for a constructor function. - */ - virtual int emitCtor(Node *n); - - /** - * Generates code for a destructor function. - */ - virtual int emitDtor(Node *n); - - /** - * Generates code for a function. - */ - virtual int emitFunction(Node *n, bool is_member, bool is_static); - - virtual int emitFunctionDispatcher(Node *n, bool /*is_member */ ); - - /** - * Generates code for a getter function. - */ - virtual int emitGetter(Node *n, bool is_member, bool is_static); - - /** - * Generates code for a setter function. - */ - virtual int emitSetter(Node *n, bool is_member, bool is_static); - - virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) = 0; - - virtual String *emitInputTypemap(Node *n, Parm *params, Wrapper *wrapper, String *arg); - - virtual void marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult = 0, bool emitReturnVariable = true); - - virtual void emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params); - - /** - * Helper function to retrieve the first parent class node. - */ - Node *getBaseClass(Node *n); - - Parm *skipIgnoredArgs(Parm *p); - - virtual int createNamespace(String *scope); - - virtual Hash *createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled); - - virtual int emitNamespaces() = 0; - - -protected: - - JSEngine engine; - Hash *templates; - State state; - - // contains context specific data (DOHs) - // to allow generation of namespace related code - // which are switched on namespace change - Hash *namespaces; - Hash *current_namespace; - String *defaultResultName; - File *f_wrappers; -}; - -/* factory methods for concrete JSEmitters: */ - -JSEmitter *swig_javascript_create_JSCEmitter(); -JSEmitter *swig_javascript_create_V8Emitter(); -JSEmitter *swig_javascript_create_NodeJSEmitter(); - -/********************************************************************** - * JAVASCRIPT: SWIG module implementation - **********************************************************************/ - -class JAVASCRIPT:public Language { - -public: - - JAVASCRIPT():emitter(NULL) { - } - ~JAVASCRIPT() { - delete emitter; - } - - virtual int functionHandler(Node *n); - virtual int globalfunctionHandler(Node *n); - virtual int variableHandler(Node *n); - virtual int globalvariableHandler(Node *n); - virtual int staticmemberfunctionHandler(Node *n); - virtual int classHandler(Node *n); - virtual int functionWrapper(Node *n); - virtual int constantWrapper(Node *n); - virtual int nativeWrapper(Node *n); - virtual void main(int argc, char *argv[]); - virtual int top(Node *n); - - /** - * Registers all %fragments assigned to section "templates". - **/ - virtual int fragmentDirective(Node *n); - -public: - - virtual String *getNSpace() const; - -private: - - JSEmitter *emitter; -}; - -/* --------------------------------------------------------------------- - * functionWrapper() - * - * Low level code generator for functions - * --------------------------------------------------------------------- */ - -int JAVASCRIPT::functionWrapper(Node *n) { - - // note: the default implementation only prints a message - // Language::functionWrapper(n); - emitter->emitWrapperFunction(n); - - return SWIG_OK; -} - -/* --------------------------------------------------------------------- - * functionHandler() - * - * Function handler for generating wrappers for functions - * --------------------------------------------------------------------- */ -int JAVASCRIPT::functionHandler(Node *n) { - - if (GetFlag(n, "isextension") == 1) { - SetFlag(n, "ismember"); - } - - emitter->enterFunction(n); - Language::functionHandler(n); - emitter->exitFunction(n); - - return SWIG_OK; -} - -/* --------------------------------------------------------------------- - * globalfunctionHandler() - * - * Function handler for generating wrappers for functions - * --------------------------------------------------------------------- */ - -int JAVASCRIPT::globalfunctionHandler(Node *n) { - emitter->switchNamespace(n); - Language::globalfunctionHandler(n); - - return SWIG_OK; -} - -/* --------------------------------------------------------------------- - * staticmemberfunctionHandler() - * - * Function handler for generating wrappers for static member functions - * --------------------------------------------------------------------- */ - -int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { - /* - * Note: storage=static is removed by Language::staticmemberfunctionHandler. - * So, don't rely on that after here. Instead use the state variable which is - * set by JSEmitter::enterFunction(). - */ - Language::staticmemberfunctionHandler(n); - return SWIG_OK; -} - -/* --------------------------------------------------------------------- - * variableHandler() - * - * Function handler for generating wrappers for variables - * --------------------------------------------------------------------- */ - -int JAVASCRIPT::variableHandler(Node *n) { - - emitter->enterVariable(n); - Language::variableHandler(n); - emitter->exitVariable(n); - - return SWIG_OK; -} - -/* --------------------------------------------------------------------- - * globalvariableHandler() - * - * Function handler for generating wrappers for global variables - * --------------------------------------------------------------------- */ - -int JAVASCRIPT::globalvariableHandler(Node *n) { - emitter->switchNamespace(n); - Language::globalvariableHandler(n); - - return SWIG_OK; -} - -/* --------------------------------------------------------------------- - * constantHandler() - * - * Function handler for generating wrappers for constants - * --------------------------------------------------------------------- */ - -int JAVASCRIPT::constantWrapper(Node *n) { - emitter->switchNamespace(n); - - // Note: callbacks trigger this wrapper handler - // TODO: handle callback declarations - if (Equal(Getattr(n, "kind"), "function")) { - return SWIG_OK; - } - // TODO: the emitter for constants must be implemented in a cleaner way - // currently we treat it like a read-only variable - // however, there is a remaining bug with function pointer constants - // which could be fixed with a cleaner approach - emitter->emitConstant(n); - - return SWIG_OK; -} - -/* --------------------------------------------------------------------- - * nativeWrapper() - * - * Function wrapper for generating placeholders for native functions - * --------------------------------------------------------------------- */ - -int JAVASCRIPT::nativeWrapper(Node *n) { - emitter->emitNativeFunction(n); - - return SWIG_OK; -} - -/* --------------------------------------------------------------------- - * classHandler() - * - * Function handler for generating wrappers for class - * --------------------------------------------------------------------- */ - -int JAVASCRIPT::classHandler(Node *n) { - emitter->switchNamespace(n); - - emitter->enterClass(n); - Language::classHandler(n); - emitter->exitClass(n); - - return SWIG_OK; -} - -int JAVASCRIPT::fragmentDirective(Node *n) { - - // catch all fragment directives that have "templates" as location - // and register them at the emitter. - String *section = Getattr(n, "section"); - - if (Equal(section, "templates") && !ImportMode) { - emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code")); - } else { - return Language::fragmentDirective(n); - } - - return SWIG_OK; -} - -String *JAVASCRIPT::getNSpace() const { - return Language::getNSpace(); -} - -/* --------------------------------------------------------------------- - * top() - * - * Function handler for processing top node of the parse tree - * Wrapper code generation essentially starts from here - * --------------------------------------------------------------------- */ - -int JAVASCRIPT::top(Node *n) { - emitter->initialize(n); - - Language::top(n); - - emitter->dump(n); - emitter->close(); - - return SWIG_OK; -} - -static const char *usage = (char *) "\ -Javascript Options (available with -javascript)\n\ - -jsc - creates a JavascriptCore extension \n\ - -v8 - creates a v8 extension \n\ - -node - creates a node.js extension \n\ - -debug-codetemplates - generates information about the origin of code templates\n"; - - -/* --------------------------------------------------------------------- - * main() - * - * Entry point for the JAVASCRIPT module - * --------------------------------------------------------------------- */ - -void JAVASCRIPT::main(int argc, char *argv[]) { - // Set javascript subdirectory in SWIG library - SWIG_library_directory("javascript"); - - int engine = -1; - - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-v8") == 0) { - if (engine != -1) { - Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE); - Exit(EXIT_FAILURE); - } - Swig_mark_arg(i); - engine = JSEmitter::V8; - } else if (strcmp(argv[i], "-jsc") == 0) { - if (engine != -1) { - Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE); - Exit(EXIT_FAILURE); - } - Swig_mark_arg(i); - engine = JSEmitter::JavascriptCore; - } else if (strcmp(argv[i], "-node") == 0) { - if (engine != -1) { - Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE); - Exit(EXIT_FAILURE); - } - Swig_mark_arg(i); - engine = JSEmitter::NodeJS; - } else if (strcmp(argv[i], "-debug-codetemplates") == 0) { - Swig_mark_arg(i); - js_template_enable_debug = true; - } else if (strcmp(argv[i], "-help") == 0) { - fputs(usage, stdout); - return; - } - } - } - - switch (engine) { - case JSEmitter::V8: - { - emitter = swig_javascript_create_V8Emitter(); - Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0); - SWIG_library_directory("javascript/v8"); - // V8 API is C++, so output must be C++ compatible even when wrapping C code - if (!cparse_cplusplus) { - Swig_cparse_cplusplusout(1); - } - break; - } - case JSEmitter::JavascriptCore: - { - emitter = swig_javascript_create_JSCEmitter(); - Preprocessor_define("SWIG_JAVASCRIPT_JSC 1", 0); - SWIG_library_directory("javascript/jsc"); - break; - } - case JSEmitter::NodeJS: - { - emitter = swig_javascript_create_V8Emitter(); - Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0); - Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0); - SWIG_library_directory("javascript/v8"); - break; - } - default: - { - Printf(stderr, "SWIG Javascript: Unknown engine. Please specify one of '-jsc', '-v8' or '-node'.\n"); - Exit(EXIT_FAILURE); - break; - } - } - - // Add a symbol to the parser for conditional compilation - Preprocessor_define("SWIGJAVASCRIPT 1", 0); - - // Add typemap definitions - SWIG_typemap_lang("javascript"); - - // Set configuration file - SWIG_config_file("javascript.swg"); - - allow_overloading(); -} - -/* ----------------------------------------------------------------------------- - * swig_javascript() - Instantiate module - * ----------------------------------------------------------------------------- */ - -static Language *new_swig_javascript() { - return new JAVASCRIPT(); -} - -extern "C" Language *swig_javascript(void) { - return new_swig_javascript(); -} - -/********************************************************************** - * Emitter implementations - **********************************************************************/ - -/* ----------------------------------------------------------------------------- - * JSEmitter() - * ----------------------------------------------------------------------------- */ - -JSEmitter::JSEmitter(JSEmitter::JSEngine engine) -: engine(engine), templates(NewHash()), namespaces(NULL), current_namespace(NULL), defaultResultName(NewString("result")), f_wrappers(NULL) { -} - -/* ----------------------------------------------------------------------------- - * ~JSEmitter() - * ----------------------------------------------------------------------------- */ - -JSEmitter::~JSEmitter() { - Delete(templates); -} - -/* ----------------------------------------------------------------------------- - * JSEmitter::RegisterTemplate() : Registers a code template - * - * Note: this is used only by JAVASCRIPT::fragmentDirective(). - * ----------------------------------------------------------------------------- */ - -int JSEmitter::registerTemplate(const String *name, const String *code) { - if (!State::IsSet(state.globals(HAS_TEMPLATES))) { - SetFlag(state.globals(), HAS_TEMPLATES); - } - return Setattr(templates, name, code); -} - -/* ----------------------------------------------------------------------------- - * JSEmitter::getTemplate() : Provides a registered code template - * ----------------------------------------------------------------------------- */ - -Template JSEmitter::getTemplate(const String *name) { - String *templ = Getattr(templates, name); - - if (!templ) { - Printf(stderr, "Could not find template %s\n.", name); - Exit(EXIT_FAILURE); - } - - Template t(templ, name); - return t; -} - -JSEmitterState & JSEmitter::getState() { - return state; -} - -int JSEmitter::initialize(Node * /*n */ ) { - - if (namespaces != NULL) { - Delete(namespaces); - } - namespaces = NewHash(); - Hash *global_namespace = createNamespaceEntry("exports", 0, 0); - - Setattr(namespaces, "::", global_namespace); - current_namespace = global_namespace; - - f_wrappers = NewString(""); - - return SWIG_OK; -} - -/* --------------------------------------------------------------------- - * skipIgnoredArgs() - * --------------------------------------------------------------------- */ - -Parm *JSEmitter::skipIgnoredArgs(Parm *p) { - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - return p; -} - -/* ----------------------------------------------------------------------------- - * JSEmitter::getBaseClass() : the node of the base class or NULL - * - * Note: the first base class is provided. Multiple inheritance is not - * supported. - * ----------------------------------------------------------------------------- */ - -Node *JSEmitter::getBaseClass(Node *n) { - // retrieve the first base class that is not %ignored - List *baselist = Getattr(n, "bases"); - if (baselist) { - Iterator base = First(baselist); - while (base.item && GetFlag(base.item, "feature:ignore")) { - base = Next(base); - } - return base.item; - } - return NULL; -} - - /* ----------------------------------------------------------------------------- - * JSEmitter::emitWrapperFunction() : dispatches emitter functions. - * - * This allows having small sized, dedicated emitting functions. - * All state dependent branching is done here. - * ----------------------------------------------------------------------------- */ - -int JSEmitter::emitWrapperFunction(Node *n) { - int ret = SWIG_OK; - - String *kind = Getattr(n, "kind"); - - if (kind) { - - if (Equal(kind, "function") - // HACK: sneaky.ctest revealed that typedef'd (global) functions must be - // detected via the 'view' attribute. - || (Equal(kind, "variable") && Equal(Getattr(n, "view"), "globalfunctionHandler")) - ) { - bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0; - bool is_static = GetFlag(state.function(), IS_STATIC) != 0; - ret = emitFunction(n, is_member, is_static); - } else if (Cmp(kind, "variable") == 0) { - bool is_static = GetFlag(state.variable(), IS_STATIC) != 0; - // HACK: smartpointeraccessed static variables are not treated as statics - if (GetFlag(n, "allocate:smartpointeraccess")) { - is_static = false; - } - - bool is_member = GetFlag(n, "ismember") != 0; - bool is_setter = GetFlag(n, "memberset") != 0 || GetFlag(n, "varset") != 0; - bool is_getter = GetFlag(n, "memberget") != 0 || GetFlag(n, "varget") != 0; - if (is_setter) { - ret = emitSetter(n, is_member, is_static); - } else if (is_getter) { - ret = emitGetter(n, is_member, is_static); - } - - } else { - Printf(stderr, "Warning: unsupported wrapper function type\n"); - ret = SWIG_ERROR; - } - } else { - String *view = Getattr(n, "view"); - - if (Cmp(view, "constructorHandler") == 0) { - ret = emitCtor(n); - } else if (Cmp(view, "destructorHandler") == 0) { - ret = emitDtor(n); - } else { - Printf(stderr, "Warning: unsupported wrapper function type"); - ret = SWIG_ERROR; - } - } - - return ret; -} - -int JSEmitter::emitNativeFunction(Node *n) { - String *wrapname = Getattr(n, "wrap:name"); - enterFunction(n); - state.function(WRAPPER_NAME, wrapname); - exitFunction(n); - return SWIG_OK; -} - -int JSEmitter::enterClass(Node *n) { - state.clazz(RESET); - state.clazz(NAME, Getattr(n, "sym:name")); - state.clazz("nspace", current_namespace); - - // Creating a mangled name using the current namespace and the symbol name - String *mangled_name = NewString(""); - Printf(mangled_name, "%s_%s", Getattr(current_namespace, NAME_MANGLED), Getattr(n, "sym:name")); - state.clazz(NAME_MANGLED, SwigType_manglestr(mangled_name)); - Delete(mangled_name); - - state.clazz(TYPE, NewString(Getattr(n, "classtype"))); - - String *type = SwigType_manglestr(Getattr(n, "classtypeobj")); - String *classtype_mangled = NewString(""); - Printf(classtype_mangled, "p%s", type); - state.clazz(TYPE_MANGLED, classtype_mangled); - Delete(type); - - String *ctor_wrapper = NewString("_wrap_new_veto_"); - Append(ctor_wrapper, state.clazz(NAME)); - state.clazz(CTOR, ctor_wrapper); - state.clazz(CTOR_DISPATCHERS, NewString("")); - state.clazz(DTOR, NewString("0")); - - // HACK: assume that a class is abstract - // this is resolved by emitCtor (which is only called for non abstract classes) - SetFlag(state.clazz(), IS_ABSTRACT); - - return SWIG_OK; -} - -int JSEmitter::enterFunction(Node *n) { - state.function(RESET); - state.function(NAME, Getattr(n, "sym:name")); - if (Equal(Getattr(n, "storage"), "static")) { - SetFlag(state.function(), IS_STATIC); - } - return SWIG_OK; -} - -int JSEmitter::enterVariable(Node *n) { - // reset the state information for variables. - state.variable(RESET); - - // Retrieve a pure symbol name. Using 'sym:name' as a basis, as it considers %renamings. - if (Equal(Getattr(n, "view"), "memberconstantHandler")) { - // Note: this is kind of hacky/experimental - // For constants/enums 'sym:name' contains e.g., 'Foo_Hello' instead of 'Hello' - state.variable(NAME, Getattr(n, "memberconstantHandler:sym:name")); - } else { - state.variable(NAME, Swig_scopename_last(Getattr(n, "sym:name"))); - } - - if (Equal(Getattr(n, "storage"), "static")) { - SetFlag(state.variable(), IS_STATIC); - } - - if (!Language::instance()->is_assignable(n)) { - SetFlag(state.variable(), IS_IMMUTABLE); - } - // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[] - if (Equal(Getattr(n, "type"), "a().char")) { - SetFlag(state.variable(), IS_IMMUTABLE); - } - - return SWIG_OK; -} - -int JSEmitter::emitCtor(Node *n) { - - Wrapper *wrapper = NewWrapper(); - - bool is_overloaded = GetFlag(n, "sym:overloaded") != 0; - - Template t_ctor(getTemplate("js_ctor")); - - String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - if (is_overloaded) { - t_ctor = getTemplate("js_overloaded_ctor"); - Append(wrap_name, Getattr(n, "sym:overname")); - } - Setattr(n, "wrap:name", wrap_name); - // note: we can remove the is_abstract flag now, as this - // is called for non-abstract classes only. - Setattr(state.clazz(), IS_ABSTRACT, 0); - - ParmList *params = Getattr(n, "parms"); - emit_parameter_variables(params, wrapper); - emit_attach_parmmaps(params, wrapper); - // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generated an extra line of applied typemaps. - // Deleting wrapper->code here, to reset, and as it seemed to have no side effect elsewhere - Delete(wrapper->code); - wrapper->code = NewString(""); - - Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"), 0)); - - marshalInputArgs(n, params, wrapper, Ctor, true, false); - String *action = emit_action(n); - Printv(wrapper->code, action, "\n", 0); - - emitCleanupCode(n, wrapper, params); - - t_ctor.replace("$jswrapper", wrap_name) - .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) - .replace("$jslocals", wrapper->locals) - .replace("$jscode", wrapper->code) - .replace("$jsargcount", Getattr(n, ARGCOUNT)) - .pretty_print(f_wrappers); - - Template t_ctor_case(getTemplate("js_ctor_dispatch_case")); - t_ctor_case.replace("$jswrapper", wrap_name) - .replace("$jsargcount", Getattr(n, ARGCOUNT)); - Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); - - DelWrapper(wrapper); - - // create a dispatching ctor - if (is_overloaded) { - if (!Getattr(n, "sym:nextSibling")) { - String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - Template t_mainctor(getTemplate("js_ctor_dispatcher")); - t_mainctor.replace("$jswrapper", wrap_name) - .replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsdispatchcases", state.clazz(CTOR_DISPATCHERS)) - .pretty_print(f_wrappers); - state.clazz(CTOR, wrap_name); - } - } else { - state.clazz(CTOR, wrap_name); - } - - return SWIG_OK; -} - -int JSEmitter::emitDtor(Node *n) { - - String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - - SwigType *type = state.clazz(TYPE); - String *p_classtype = SwigType_add_pointer(state.clazz(TYPE)); - String *ctype = SwigType_lstr(p_classtype, ""); - String *jsfree = NewString(""); - - // (Taken from JSCore implementation.) - /* The if (Extend) block was taken from the Ruby implementation. - * The problem is that in the case of an %extend to create a destructor for a struct to coordinate automatic memory cleanup with the Javascript collector, - * the SWIG function was not being generated. More specifically: - struct MyData { - %extend { - ~MyData() { - FreeData($self); - } - } - }; - %newobject CreateData; - struct MyData* CreateData(void); - %delobject FreeData; - void FreeData(struct MyData* the_data); - - where the use case is something like: - var my_data = example.CreateData(); - my_data = null; - - This function was not being generated: - SWIGINTERN void delete_MyData(struct MyData *self){ - FreeData(self); - } - - I don't understand fully why it wasn't being generated. It just seems to happen in the Lua generator. - There is a comment about staticmemberfunctionHandler having an inconsistency and I tracked down dome of the SWIGINTERN void delete_* - code to that function in the Language base class. - The Ruby implementation seems to have an explicit check for if(Extend) and explicitly generates the code, so that's what I'm doing here. - The Ruby implementation does other stuff which I omit. - */ - if (Extend) { - String *wrap = Getattr(n, "wrap:code"); - if (wrap) { - Printv(f_wrappers, wrap, NIL); - } - } - // HACK: this is only for the v8 emitter. maybe set an attribute wrap:action of node - // TODO: generate dtors more similar to other wrappers - // EW: I think this is wrong. delete should only be used when new was used to create. If malloc was used, free needs to be used. - if (SwigType_isarray(type)) { - Printf(jsfree, "delete [] (%s)", ctype); - } else { - Printf(jsfree, "delete (%s)", ctype); - } - - String *destructor_action = Getattr(n, "wrap:action"); - // Adapted from the JSCore implementation. - /* The next challenge is to generate the correct finalize function for JavaScriptCore to call. - Originally, it would use this fragment from javascriptcode.swg - %fragment ("JS_destructordefn", "templates") - %{ - void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) - { - SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); - if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject); - free(t); - } - %} - - But for the above example case of %extend to define a destructor on a struct, we need to override the system to not call - free ((${type}*)t->swigCObject); - and substitute it with what the user has provided. - To solve this, I created a variation fragment called JS_destructoroverridedefn: - SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); - if(t && t->swigCMemOwn) { - ${type}* arg1 = (${type}*)t->swigCObject; - ${destructor_action} - } - free(t); - - Based on what I saw in the Lua and Ruby modules, I use Getattr(n, "wrap:action") - to decide if the user has a preferred destructor action. - Based on that, I decide which fragment to use. - And in the case of the custom action, I substitute that action in. - I noticed that destructor_action has the form - delete_MyData(arg1); - The explicit arg1 is a little funny, so I structured the fragment to create a temporary variable called arg1 to make the generation easier. - This might suggest this solution misunderstands a more complex case. - - Also, there is a problem where destructor_action is always true for me, even when not requesting %extend as above. - So this code doesn't actually quite work as I expect. The end result is that the code still works because - destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is weird. - I think there is a deeper underlying SWIG issue because I don't think it should be char*. However, it doesn't really matter for free. - - Maybe the fix for the destructor_action always true problem is that this is supposed to be embedded in the if(Extend) block above. - But I don't fully understand the conditions of any of these things, and since it works for the moment, I don't want to break more stuff. - */ - if (destructor_action) { - Template t_dtor = getTemplate("js_dtoroverride"); - state.clazz(DTOR, wrap_name); - t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) - .replace("$jswrapper", wrap_name) - .replace("$jsfree", jsfree) - .replace("$jstype", ctype); - - t_dtor.replace("${destructor_action}", destructor_action); - Wrapper_pretty_print(t_dtor.str(), f_wrappers); - } else { - Template t_dtor = getTemplate("js_dtor"); - state.clazz(DTOR, wrap_name); - t_dtor.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jswrapper", wrap_name) - .replace("$jsfree", jsfree) - .replace("$jstype", ctype) - .pretty_print(f_wrappers); - } - - Delete(p_classtype); - Delete(ctype); - Delete(jsfree); - - return SWIG_OK; -} - -int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { - Wrapper *wrapper = NewWrapper(); - Template t_getter(getTemplate("js_getter")); - - // prepare wrapper name - String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - Setattr(n, "wrap:name", wrap_name); - state.variable(GETTER, wrap_name); - - // prepare local variables - ParmList *params = Getattr(n, "parms"); - emit_parameter_variables(params, wrapper); - emit_attach_parmmaps(params, wrapper); - - // prepare code part - String *action = emit_action(n); - marshalInputArgs(n, params, wrapper, Getter, is_member, is_static); - marshalOutput(n, params, wrapper, action); - - emitCleanupCode(n, wrapper, params); - - t_getter.replace("$jswrapper", wrap_name) - .replace("$jslocals", wrapper->locals) - .replace("$jscode", wrapper->code) - .pretty_print(f_wrappers); - - DelWrapper(wrapper); - - return SWIG_OK; -} - -int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { - - // skip variables that are immutable - if (State::IsSet(state.variable(IS_IMMUTABLE))) { - return SWIG_OK; - } - - Wrapper *wrapper = NewWrapper(); - - Template t_setter(getTemplate("js_setter")); - - // prepare wrapper name - String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - Setattr(n, "wrap:name", wrap_name); - state.variable(SETTER, wrap_name); - - // prepare local variables - ParmList *params = Getattr(n, "parms"); - emit_parameter_variables(params, wrapper); - emit_attach_parmmaps(params, wrapper); - - // prepare code part - String *action = emit_action(n); - marshalInputArgs(n, params, wrapper, Setter, is_member, is_static); - Append(wrapper->code, action); - - emitCleanupCode(n, wrapper, params); - - t_setter.replace("$jswrapper", wrap_name) - .replace("$jslocals", wrapper->locals) - .replace("$jscode", wrapper->code) - .pretty_print(f_wrappers); - - DelWrapper(wrapper); - - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * JSEmitter::emitConstant() : triggers code generation for constants - * ----------------------------------------------------------------------------- */ - -int JSEmitter::emitConstant(Node *n) { - // HACK: somehow it happened under Mac OS X that before everything started - // a lot of SWIG internal constants were emitted - // This didn't happen on other platforms yet... - // we ignore those premature definitions - if (!State::IsSet(state.globals(HAS_TEMPLATES))) { - return SWIG_ERROR; - } - - Wrapper *wrapper = NewWrapper(); - SwigType *type = Getattr(n, "type"); - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - String *wname = Swig_name_wrapper(name); - String *rawval = Getattr(n, "rawval"); - String *value = rawval ? rawval : Getattr(n, "value"); - - // HACK: forcing usage of cppvalue for v8 (which turned out to fix typedef_struct.i, et. al) - if (State::IsSet(state.globals(FORCE_CPP)) && Getattr(n, "cppvalue") != NULL) { - value = Getattr(n, "cppvalue"); - } - - Template t_getter(getTemplate("js_getter")); - - // call the variable methods as a constants are - // registered in same way - enterVariable(n); - state.variable(GETTER, wname); - // TODO: why do we need this? - Setattr(n, "wrap:name", wname); - - // special treatment of member pointers - if (SwigType_type(type) == T_MPOINTER) { - // TODO: this could go into a code-template - String *mpointer_wname = NewString(""); - Printf(mpointer_wname, "_wrapConstant_%s", iname); - Setattr(n, "memberpointer:constant:wrap:name", mpointer_wname); - String *str = SwigType_str(type, mpointer_wname); - Printf(f_wrappers, "static %s = %s;\n", str, value); - Delete(str); - value = mpointer_wname; - } - - marshalOutput(n, 0, wrapper, NewString(""), value, false); - - t_getter.replace("$jswrapper", wname) - .replace("$jslocals", wrapper->locals) - .replace("$jscode", wrapper->code) - .pretty_print(f_wrappers); - - exitVariable(n); - - DelWrapper(wrapper); - - return SWIG_OK; -} - -int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { - Wrapper *wrapper = NewWrapper(); - Template t_function(getTemplate("js_function")); - - bool is_overloaded = GetFlag(n, "sym:overloaded") != 0; - - // prepare the function wrapper name - String *iname = Getattr(n, "sym:name"); - String *wrap_name = Swig_name_wrapper(iname); - if (is_overloaded) { - t_function = getTemplate("js_overloaded_function"); - Append(wrap_name, Getattr(n, "sym:overname")); - } - Setattr(n, "wrap:name", wrap_name); - state.function(WRAPPER_NAME, wrap_name); - - // prepare local variables - ParmList *params = Getattr(n, "parms"); - emit_parameter_variables(params, wrapper); - emit_attach_parmmaps(params, wrapper); - - // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generates an extra line of applied typemap. - // Deleting wrapper->code here fixes the problem, and seems to have no side effect elsewhere - Delete(wrapper->code); - wrapper->code = NewString(""); - - marshalInputArgs(n, params, wrapper, Function, is_member, is_static); - String *action = emit_action(n); - marshalOutput(n, params, wrapper, action); - emitCleanupCode(n, wrapper, params); - Replaceall(wrapper->code, "$symname", iname); - - t_function.replace("$jswrapper", wrap_name) - .replace("$jslocals", wrapper->locals) - .replace("$jscode", wrapper->code) - .replace("$jsargcount", Getattr(n, ARGCOUNT)) - .pretty_print(f_wrappers); - - - DelWrapper(wrapper); - - return SWIG_OK; -} - -int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { - Wrapper *wrapper = NewWrapper(); - - // Generate call list, go to first node - Node *sibl = n; - - while (Getattr(sibl, "sym:previousSibling")) - sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up - - do { - String *siblname = Getattr(sibl, "wrap:name"); - - if (siblname) { - // handle function overloading - Template t_dispatch_case = getTemplate("js_function_dispatch_case"); - t_dispatch_case.replace("$jswrapper", siblname) - .replace("$jsargcount", Getattr(sibl, ARGCOUNT)); - - Append(wrapper->code, t_dispatch_case.str()); - } - - } while ((sibl = Getattr(sibl, "sym:nextSibling"))); - - Template t_function(getTemplate("js_function_dispatcher")); - - // Note: this dispatcher function gets called after the last overloaded function has been created. - // At this time, n.wrap:name contains the name of the last wrapper function. - // To get a valid function name for the dispatcher function we take the last wrapper name and - // subtract the extension "sym:overname", - String *wrap_name = NewString(Getattr(n, "wrap:name")); - String *overname = Getattr(n, "sym:overname"); - - Node *methodclass = Swig_methodclass(n); - String *class_name = Getattr(methodclass, "sym:name"); - - int l1 = Len(wrap_name); - int l2 = Len(overname); - Delslice(wrap_name, l1 - l2, l1); - - String *new_string = NewStringf("%s_%s", class_name, wrap_name); - String *final_wrap_name = Swig_name_wrapper(new_string); - - Setattr(n, "wrap:name", final_wrap_name); - state.function(WRAPPER_NAME, final_wrap_name); - - - - t_function.replace("$jslocals", wrapper->locals) - .replace("$jscode", wrapper->code); - - // call this here, to replace all variables - t_function.replace("$jswrapper", final_wrap_name) - .replace("$jsname", state.function(NAME)) - .pretty_print(f_wrappers); - - // Delete the state variable - DelWrapper(wrapper); - - return SWIG_OK; -} - -String *JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg) { - // Get input typemap for current param - String *tm = Getattr(p, "tmap:in"); - SwigType *type = Getattr(p, "type"); - - if (tm != NULL) { - Replaceall(tm, "$input", arg); - Setattr(p, "emit:input", arg); - // do replacements for built-in variables - if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - Replaceall(tm, "$symname", Getattr(n, "sym:name")); - Printf(wrapper->code, "%s\n", tm); - } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(type, 0)); - } - - return tm; -} - -void JSEmitter::marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult, bool emitReturnVariable) { - SwigType *type = Getattr(n, "type"); - String *tm; - Parm *p; - - // adds a declaration for the result variable - if (emitReturnVariable) - emit_return_variable(n, type, wrapper); - // if not given, use default result identifier ('result') for output typemap - if (cresult == 0) - cresult = defaultResultName; - - tm = Swig_typemap_lookup_out("out", n, cresult, wrapper, actioncode); - bool should_own = GetFlag(n, "feature:new") != 0; - - if (tm) { - Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0))); - - if (should_own) { - Replaceall(tm, "$owner", "SWIG_POINTER_OWN"); - } else { - Replaceall(tm, "$owner", "0"); - } - Append(wrapper->code, tm); - - if (Len(tm) > 0) { - Printf(wrapper->code, "\n"); - } - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name")); - } - - if (params) { - for (p = params; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(wrapper->code, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - } - - Replaceall(wrapper->code, "$result", "jsresult"); -} - -void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) { - Parm *p; - String *tm; - - for (p = params; p;) { - if ((tm = Getattr(p, "tmap:freearg"))) { - //addThrows(n, "tmap:freearg", p); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(wrapper->code, tm, "\n", NIL); - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - if (GetFlag(n, "feature:new")) { - tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0); - if (tm != NIL) { - //addThrows(throws_hash, "newfree", n); - Printv(wrapper->code, tm, "\n", NIL); - } - } - - /* See if there is any return cleanup code */ - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printf(wrapper->code, "%s\n", tm); - Delete(tm); - } -} - -int JSEmitter::switchNamespace(Node *n) { - // HACK: somehow this gets called for member functions. - // We can safely ignore them, as members are not associated to a namespace (only their class) - if (GetFlag(n, "ismember")) { - return SWIG_OK; - } - - // if nspace is deactivated, everything goes into the global scope - if (!GetFlag(n, "feature:nspace")) { - current_namespace = Getattr(namespaces, "::"); - return SWIG_OK; - } - -// EXPERIMENTAL: we want to use Language::getNSpace() here -// However, it is not working yet. -// For namespace functions Language::getNSpace() does not give a valid result -#if 0 - JAVASCRIPT *lang = static_cast<JAVASCRIPT*>(Language::instance()); - String *_nspace = lang->getNSpace(); - if (!Equal(nspace, _nspace)) { - Printf(stdout, "##### Custom vs Language::getNSpace(): %s | %s\n", nspace, _nspace); - } -#endif - - String *nspace = Getattr(n, "sym:nspace"); - - if (nspace == NULL) { - // It seems that only classes have 'sym:nspace' set. - // We try to get the namespace from the qualified name (i.e., everything before the last '::') - nspace = Swig_scopename_prefix(Getattr(n, "name")); - } - - // If there is not even a scopename prefix then it must be global scope - if (nspace == NULL) { - current_namespace = Getattr(namespaces, "::"); - return SWIG_OK; - } - - String *scope = NewString(nspace); - // replace "." with "::" that we can use Swig_scopename_last - Replaceall(scope, ".", "::"); - - // if the scope is not yet registered - // create (parent) namespaces recursively - if (!Getattr(namespaces, scope)) { - createNamespace(scope); - } - current_namespace = Getattr(namespaces, scope); - - return SWIG_OK; -} - -int JSEmitter::createNamespace(String *scope) { - - String *parent_scope = Swig_scopename_prefix(scope); - Hash *parent_namespace; - if (parent_scope == 0) { - parent_namespace = Getattr(namespaces, "::"); - } else if (!Getattr(namespaces, parent_scope)) { - createNamespace(parent_scope); - parent_namespace = Getattr(namespaces, parent_scope); - } else { - parent_namespace = Getattr(namespaces, parent_scope); - } - assert(parent_namespace != 0); - - Hash *new_namespace = createNamespaceEntry(Char(scope), Char(Getattr(parent_namespace, "name")), Char(Getattr(parent_namespace, "name_mangled"))); - Setattr(namespaces, scope, new_namespace); - - Delete(parent_scope); - return SWIG_OK; -} - -Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent, const char *parent_mangled) { - Hash *entry = NewHash(); - String *name = NewString(_name); - Setattr(entry, NAME, Swig_scopename_last(name)); - Setattr(entry, NAME_MANGLED, Swig_name_mangle(name)); - Setattr(entry, PARENT, NewString(parent)); - Setattr(entry, PARENT_MANGLED, NewString(parent_mangled)); - - Delete(name); - return entry; -} - -/********************************************************************** - * JavascriptCore: JSEmitter implementation for JavascriptCore engine - **********************************************************************/ - -class JSCEmitter:public JSEmitter { - -public: - JSCEmitter(); - virtual ~ JSCEmitter(); - virtual int initialize(Node *n); - virtual int dump(Node *n); - virtual int close(); - -protected: - virtual int enterVariable(Node *n); - virtual int exitVariable(Node *n); - virtual int enterFunction(Node *n); - virtual int exitFunction(Node *n); - virtual int enterClass(Node *n); - virtual int exitClass(Node *n); - virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); - virtual Hash *createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled); - virtual int emitNamespaces(); - -private: - - String *NULL_STR; - String *VETO_SET; - - // output file and major code parts - File *f_wrap_cpp; - File *f_runtime; - File *f_header; - File *f_init; - -}; - -JSCEmitter::JSCEmitter() -: JSEmitter(JSEmitter::JavascriptCore), NULL_STR(NewString("NULL")), VETO_SET(NewString("JS_veto_set_variable")), f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), f_init(NULL) { -} - -JSCEmitter::~JSCEmitter() { - Delete(NULL_STR); - Delete(VETO_SET); -} - - -/* --------------------------------------------------------------------- - * marshalInputArgs() - * - * Process all of the arguments passed into the argv array - * and convert them into C/C++ function arguments using the - * supplied typemaps. - * --------------------------------------------------------------------- */ - -void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { - Parm *p; - String *tm; - - // determine an offset index, as members have an extra 'this' argument - // except: static members and ctors. - int startIdx = 0; - if (is_member && !is_static && mode != Ctor) { - startIdx = 1; - } - // store number of arguments for argument checks - int num_args = emit_num_arguments(parms) - startIdx; - String *argcount = NewString(""); - Printf(argcount, "%d", num_args); - Setattr(n, ARGCOUNT, argcount); - - // process arguments - int i = 0; - for (p = parms; p; i++) { - String *arg = NewString(""); - String *type = Getattr(p, "type"); - - // ignore varargs - if (SwigType_isvarargs(type)) - break; - - switch (mode) { - case Getter: - case Function: - if (is_member && !is_static && i == 0) { - Printv(arg, "thisObject", 0); - } else { - Printf(arg, "argv[%d]", i - startIdx); - } - break; - case Setter: - if (is_member && !is_static && i == 0) { - Printv(arg, "thisObject", 0); - } else { - Printv(arg, "value", 0); - } - break; - case Ctor: - Printf(arg, "argv[%d]", i); - break; - default: - Printf(stderr, "Illegal MarshallingMode."); - Exit(EXIT_FAILURE); - } - tm = emitInputTypemap(n, p, wrapper, arg); - Delete(arg); - if (tm) { - p = Getattr(p, "tmap:in:next"); - } else { - p = nextSibling(p); - } - } -} - -int JSCEmitter::initialize(Node *n) { - - JSEmitter::initialize(n); - - /* Get the output file name */ - String *outfile = Getattr(n, "outfile"); - - /* Initialize I/O */ - f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); - if (!f_wrap_cpp) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - - /* Initialization of members */ - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - - state.globals(CREATE_NAMESPACES, NewString("")); - state.globals(REGISTER_NAMESPACES, NewString("")); - state.globals(INITIALIZER, NewString("")); - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("begin", f_wrap_cpp); - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", f_init); - - Swig_banner(f_wrap_cpp); - - Swig_obligatory_macros(f_runtime, "JAVASCRIPT"); - - return SWIG_OK; -} - -int JSCEmitter::dump(Node *n) { - /* Get the module name */ - String *module = Getattr(n, "name"); - - Template initializer_define(getTemplate("js_initializer_define")); - initializer_define.replace("$jsname", module).pretty_print(f_header); - - SwigType_emit_type_table(f_runtime, f_wrappers); - - Printv(f_wrap_cpp, f_runtime, "\n", 0); - Printv(f_wrap_cpp, f_header, "\n", 0); - Printv(f_wrap_cpp, f_wrappers, "\n", 0); - - emitNamespaces(); - - // compose the initializer function using a template - Template initializer(getTemplate("js_initializer")); - initializer.replace("$jsname", module) - .replace("$jsregisterclasses", state.globals(INITIALIZER)) - .replace("$jscreatenamespaces", state.globals(CREATE_NAMESPACES)) - .replace("$jsregisternamespaces", state.globals(REGISTER_NAMESPACES)) - .pretty_print(f_init); - - Printv(f_wrap_cpp, f_init, 0); - - return SWIG_OK; -} - -int JSCEmitter::close() { - Delete(f_runtime); - Delete(f_header); - Delete(f_wrappers); - Delete(f_init); - Delete(namespaces); - Delete(f_wrap_cpp); - return SWIG_OK; -} - -int JSCEmitter::enterFunction(Node *n) { - - JSEmitter::enterFunction(n); - - return SWIG_OK; -} - -int JSCEmitter::exitFunction(Node *n) { - Template t_function = getTemplate("jsc_function_declaration"); - - bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0; - bool is_overloaded = GetFlag(n, "sym:overloaded") != 0; - - // handle overloaded functions - if (is_overloaded) { - if (!Getattr(n, "sym:nextSibling")) { - //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); - // create dispatcher - emitFunctionDispatcher(n, is_member); - } else { - //don't register wrappers of overloaded functions in function tables - return SWIG_OK; - } - } - - t_function.replace("$jsname", state.function(NAME)) - .replace("$jswrapper", state.function(WRAPPER_NAME)); - - if (is_member) { - if (GetFlag(state.function(), IS_STATIC)) { - t_function.pretty_print(state.clazz(STATIC_FUNCTIONS)); - } else { - t_function.pretty_print(state.clazz(MEMBER_FUNCTIONS)); - } - } else { - t_function.pretty_print(Getattr(current_namespace, "functions")); - } - - return SWIG_OK; -} - -int JSCEmitter::enterVariable(Node *n) { - JSEmitter::enterVariable(n); - state.variable(GETTER, NULL_STR); - state.variable(SETTER, VETO_SET); - return SWIG_OK; -} - -int JSCEmitter::exitVariable(Node *n) { - Template t_variable(getTemplate("jsc_variable_declaration")); - t_variable.replace("$jsname", state.variable(NAME)) - .replace("$jsgetter", state.variable(GETTER)) - .replace("$jssetter", state.variable(SETTER)); - - if (GetFlag(n, "ismember")) { - if (GetFlag(state.variable(), IS_STATIC) - || Equal(Getattr(n, "nodeType"), "enumitem")) { - t_variable.pretty_print(state.clazz(STATIC_VARIABLES)); - } else { - t_variable.pretty_print(state.clazz(MEMBER_VARIABLES)); - } - } else { - t_variable.pretty_print(Getattr(current_namespace, "values")); - } - - return SWIG_OK; -} - -int JSCEmitter::enterClass(Node *n) { - JSEmitter::enterClass(n); - state.clazz(MEMBER_VARIABLES, NewString("")); - state.clazz(MEMBER_FUNCTIONS, NewString("")); - state.clazz(STATIC_VARIABLES, NewString("")); - state.clazz(STATIC_FUNCTIONS, NewString("")); - - Template t_class_decl = getTemplate("jsc_class_declaration"); - t_class_decl.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .pretty_print(f_wrappers); - - return SWIG_OK; -} - -int JSCEmitter::exitClass(Node *n) { - Template t_class_tables(getTemplate("jsc_class_tables")); - t_class_tables.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsclassvariables", state.clazz(MEMBER_VARIABLES)) - .replace("$jsclassfunctions", state.clazz(MEMBER_FUNCTIONS)) - .replace("$jsstaticclassfunctions", state.clazz(STATIC_FUNCTIONS)) - .replace("$jsstaticclassvariables", state.clazz(STATIC_VARIABLES)) - .pretty_print(f_wrappers); - - /* adds the ctor wrappers at this position */ - // Note: this is necessary to avoid extra forward declarations. - //Append(f_wrappers, state.clazz(CTOR_WRAPPERS)); - - // for abstract classes add a vetoing ctor - if (GetFlag(state.clazz(), IS_ABSTRACT)) { - Template t_veto_ctor(getTemplate("js_veto_ctor")); - t_veto_ctor.replace("$jswrapper", state.clazz(CTOR)) - .replace("$jsname", state.clazz(NAME)) - .pretty_print(f_wrappers); - } - - /* adds a class template statement to initializer function */ - Template t_classtemplate(getTemplate("jsc_class_definition")); - - /* prepare registration of base class */ - String *jsclass_inheritance = NewString(""); - Node *base_class = getBaseClass(n); - if (base_class != NULL) { - Template t_inherit(getTemplate("jsc_class_inherit")); - t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsbaseclassmangled", SwigType_manglestr(Getattr(base_class, "name"))) - .pretty_print(jsclass_inheritance); - } else { - Template t_inherit(getTemplate("jsc_class_noinherit")); - t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .pretty_print(jsclass_inheritance); - } - - t_classtemplate.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) - .replace("$jsclass_inheritance", jsclass_inheritance) - .replace("$jsctor", state.clazz(CTOR)) - .replace("$jsdtor", state.clazz(DTOR)) - .pretty_print(state.globals(INITIALIZER)); - Delete(jsclass_inheritance); - - /* Note: this makes sure that there is a swig_type added for this class */ - SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); - - /* adds a class registration statement to initializer function */ - Template t_registerclass(getTemplate("jsc_class_registration")); - t_registerclass.replace("$jsname", state.clazz(NAME)) - .replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsnspace", Getattr(state.clazz("nspace"), NAME_MANGLED)) - .pretty_print(state.globals(INITIALIZER)); - - return SWIG_OK; -} - -Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled) { - Hash *entry = JSEmitter::createNamespaceEntry(name, parent, parent_mangled); - Setattr(entry, "functions", NewString("")); - Setattr(entry, "values", NewString("")); - return entry; -} - -int JSCEmitter::emitNamespaces() { - Iterator it; - for (it = First(namespaces); it.item; it = Next(it)) { - Hash *entry = it.item; - String *name = Getattr(entry, NAME); - String *name_mangled = Getattr(entry, NAME_MANGLED); - String *parent_mangled = Getattr(entry, PARENT_MANGLED); - String *functions = Getattr(entry, "functions"); - String *variables = Getattr(entry, "values"); - - // skip the global namespace which is given by the application - - Template namespace_definition(getTemplate("jsc_nspace_declaration")); - namespace_definition.replace("$jsglobalvariables", variables) - .replace("$jsglobalfunctions", functions) - .replace("$jsnspace", name_mangled) - .replace("$jsmangledname", name_mangled) - .pretty_print(f_wrap_cpp); - - Template t_createNamespace(getTemplate("jsc_nspace_definition")); - t_createNamespace.replace("$jsmangledname", name_mangled); - Append(state.globals(CREATE_NAMESPACES), t_createNamespace.str()); - - // Don't register 'exports' as namespace. It is return to the application. - if (!Equal("exports", name)) { - Template t_registerNamespace(getTemplate("jsc_nspace_registration")); - t_registerNamespace.replace("$jsmangledname", name_mangled) - .replace("$jsname", name) - .replace("$jsparent", parent_mangled); - Append(state.globals(REGISTER_NAMESPACES), t_registerNamespace.str()); - } - } - - return SWIG_OK; -} - -JSEmitter *swig_javascript_create_JSCEmitter() { - return new JSCEmitter(); -} - -/********************************************************************** - * V8: JSEmitter implementation for V8 engine - **********************************************************************/ - -class V8Emitter:public JSEmitter { - -public: - V8Emitter(); - - virtual ~ V8Emitter(); - virtual int initialize(Node *n); - virtual int dump(Node *n); - virtual int close(); - virtual int enterClass(Node *n); - virtual int exitClass(Node *n); - virtual int enterVariable(Node *n); - virtual int exitVariable(Node *n); - virtual int exitFunction(Node *n); - -protected: - virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); - virtual int emitNamespaces(); - -protected: - /* built-in parts */ - String *f_runtime; - String *f_header; - String *f_init; - String *f_post_init; - - /* part for class templates */ - String *f_class_templates; - - /* parts for initilizer */ - String *f_init_namespaces; - String *f_init_class_templates; - String *f_init_wrappers; - String *f_init_inheritance; - String *f_init_class_instances; - String *f_init_static_wrappers; - String *f_init_register_classes; - String *f_init_register_namespaces; - - // the output cpp file - File *f_wrap_cpp; - - String *NULL_STR; - String *VETO_SET; - String *moduleName; - -}; - -V8Emitter::V8Emitter() -: JSEmitter(JSEmitter::V8), NULL_STR(NewString("0")), VETO_SET(NewString("JS_veto_set_variable")) { -} - -V8Emitter::~V8Emitter() { - Delete(NULL_STR); - Delete(VETO_SET); -} - -int V8Emitter::initialize(Node *n) { - JSEmitter::initialize(n); - - moduleName = Getattr(n, "name"); - - // Get the output file name - String *outfile = Getattr(n, "outfile"); - f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); - if (!f_wrap_cpp) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - - f_runtime = NewString(""); - f_header = NewString(""); - f_class_templates = NewString(""); - f_init = NewString(""); - f_post_init = NewString(""); - - f_init_namespaces = NewString(""); - f_init_class_templates = NewString(""); - f_init_wrappers = NewString(""); - f_init_inheritance = NewString(""); - f_init_class_instances = NewString(""); - f_init_static_wrappers = NewString(""); - f_init_register_classes = NewString(""); - f_init_register_namespaces = NewString(""); - - // note: this is necessary for built-in generation of SWIG runtime code - Swig_register_filebyname("begin", f_wrap_cpp); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("init", f_init); - Swig_register_filebyname("post-init", f_post_init); - - state.globals(FORCE_CPP, NewString("1")); - - Swig_banner(f_wrap_cpp); - - Swig_obligatory_macros(f_runtime, "JAVASCRIPT"); - - return SWIG_OK; -} - -int V8Emitter::dump(Node *n) { - /* Get the module name */ - String *module = Getattr(n, "name"); - - Template initializer_define(getTemplate("js_initializer_define")); - initializer_define.replace("$jsname", module).pretty_print(f_header); - - SwigType_emit_type_table(f_runtime, f_wrappers); - - Printv(f_wrap_cpp, f_runtime, "\n", 0); - Printv(f_wrap_cpp, f_header, "\n", 0); - Printv(f_wrap_cpp, f_class_templates, "\n", 0); - Printv(f_wrap_cpp, f_wrappers, "\n", 0); - - emitNamespaces(); - - // compose the initializer function using a template - // filled with sub-parts - Template initializer(getTemplate("js_initializer")); - initializer.replace("$jsname", moduleName) - .replace("$jsv8nspaces", f_init_namespaces) - .replace("$jsv8classtemplates", f_init_class_templates) - .replace("$jsv8wrappers", f_init_wrappers) - .replace("$jsv8inheritance", f_init_inheritance) - .replace("$jsv8classinstances", f_init_class_instances) - .replace("$jsv8staticwrappers", f_init_static_wrappers) - .replace("$jsv8registerclasses", f_init_register_classes) - .replace("$jsv8registernspaces", f_init_register_namespaces); - Printv(f_init, initializer.str(), 0); - - Printv(f_wrap_cpp, f_init, 0); - - Printv(f_wrap_cpp, f_post_init, 0); - - return SWIG_OK; -} - -int V8Emitter::close() { - Delete(f_runtime); - Delete(f_header); - Delete(f_class_templates); - Delete(f_init_namespaces); - Delete(f_init_class_templates); - Delete(f_init_wrappers); - Delete(f_init_inheritance); - Delete(f_init_class_instances); - Delete(f_init_static_wrappers); - Delete(f_init_register_classes); - Delete(f_init_register_namespaces); - Delete(f_init); - Delete(f_post_init); - Delete(f_wrap_cpp); - return SWIG_OK; -} - -int V8Emitter::enterClass(Node *n) { - JSEmitter::enterClass(n); - - // emit declaration of a v8 class template - Template t_decl_class(getTemplate("jsv8_declare_class_template")); - t_decl_class.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .trim() - .pretty_print(f_class_templates); - - return SWIG_OK; -} - -int V8Emitter::exitClass(Node *n) { - if (GetFlag(state.clazz(), IS_ABSTRACT)) { - Template t_veto_ctor(getTemplate("js_veto_ctor")); - t_veto_ctor.replace("$jswrapper", state.clazz(CTOR)) - .replace("$jsname", state.clazz(NAME)) - .pretty_print(f_wrappers); - } - - /* Note: this makes sure that there is a swig_type added for this class */ - String *clientData = NewString(""); - Printf(clientData, "&%s_clientData", state.clazz(NAME_MANGLED)); - - /* Note: this makes sure that there is a swig_type added for this class */ - SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); - - // emit definition of v8 class template - Template t_def_class = getTemplate("jsv8_define_class_template"); - t_def_class.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.clazz(NAME)) - .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) - .replace("$jsdtor", state.clazz(DTOR)) - .trim() - .pretty_print(f_init_class_templates); - - Template t_class_instance = getTemplate("jsv8_create_class_instance"); - t_class_instance.replace("$jsname", state.clazz(NAME)) - .replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsctor", state.clazz(CTOR)) - .trim() - .pretty_print(f_init_class_instances); - - // emit inheritance setup - Node *baseClass = getBaseClass(n); - if (baseClass) { - String *base_name = Getattr(baseClass, "name"); - - Template t_inherit = getTemplate("jsv8_inherit"); - - String *base_name_mangled = SwigType_manglestr(base_name); - t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsbaseclass", base_name_mangled) - .trim() - .pretty_print(f_init_inheritance); - Delete(base_name_mangled); - } - // emit registration of class template - Template t_register = getTemplate("jsv8_register_class"); - t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.clazz(NAME)) - .replace("$jsparent", Getattr(state.clazz("nspace"), NAME_MANGLED)) - .trim() - .pretty_print(f_init_register_classes); - - return SWIG_OK; -} - -int V8Emitter::enterVariable(Node *n) { - JSEmitter::enterVariable(n); - - state.variable(GETTER, NULL_STR); - state.variable(SETTER, VETO_SET); - - return SWIG_OK; -} - -int V8Emitter::exitVariable(Node *n) { - if (GetFlag(n, "ismember")) { - if (GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem")) { - Template t_register = getTemplate("jsv8_register_static_variable"); - t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.variable(NAME)) - .replace("$jsgetter", state.variable(GETTER)) - .replace("$jssetter", state.variable(SETTER)) - .trim() - .pretty_print(f_init_static_wrappers); - } else { - Template t_register = getTemplate("jsv8_register_member_variable"); - t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.variable(NAME)) - .replace("$jsgetter", state.variable(GETTER)) - .replace("$jssetter", state.variable(SETTER)) - .trim() - .pretty_print(f_init_wrappers); - } - } else { - // Note: a global variable is treated like a static variable - // with the parent being a nspace object (instead of class object) - Template t_register = getTemplate("jsv8_register_static_variable"); - t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED)) - .replace("$jsname", state.variable(NAME)) - .replace("$jsgetter", state.variable(GETTER)) - .replace("$jssetter", state.variable(SETTER)) - .trim() - .pretty_print(f_init_wrappers); - } - - return SWIG_OK; -} - -int V8Emitter::exitFunction(Node *n) { - bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0; - - // create a dispatcher for overloaded functions - bool is_overloaded = GetFlag(n, "sym:overloaded") != 0; - if (is_overloaded) { - if (!Getattr(n, "sym:nextSibling")) { - //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); - emitFunctionDispatcher(n, is_member); - } else { - //don't register wrappers of overloaded functions in function tables - return SWIG_OK; - } - } - // register the function at the specific context - if (is_member) { - if (GetFlag(state.function(), IS_STATIC)) { - Template t_register = getTemplate("jsv8_register_static_function"); - t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.function(NAME)) - .replace("$jswrapper", state.function(WRAPPER_NAME)) - .trim() - .pretty_print(f_init_static_wrappers); - } else { - Template t_register = getTemplate("jsv8_register_member_function"); - t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.function(NAME)) - .replace("$jswrapper", state.function(WRAPPER_NAME)) - .trim() - .pretty_print(f_init_wrappers); - } - } else { - // Note: a global function is treated like a static function - // with the parent being a nspace object instead of class object - Template t_register = getTemplate("jsv8_register_static_function"); - t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED)) - .replace("$jsname", state.function(NAME)) - .replace("$jswrapper", state.function(WRAPPER_NAME)) - .trim() - .pretty_print(f_init_static_wrappers); - } - - return SWIG_OK; -} - -void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { - Parm *p; - String *tm; - - int startIdx = 0; - if (is_member && !is_static && mode != Ctor) { - startIdx = 1; - } - // store number of arguments for argument checks - int num_args = emit_num_arguments(parms) - startIdx; - String *argcount = NewString(""); - Printf(argcount, "%d", num_args); - Setattr(n, ARGCOUNT, argcount); - - int i = 0; - for (p = parms; p; i++) { - String *arg = NewString(""); - String *type = Getattr(p, "type"); - - // ignore varargs - if (SwigType_isvarargs(type)) - break; - - switch (mode) { - case Getter: - if (is_member && !is_static && i == 0) { - Printv(arg, "info.Holder()", 0); - } else { - Printf(arg, "args[%d]", i - startIdx); - } - break; - case Function: - if (is_member && !is_static && i == 0) { - Printv(arg, "args.Holder()", 0); - } else { - Printf(arg, "args[%d]", i - startIdx); - } - break; - case Setter: - if (is_member && !is_static && i == 0) { - Printv(arg, "info.Holder()", 0); - } else { - Printv(arg, "value", 0); - } - break; - case Ctor: - Printf(arg, "args[%d]", i); - break; - default: - Printf(stderr, "Illegal MarshallingMode."); - Exit(EXIT_FAILURE); - } - - tm = emitInputTypemap(n, p, wrapper, arg); - Delete(arg); - - if (tm) { - p = Getattr(p, "tmap:in:next"); - } else { - p = nextSibling(p); - } - } -} - -int V8Emitter::emitNamespaces() { - Iterator it; - for (it = First(namespaces); it.item; it = Next(it)) { - Hash *entry = it.item; - String *name = Getattr(entry, NAME); - String *name_mangled = Getattr(entry, NAME_MANGLED); - String *parent = Getattr(entry, PARENT); - String *parent_mangled = Getattr(entry, PARENT_MANGLED); - - bool do_create = true; - bool do_register = true; - - if (Equal(parent, "")) { - do_register = false; - } - // Note: 'exports' is by convention the name of the object where - // globals are stored into - if (Equal(name, "exports")) { - do_create = false; - } - - if (do_create) { - // create namespace object and register it to the parent scope - Template t_create_ns = getTemplate("jsv8_create_namespace"); - t_create_ns.replace("$jsmangledname", name_mangled) - .trim() - .pretty_print(f_init_namespaces); - } - - if (do_register) { - Template t_register_ns = getTemplate("jsv8_register_namespace"); - t_register_ns.replace("$jsmangledname", name_mangled) - .replace("$jsname", name) - .replace("$jsparent", parent_mangled) - .trim(); - - // prepend in order to achieve reversed order of registration statements - String *tmp_register_stmt = NewString(""); - t_register_ns.pretty_print(tmp_register_stmt); - Insert(f_init_register_namespaces, 0, tmp_register_stmt); - Delete(tmp_register_stmt); - } - } - - return SWIG_OK; -} - -JSEmitter *swig_javascript_create_V8Emitter() { - return new V8Emitter(); -} - -/********************************************************************** - * Helper implementations - **********************************************************************/ - -JSEmitterState::JSEmitterState() -: globalHash(NewHash()) { - // initialize sub-hashes - Setattr(globalHash, "class", NewHash()); - Setattr(globalHash, "function", NewHash()); - Setattr(globalHash, "variable", NewHash()); -} - -JSEmitterState::~JSEmitterState() { - Delete(globalHash); -} - -DOH *JSEmitterState::getState(const char *key, bool new_key) { - if (new_key) { - Hash *hash = NewHash(); - Setattr(globalHash, key, hash); - } - return Getattr(globalHash, key); -} - -DOH *JSEmitterState::globals() { - return globalHash; -} - -DOH *JSEmitterState::globals(const char *key, DOH *initial) { - if (initial != 0) { - Setattr(globalHash, key, initial); - } - return Getattr(globalHash, key); -} - -DOH *JSEmitterState::clazz(bool new_key) { - return getState("class", new_key); -} - -DOH *JSEmitterState::clazz(const char *key, DOH *initial) { - DOH *c = clazz(); - if (initial != 0) { - Setattr(c, key, initial); - } - return Getattr(c, key); -} - -DOH *JSEmitterState::function(bool new_key) { - return getState("function", new_key); -} - -DOH *JSEmitterState::function(const char *key, DOH *initial) { - DOH *f = function(); - if (initial != 0) { - Setattr(f, key, initial); - } - return Getattr(f, key); -} - -DOH *JSEmitterState::variable(bool new_key) { - return getState("variable", new_key); -} - -DOH *JSEmitterState::variable(const char *key, DOH *initial) { - DOH *v = variable(); - if (initial != 0) { - Setattr(v, key, initial); - } - return Getattr(v, key); -} - -/*static*/ -int JSEmitterState::IsSet(DOH *val) { - if (!val) { - return 0; - } else { - const char *cval = Char(val); - if (!cval) - return 0; - return (strcmp(cval, "0") != 0) ? 1 : 0; - } -} - -/* ----------------------------------------------------------------------------- - * Template::Template() : creates a Template class for given template code - * ----------------------------------------------------------------------------- */ - -Template::Template(const String *code_) { - - if (!code_) { - Printf(stdout, "Template code was null. Illegal input for template."); - Exit(EXIT_FAILURE); - } - code = NewString(code_); - templateName = NewString(""); -} - -Template::Template(const String *code_, const String *templateName_) { - - if (!code_) { - Printf(stdout, "Template code was null. Illegal input for template."); - Exit(EXIT_FAILURE); - } - - code = NewString(code_); - templateName = NewString(templateName_); -} - - -/* ----------------------------------------------------------------------------- - * Template::~Template() : cleans up of Template. - * ----------------------------------------------------------------------------- */ - -Template::~Template() { - Delete(code); - Delete(templateName); -} - -/* ----------------------------------------------------------------------------- - * String* Template::str() : retrieves the current content of the template. - * ----------------------------------------------------------------------------- */ - -String *Template::str() { - if (js_template_enable_debug) { - String *pre_code = NewString(""); - String *post_code = NewString(""); - String *debug_code = NewString(""); - Printf(pre_code, "/* begin fragment(\"%s\") */", templateName); - Printf(post_code, "/* end fragment(\"%s\") */", templateName); - Printf(debug_code, "%s\n%s\n%s\n", pre_code, code, post_code); - - Delete(code); - Delete(pre_code); - Delete(post_code); - - code = debug_code; - } - return code; -} - -Template & Template::trim() { - const char *str = Char(code); - if (str == 0) - return *this; - - int length = Len(code); - if (length == 0) - return *this; - - int idx; - for (idx = 0; idx < length; ++idx) { - if (str[idx] != ' ' && str[idx] != '\t' && str[idx] != '\r' && str[idx] != '\n') - break; - } - int start_pos = idx; - - for (idx = length - 1; idx >= start_pos; --idx) { - if (str[idx] != ' ' && str[idx] != '\t' && str[idx] != '\r' && str[idx] != '\n') - break; - } - int end_pos = idx; - - int new_length = end_pos - start_pos + 1; - char *newstr = new char[new_length + 1]; - memcpy(newstr, str + start_pos, new_length); - newstr[new_length] = 0; - - Delete(code); - code = NewString(newstr); - delete[]newstr; - - return *this; -} - -/* ----------------------------------------------------------------------------- - * Template& Template::replace(const String* pattern, const String* repl) : - * - * replaces all occurrences of a given pattern with a given replacement. - * - * - pattern: the pattern to be replaced - * - repl: the replacement string - * - returns a reference to the Template to allow chaining of methods. - * ----------------------------------------------------------------------------- */ - -Template & Template::replace(const String *pattern, const String *repl) { - Replaceall(code, pattern, repl); - return *this; -} - -Template & Template::print(DOH *doh) { - Printv(doh, str(), 0); - return *this; -} - -Template & Template::pretty_print(DOH *doh) { - Wrapper_pretty_print(str(), doh); - return *this; -} - -Template::Template(const Template & t) { - code = NewString(t.code); - templateName = NewString(t.templateName); -} - -void Template::operator=(const Template & t) { - Delete(code); - Delete(templateName); - code = NewString(t.code); - templateName = NewString(t.templateName); -} diff --git a/contrib/tools/swig/Source/Modules/lang.cxx b/contrib/tools/swig/Source/Modules/lang.cxx deleted file mode 100644 index 1e10e51d675..00000000000 --- a/contrib/tools/swig/Source/Modules/lang.cxx +++ /dev/null @@ -1,3902 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * lang.cxx - * - * Language base class functions. Default C++ handling is also implemented here. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" -#include <ctype.h> - -/* default mode settings */ -static int director_mode = 0; -static int director_protected_mode = 1; -static int all_protected_mode = 0; -static int naturalvar_mode = 0; -Language *Language::this_ = 0; - -/* Set director_protected_mode */ -void Wrapper_director_mode_set(int flag) { - director_mode = flag; -} - -void Wrapper_director_protected_mode_set(int flag) { - director_protected_mode = flag; -} - -void Wrapper_all_protected_mode_set(int flag) { - all_protected_mode = flag; -} - -void Wrapper_naturalvar_mode_set(int flag) { - naturalvar_mode = flag; -} - -extern "C" { - int Swig_director_mode() { - return director_mode; - } - int Swig_director_protected_mode() { - return director_protected_mode; - } - int Swig_all_protected_mode() { - return all_protected_mode; - } - void Language_replace_special_variables(String *method, String *tm, Parm *parm) { - Language::instance()->replaceSpecialVariables(method, tm, parm); - } -} - -/* Some status variables used during parsing */ -static int InClass = 0; /* Parsing C++ or not */ -static String *ClassName = 0; /* This is the real name of the current class */ -static String *EnumClassName = 0; /* Enum class name */ -static String *ClassPrefix = 0; /* Class prefix */ -static String *EnumClassPrefix = 0; /* Prefix for strongly typed enums (including ClassPrefix) */ -static String *NSpace = 0; /* Namespace for the nspace feature */ -static String *ClassType = 0; /* Fully qualified type name to use */ -static String *DirectorClassName = 0; /* Director name of the current class */ -int Abstract = 0; -int ImportMode = 0; -int IsVirtual = 0; -static String *AttributeFunctionGet = 0; -static String *AttributeFunctionSet = 0; -static Node *CurrentClass = 0; -int line_number = 0; -String *input_file = 0; -int SmartPointer = 0; -static Hash *classhash; - -extern int GenerateDefault; -extern int ForceExtern; -extern int AddExtern; -extern "C" { - extern int UseWrapperSuffix; -} - -/* import modes */ - -#define IMPORT_MODE 1 - -/* ---------------------------------------------------------------------- - * Dispatcher::emit_one() - * - * Dispatch a single node - * ---------------------------------------------------------------------- */ - -int Dispatcher::emit_one(Node *n) { - int ret = SWIG_OK; - - char *tag = Char(nodeType(n)); - if (!tag) { - /* Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree - node!\n"); */ - return SWIG_OK; - } - - /* Do not proceed if marked with an error */ - - if (Getattr(n, "error")) - return SWIG_OK; - - /* Look for warnings */ - String *wrn = Getattr(n, "feature:warnfilter"); - if (wrn) - Swig_warnfilter(wrn, 1); - - /* ============================================================ - * C/C++ parsing - * ============================================================ */ - - if (strcmp(tag, "extern") == 0) { - ret = externDeclaration(n); - } else if (strcmp(tag, "cdecl") == 0) { - ret = cDeclaration(n); - } else if (strcmp(tag, "enum") == 0) { - ret = enumDeclaration(n); - } else if (strcmp(tag, "enumitem") == 0) { - ret = enumvalueDeclaration(n); - } else if (strcmp(tag, "enumforward") == 0) { - ret = enumforwardDeclaration(n); - } else if (strcmp(tag, "class") == 0) { - ret = classDeclaration(n); - } else if (strcmp(tag, "classforward") == 0) { - ret = classforwardDeclaration(n); - } else if (strcmp(tag, "constructor") == 0) { - ret = constructorDeclaration(n); - } else if (strcmp(tag, "destructor") == 0) { - ret = destructorDeclaration(n); - } else if (strcmp(tag, "access") == 0) { - ret = accessDeclaration(n); - } else if (strcmp(tag, "using") == 0) { - ret = usingDeclaration(n); - } else if (strcmp(tag, "namespace") == 0) { - ret = namespaceDeclaration(n); - } else if (strcmp(tag, "template") == 0) { - ret = templateDeclaration(n); - } else if (strcmp(tag, "lambda") == 0) { - ret = lambdaDeclaration(n); - } - - /* =============================================================== - * SWIG directives - * =============================================================== */ - - else if (strcmp(tag, "top") == 0) { - ret = top(n); - } else if (strcmp(tag, "extend") == 0) { - ret = extendDirective(n); - } else if (strcmp(tag, "apply") == 0) { - ret = applyDirective(n); - } else if (strcmp(tag, "clear") == 0) { - ret = clearDirective(n); - } else if (strcmp(tag, "constant") == 0) { - ret = constantDirective(n); - } else if (strcmp(tag, "fragment") == 0) { - ret = fragmentDirective(n); - } else if (strcmp(tag, "import") == 0) { - ret = importDirective(n); - } else if (strcmp(tag, "include") == 0) { - ret = includeDirective(n); - } else if (strcmp(tag, "insert") == 0) { - ret = insertDirective(n); - } else if (strcmp(tag, "module") == 0) { - ret = moduleDirective(n); - } else if (strcmp(tag, "native") == 0) { - ret = nativeDirective(n); - } else if (strcmp(tag, "pragma") == 0) { - ret = pragmaDirective(n); - } else if (strcmp(tag, "typemap") == 0) { - ret = typemapDirective(n); - } else if (strcmp(tag, "typemapcopy") == 0) { - ret = typemapcopyDirective(n); - } else if (strcmp(tag, "typemapitem") == 0) { - ret = typemapitemDirective(n); - } else if (strcmp(tag, "types") == 0) { - ret = typesDirective(n); - } else { - Swig_error(input_file, line_number, "Unrecognized parse tree node type '%s'\n", tag); - ret = SWIG_ERROR; - } - if (wrn) - Swig_warnfilter(wrn, 0); - return ret; -} - -/* ---------------------------------------------------------------------- - * Dispatcher::emit_children() - * - * Emit all children that match the given type. type = 0 means all types. - * ---------------------------------------------------------------------- */ - -int Dispatcher::emit_children(Node *n) { - Node *c; - char *eo = Char(Getattr(n, "feature:emitonlychildren")); - for (c = firstChild(n); c; c = nextSibling(c)) { - if (eo) { - const char *tag = Char(nodeType(c)); - if (strcmp(tag, "cdecl") == 0) { - if (checkAttribute(c, "storage", "typedef")) - tag = "typedef"; - } - if (strstr(eo, tag) == 0) { - continue; - } - } - emit_one(c); - } - return SWIG_OK; -} - - -/* Stubs for dispatcher class. We don't do anything by default---up to derived class - to fill in traversal code */ - -int Dispatcher::defaultHandler(Node *) { - return SWIG_OK; -} -int Dispatcher::extendDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::applyDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::clearDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::constantDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::fragmentDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::importDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::includeDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::insertDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::moduleDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::nativeDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::pragmaDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::typemapDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::typemapitemDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::typemapcopyDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::typesDirective(Node *n) { - return defaultHandler(n); -} -int Dispatcher::cDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::externDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::enumDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::enumvalueDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::enumforwardDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::classDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::templateDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::lambdaDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::classforwardDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::constructorDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::destructorDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::accessDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::usingDeclaration(Node *n) { - return defaultHandler(n); -} -int Dispatcher::namespaceDeclaration(Node *n) { - return defaultHandler(n); -} - -/* Allocators */ -Language::Language(): -none_comparison(NewString("$arg != 0")), -director_ctor_code(NewString("")), -director_prot_ctor_code(0), -symtabs(NewHash()), -overloading(0), -multiinput(0), -cplus_runtime(0), -directors(0) { - symbolAddScope(""); // create top level/global symbol table scope - argc_template_string = NewString("argc"); - argv_template_string = NewString("argv[%d]"); - - /* Default director constructor code, passed to Swig_ConstructorToFunction */ - Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", " $director_new \n", "} else {\n", " $nondirector_new \n", "}\n", NIL); - - /* - Default director 'protected' constructor code, disabled by - default. Each language that needs it, has to define it. - */ - director_prot_ctor_code = 0; - director_multiple_inheritance = 1; - director_language = 0; - assert(!this_); - this_ = this; - - doxygenTranslator = NULL; -} - -Language::~Language() { - Delete(symtabs); - Delete(director_ctor_code); - Delete(none_comparison); - this_ = 0; -} - - /* ----------------------------------------------------------------------------- - * directorClassName() - * ----------------------------------------------------------------------------- */ - - String *Language::directorClassName(Node *n) { - String *dirclassname; - String *nspace = NewString(Getattr(n, "sym:nspace")); - const char *attrib = "director:classname"; - String *classname = getClassPrefix(); - - Replace(nspace, NSPACE_SEPARATOR, "_", DOH_REPLACE_ANY); - if (Len(nspace) > 0) - dirclassname = NewStringf("SwigDirector_%s_%s", nspace, classname); - else - dirclassname = NewStringf("SwigDirector_%s", classname); - Setattr(n, attrib, dirclassname); - - Delete(nspace); - return dirclassname; - } - -/* ---------------------------------------------------------------------- - emit_one() - ---------------------------------------------------------------------- */ - -int Language::emit_one(Node *n) { - int ret; - int oldext; - if (!n) - return SWIG_OK; - - if (GetFlag(n, "feature:ignore") - && !Getattr(n, "feature:onlychildren")) - return SWIG_OK; - - oldext = Extend; - if (Getattr(n, "feature:extend")) - Extend = 1; - - line_number = Getline(n); - input_file = Getfile(n); - - /* - symtab = Getattr(n,"symtab"); - if (symtab) { - symtab = Swig_symbol_setscope(symtab); - } - */ - ret = Dispatcher::emit_one(n); - /* - if (symtab) { - Swig_symbol_setscope(symtab); - } - */ - Extend = oldext; - return ret; -} - - -static Parm *nonvoid_parms(Parm *p) { - if (p) { - SwigType *t = Getattr(p, "type"); - if (SwigType_type(t) == T_VOID) - return 0; - } - return p; -} - -/* ----------------------------------------------------------------------------- - * cplus_value_type() - * - * Returns the alternative value type needed in C++ for class value - * types. When swig is not sure about using a plain $ltype value, - * since the class doesn't have a default constructor, or it can't be - * assigned, you will get back 'SwigValueWrapper<type >'. - * - * ----------------------------------------------------------------------------- */ - -SwigType *cplus_value_type(SwigType *t) { - return SwigType_alttype(t, 0); -} - -static Node *first_nontemplate(Node *n) { - while (n) { - if (Strcmp(nodeType(n), "template") != 0) - return n; - n = Getattr(n, "sym:nextSibling"); - } - return n; -} - - - -/* -------------------------------------------------------------------------- - * swig_pragma() - * - * Handle swig pragma directives. - * -------------------------------------------------------------------------- */ - -void swig_pragma(char *lang, char *name, char *value) { - if (strcmp(lang, "swig") == 0) { - if ((strcmp(name, "make_default") == 0) || ((strcmp(name, "makedefault") == 0))) { - GenerateDefault = 1; - } else if ((strcmp(name, "no_default") == 0) || ((strcmp(name, "nodefault") == 0))) { - Swig_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use %%nodefaultctor, %%nodefaultdtor instead.\n"); - GenerateDefault = 0; - } else if (strcmp(name, "attributefunction") == 0) { - String *nvalue = NewString(value); - char *s = strchr(Char(nvalue), ':'); - if (!s) { - Swig_error(input_file, line_number, "Bad value for attributefunction. Expected \"fmtget:fmtset\".\n"); - } else { - *s = 0; - AttributeFunctionGet = NewString(Char(nvalue)); - AttributeFunctionSet = NewString(s + 1); - } - Delete(nvalue); - } else if (strcmp(name, "noattributefunction") == 0) { - AttributeFunctionGet = 0; - AttributeFunctionSet = 0; - } - } -} - -/* -------------------------------------------------------------------------- - * Language::use_naturalvar_mode() - * - * Determine whether to use const ref typemaps instead of pointer typemaps - * for variable access. - * -------------------------------------------------------------------------- */ -int Language::use_naturalvar_mode(Node *n) const { - if (Getattr(n, "unnamed")) - return 0; - - // The naturalvar feature can be attached to either the variable name or the variable's type - // naturalvar on the variable name is more specific and overrides naturalvar on the variable's type - String *naturalvar = Getattr(n, "feature:naturalvar"); - bool explicitly_off = naturalvar && Strcmp(naturalvar, "0") == 0; - int nvar = GetFlag(n, "feature:naturalvar"); - - if (!explicitly_off && !nvar) { - /* look for feature in the class */ - SwigType *ty = Getattr(n, "type"); - SwigType *fullty = SwigType_typedef_resolve_all(ty); - if (SwigType_isclass(fullty)) { - SwigType *tys = SwigType_strip_qualifiers(fullty); - if (!CPlusPlus) { - Replaceall(tys, "struct ", ""); - Replaceall(tys, "union ", ""); - Replaceall(tys, "class ", ""); - } - Node *typenode = Swig_symbol_clookup(tys, 0); - if (typenode) { - naturalvar = Getattr(typenode, "feature:naturalvar"); - explicitly_off = naturalvar && Strcmp(naturalvar, "0") == 0; - nvar = nvar || GetFlag(typenode, "feature:naturalvar"); - } - Delete(tys); - } - Delete(fullty); - } - nvar = nvar || naturalvar_mode; - return explicitly_off ? 0 : nvar ? CWRAP_NATURAL_VAR : 0; -} - -/* ---------------------------------------------------------------------- - * Language::top() - Top of parsing tree - * ---------------------------------------------------------------------- */ - -int Language::top(Node *n) { - Node *mod = Getattr(n, "module"); - if (mod) { - Node *options = Getattr(mod, "options"); - if (options) { - if (Getattr(options, "naturalvar")) { - naturalvar_mode = 1; - } - } - } - classhash = Getattr(n, "classes"); - return emit_children(n); -} - -/* ---------------------------------------------------------------------- - * Language::extendDirective() - * ---------------------------------------------------------------------- */ - -int Language::extendDirective(Node *n) { - save_value<int> oldam(Extend, CWRAP_EXTEND); - save_value<AccessMode> oldmode(cplus_mode, PUBLIC); - emit_children(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::applyDirective() - * ---------------------------------------------------------------------- */ - -int Language::applyDirective(Node *n) { - - Parm *pattern = Getattr(n, "pattern"); - Node *c = firstChild(n); - while (c) { - Parm *apattern = Getattr(c, "pattern"); - if (ParmList_len(pattern) != ParmList_len(apattern)) { - Swig_error(input_file, line_number, "Can't apply (%s) to (%s). Number of arguments don't match.\n", ParmList_str(pattern), ParmList_str(apattern)); - } else { - if (!Swig_typemap_apply(pattern, apattern)) { - Swig_warning(WARN_TYPEMAP_APPLY_UNDEF, input_file, line_number, "Can't apply (%s). No typemaps are defined.\n", ParmList_str(pattern)); - } - } - c = nextSibling(c); - } - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::clearDirective() - * ---------------------------------------------------------------------- */ - -int Language::clearDirective(Node *n) { - Node *p; - for (p = firstChild(n); p; p = nextSibling(p)) { - ParmList *pattern = Getattr(p, "pattern"); - Swig_typemap_clear_apply(pattern); - } - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::constantDirective() - * ---------------------------------------------------------------------- */ - -int Language::constantDirective(Node *n) { - - if (CurrentClass && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - if (!GetFlag(n, "feature:allowexcept")) { - UnsetFlag(n, "feature:except"); - } - if (Getattr(n, "feature:exceptvar")) { - Setattr(n, "feature:except", Getattr(n, "feature:exceptvar")); - } - - if (!ImportMode) { - Swig_require("constantDirective", n, "name", "?value", NIL); - String *name = Getattr(n, "name"); - String *value = Getattr(n, "value"); - if (!value) { - value = Copy(name); - } else { - /* if (checkAttribute(n,"type","char")) { - value = NewString(value); - } else { - value = NewStringf("%(escape)s", value); - } - */ - Setattr(n, "rawvalue", value); - value = NewStringf("%(escape)s", value); - if (!Len(value)) - Append(value, "\\0"); - /* Printf(stdout,"'%s' = '%s'\n", name, value); */ - } - Setattr(n, "value", value); - this->constantWrapper(n); - Swig_restore(n); - return SWIG_OK; - } - return SWIG_NOWRAP; -} - -/* ---------------------------------------------------------------------- - * Language::fragmentDirective() - * ---------------------------------------------------------------------- */ - -int Language::fragmentDirective(Node *n) { - if (!(Getattr(n, "emitonly") && ImportMode)) - Swig_fragment_register(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::importDirective() - * ---------------------------------------------------------------------- */ - -int Language::importDirective(Node *n) { - int oldim = ImportMode; - ImportMode = IMPORT_MODE; - emit_children(n); - ImportMode = oldim; - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::includeDirective() - * ---------------------------------------------------------------------- */ - -int Language::includeDirective(Node *n) { - emit_children(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::insertDirective() - * ---------------------------------------------------------------------- */ - -int Language::insertDirective(Node *n) { - /* %insert directive */ - if ((!ImportMode) || Getattr(n, "generated")) { - String *code = Getattr(n, "code"); - String *section = Getattr(n, "section"); - File *f = 0; - if (!section) { /* %{ ... %} */ - f = Swig_filebyname("header"); - } else { - f = Swig_filebyname(section); - } - if (f) { - Printf(f, "%s\n", code); - } else { - Swig_error(input_file, line_number, "Unknown target '%s' for %%insert directive.\n", section); - } - return SWIG_OK; - } else { - return SWIG_NOWRAP; - } -} - -/* ---------------------------------------------------------------------- - * Language::moduleDirective() - * ---------------------------------------------------------------------- */ - -int Language::moduleDirective(Node *n) { - (void) n; - /* %module directive */ - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::nativeDirective() - * ---------------------------------------------------------------------- */ - -int Language::nativeDirective(Node *n) { - if (!ImportMode) { - return nativeWrapper(n); - } else { - return SWIG_NOWRAP; - } -} - -/* ---------------------------------------------------------------------- - * Language::pragmaDirective() - * ---------------------------------------------------------------------- */ - -int Language::pragmaDirective(Node *n) { - /* %pragma directive */ - if (!ImportMode) { - String *lan = Getattr(n, "lang"); - String *name = Getattr(n, "name"); - String *value = Getattr(n, "value"); - swig_pragma(Char(lan), Char(name), Char(value)); - /* pragma(Char(lan),Char(name),Char(value)); */ - return SWIG_OK; - } - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::typemapDirective() - * ---------------------------------------------------------------------- */ - -int Language::typemapDirective(Node *n) { - /* %typemap directive */ - String *method = Getattr(n, "method"); - String *code = Getattr(n, "code"); - Parm *kwargs = Getattr(n, "kwargs"); - Node *items = firstChild(n); - static int nameerror = 0; - - - if (code && (Strstr(code, "$source") || (Strstr(code, "$target")))) { - Swig_error(Getfile(n), Getline(n), "Obsolete typemap feature ($source/$target).\n"); - if (!nameerror) { - Swig_error(Getfile(n), Getline(n), "The use of $source and $target in a typemap declaration is no longer supported.\n\ -For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\ -$source by $input and $target by $1. For typemaps related to return values (out,\n\ -argout,ret,except), replace $source by $1 and $target by $result. See the file\n\ -Doc/Manual/Typemaps.html for complete details.\n"); - nameerror = 1; - } - } - - if (Strcmp(method, "except") == 0) { - Swig_warning(WARN_DEPRECATED_EXCEPT_TM, Getfile(n), Getline(n), "%%typemap(except) is deprecated. Use the %%exception directive.\n"); - } - - if (Strcmp(method, "in") == 0) { - Hash *k; - k = kwargs; - while (k) { - if (checkAttribute(k, "name", "numinputs")) { - if (!multiinput && (GetInt(k, "value") > 1)) { - Swig_error(Getfile(n), Getline(n), "Multiple-input typemaps (numinputs > 1) not supported by this target language module.\n"); - return SWIG_ERROR; - } - break; - } - k = nextSibling(k); - } - if (!k) { - k = NewHash(); - Setattr(k, "name", "numinputs"); - Setattr(k, "value", "1"); - set_nextSibling(k, kwargs); - Setattr(n, "kwargs", k); - kwargs = k; - } - } - - if (Strcmp(method, "ignore") == 0) { - Swig_warning(WARN_DEPRECATED_IGNORE_TM, Getfile(n), Getline(n), "%%typemap(ignore) has been replaced by %%typemap(in,numinputs=0).\n"); - - Clear(method); - Append(method, "in"); - Hash *k = NewHash(); - Setattr(k, "name", "numinputs"); - Setattr(k, "value", "0"); - set_nextSibling(k, kwargs); - Setattr(n, "kwargs", k); - kwargs = k; - } - - /* Replace $descriptor() macros */ - - if (code) { - Setfile(code, Getfile(n)); - Setline(code, Getline(n)); - Swig_cparse_replace_descriptor(code); - } - - while (items) { - Parm *pattern = Getattr(items, "pattern"); - Parm *parms = Getattr(items, "parms"); - - if (code) { - Swig_typemap_register(method, pattern, code, parms, kwargs); - } else { - Swig_typemap_clear(method, pattern); - } - items = nextSibling(items); - } - return SWIG_OK; - -} - -/* ---------------------------------------------------------------------- - * Language::typemapcopyDirective() - * ---------------------------------------------------------------------- */ - -int Language::typemapcopyDirective(Node *n) { - String *method = Getattr(n, "method"); - Parm *pattern = Getattr(n, "pattern"); - Node *items = firstChild(n); - int nsrc = 0; - nsrc = ParmList_len(pattern); - while (items) { - ParmList *npattern = Getattr(items, "pattern"); - if (nsrc != ParmList_len(npattern)) { - Swig_error(input_file, line_number, "Can't copy typemap. Number of types differ.\n"); - } else { - if (Swig_typemap_copy(method, pattern, npattern) < 0) { - Swig_error(input_file, line_number, "Can't copy typemap (%s) %s = %s\n", method, ParmList_str(pattern), ParmList_str(npattern)); - } - } - items = nextSibling(items); - } - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::typesDirective() - * ---------------------------------------------------------------------- */ - -int Language::typesDirective(Node *n) { - Parm *parms = Getattr(n, "parms"); - String *convcode = Getattr(n, "convcode"); /* optional user supplied conversion code for custom casting */ - while (parms) { - SwigType *t = Getattr(parms, "type"); - String *v = Getattr(parms, "value"); - if (!v) { - SwigType_remember(t); - } else { - if (SwigType_issimple(t)) { - SwigType_inherit(t, v, 0, convcode); - } - } - parms = nextSibling(parms); - } - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::cDeclaration() - * ---------------------------------------------------------------------- */ - -int Language::cDeclaration(Node *n) { - - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - SwigType *decl = Getattr(n, "decl"); - String *storage = Getattr(n, "storage"); - Node *over; - File *f_header = 0; - SwigType *ty, *fullty; - - if (Getattr(n, "feature:onlychildren")) { - if (GetFlag(n, "feature:ignore")) { - return SWIG_NOWRAP; - } else { - // Found an unignored templated method that has an empty template instantiation (%template()) - // Ignore it unless it has been %rename'd - if (Strncmp(symname, "__dummy_", 8) == 0 && Cmp(storage, "typedef") != 0) { - SetFlag(n, "feature:ignore"); - Swig_warning(WARN_LANG_TEMPLATE_METHOD_IGNORE, input_file, line_number, - "%%template() contains no name. Template method ignored: %s\n", Swig_name_decl(n)); - return SWIG_NOWRAP; - } - } - } - - /* discards nodes following the access control rules */ - if (cplus_mode != PUBLIC || !is_public(n)) { - /* except for friends, they are not affected by access control */ - int isfriend = Cmp(storage, "friend") == 0; - if (!isfriend) { - /* Check what the director needs. If the method is pure virtual, it is always needed. - * Also wrap non-virtual protected members if asked for (allprotected mode). */ - if (!(directorsEnabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || isNonVirtualProtectedAccess(n)))) { - return SWIG_NOWRAP; - } - // Prevent wrapping protected overloaded director methods more than once - - // This bit of code is only needed due to the cDeclaration call in classHandler() - String *wrapname = NewStringf("nonpublic_%s%s", symname, Getattr(n, "sym:overname")); - if (Getattr(CurrentClass, wrapname)) { - Delete(wrapname); - return SWIG_NOWRAP; - } - SetFlag(CurrentClass, wrapname); - Delete(wrapname); - } - } - - if (Cmp(storage, "typedef") == 0) { - Swig_save("cDeclaration", n, "type", NIL); - SwigType *t = Copy(type); - if (t) { - SwigType_push(t, decl); - Setattr(n, "type", t); - typedefHandler(n); - } - Swig_restore(n); - return SWIG_OK; - } - - /* If in import mode, we proceed no further */ - if (ImportMode) - return SWIG_NOWRAP; - - /* If we're in extend mode and there is code, replace the $descriptor macros */ - if (Extend) { - String *code = Getattr(n, "code"); - if (code) { - Setfile(code, Getfile(n)); - Setline(code, Getline(n)); - Swig_cparse_replace_descriptor(code); - } - } - - /* Overloaded symbol check */ - over = Swig_symbol_isoverloaded(n); - if (!overloading) { - if (over) - over = first_nontemplate(over); - if (over && (over != n)) { - Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored. %s\n", Swig_name_decl(n)); - Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over), "Previous declaration is %s\n", Swig_name_decl(over)); - return SWIG_NOWRAP; - } - } - - if (!validIdentifier(symname)) { - Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap '%s' unless renamed to a valid identifier.\n", SwigType_namestr(symname)); - return SWIG_NOWRAP; - } - - ty = NewString(type); - SwigType_push(ty, decl); - fullty = SwigType_typedef_resolve_all(ty); - if (SwigType_isfunction(fullty)) { - if (!SwigType_isfunction(ty)) { - Delete(ty); - ty = fullty; - fullty = 0; - ParmList *parms = SwigType_function_parms(ty, n); - Setattr(n, "parms", parms); - } - /* Transform the node into a 'function' node and emit */ - if (!CurrentClass) { - f_header = Swig_filebyname("header"); - - if (AddExtern) { - if (f_header) { - if (Swig_storage_isextern(n) || (ForceExtern && !storage)) { - /* we don't need the 'extern' part in the C/C++ declaration, - and it produces some problems when namespace and SUN - Studio is used. - - Printf(f_header,"extern %s", SwigType_str(ty,name)); - - In fact generating extern declarations is quite error prone and is - no longer the default. Getting it right seems impossible with namespaces - and default arguments and when a method is declared with the various Windows - calling conventions - SWIG doesn't understand Windows (non standard) calling - conventions in the first place, so can't regenerate them. - */ - String *str = SwigType_str(ty, name); - Printf(f_header, "%s", str); - Delete(str); - { - DOH *t = Getattr(n, "throws"); - if (t) { - Printf(f_header, " throw("); - while (t) { - Printf(f_header, "%s", Getattr(t, "type")); - t = nextSibling(t); - if (t) - Printf(f_header, ","); - } - Printf(f_header, ")"); - } - } - Printf(f_header, ";\n"); - } else if (Swig_storage_isexternc(n)) { - /* here 'extern "C"' is needed */ - String *str = SwigType_str(ty, name); - Printf(f_header, "extern \"C\" %s;\n", str); - Delete(str); - } - } - } - } - /* This needs to check qualifiers */ - if (SwigType_isqualifier(ty)) { - SwigType *qual = SwigType_pop(ty); - Setattr(n, "qualifier", qual); - Delete(qual); - } - Delete(SwigType_pop_function(ty)); - DohIncref(type); - Setattr(n, "type", ty); - - functionHandler(n); - - Setattr(n, "type", type); - Delete(ty); - Delete(type); - return SWIG_OK; - } else { - /* Some kind of variable declaration */ - String *declaration = Copy(decl); - Delattr(n, "decl"); - if (!CurrentClass) { - if (Swig_storage_isextern(n) || ForceExtern) { - if (AddExtern) { - f_header = Swig_filebyname("header"); - if (f_header) { - String *str = SwigType_str(ty, name); - Printf(f_header, "%s %s;\n", Getattr(n, "storage"), str); - Delete(str); - } - } - } - } - if (!SwigType_ismutable(ty)) { - SetFlag(n, "feature:immutable"); - } - /* If an array and elements are const, then read-only */ - if (SwigType_isarray(ty)) { - SwigType *tya = SwigType_array_type(ty); - if (SwigType_isconst(tya)) { - SetFlag(n, "feature:immutable"); - } - Delete(tya); - } - DohIncref(type); - Setattr(n, "type", ty); - variableHandler(n); - Setattr(n, "type", type); - Setattr(n, "decl", declaration); - Delete(ty); - Delete(type); - Delete(fullty); - return SWIG_OK; - } -} - -/* ---------------------------------------------------------------------- - * Language::functionHandler() - * ---------------------------------------------------------------------- */ - -int Language::functionHandler(Node *n) { - String *storage = Getattr(n, "storage"); - int isfriend = CurrentClass && Cmp(storage, "friend") == 0; - int isstatic = CurrentClass && Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess")); - Parm *p = Getattr(n, "parms"); - if (GetFlag(n, "feature:del")) { - /* the method acts like a delete operator, ie, we need to disown the parameter */ - if (CurrentClass && !isstatic && !isfriend) { - SetFlag(n, "feature:self:disown"); - } else { - if (p) - SetFlag(p, "wrap:disown"); - } - } - if (!CurrentClass) { - globalfunctionHandler(n); - } else { - if (isstatic) { - staticmemberfunctionHandler(n); - } else if (isfriend) { - int oldInClass = InClass; - InClass = 0; - globalfunctionHandler(n); - InClass = oldInClass; - } else { - // This is a member function, set a flag so the documentation type is correct - SetFlag(n, "memberfunction"); - Node *explicit_n = 0; - if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) { - bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0)); - if (virtual_but_not_pure_virtual) { - // Add additional wrapper which makes an explicit call to the virtual method (ie not a virtual call) - explicit_n = Copy(n); - String *new_symname = Copy(Getattr(n, "sym:name")); - String *suffix = Getattr(parentNode(n), "sym:name"); - Printv(new_symname, "SwigExplicit", suffix, NIL); - Setattr(explicit_n, "sym:name", new_symname); - Delattr(explicit_n, "storage"); - Delattr(explicit_n, "override"); - Delattr(explicit_n, "hides"); - SetFlag(explicit_n, "explicitcall"); - Setattr(n, "explicitcallnode", explicit_n); - } - } - - memberfunctionHandler(n); - - if (explicit_n) { - memberfunctionHandler(explicit_n); - Delattr(explicit_n, "explicitcall"); - Delete(explicit_n); - } - } - } - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::globalfunctionHandler() - * ---------------------------------------------------------------------- */ - -int Language::globalfunctionHandler(Node *n) { - - Swig_require("globalfunctionHandler", n, "name", "sym:name", "type", "?parms", NIL); - - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - ParmList *parms = Getattr(n, "parms"); - - /* Check for callback mode */ - String *cb = GetFlagAttr(n, "feature:callback"); - if (cb) { - String *cbname = Getattr(n, "feature:callback:name"); - if (!cbname) { - cbname = NewStringf(cb, symname); - Setattr(n, "feature:callback:name", cbname); - } - - callbackfunctionHandler(n); - if (Cmp(cbname, symname) == 0) { - Delete(cbname); - Swig_restore(n); - return SWIG_NOWRAP; - } - Delete(cbname); - } - Setattr(n, "parms", nonvoid_parms(parms)); - - String *extendname = Getattr(n, "extendname"); - String *call = Swig_cfunction_call(extendname ? extendname : name, parms); - String *cres = Swig_cresult(type, Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); - Delete(cres); - Delete(call); - functionWrapper(n); - - Swig_restore(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::callbackfunctionHandler() - * ---------------------------------------------------------------------- */ - -int Language::callbackfunctionHandler(Node *n) { - Swig_require("callbackfunctionHandler", n, "name", "*sym:name", "*type", "?value", NIL); - String *type = Getattr(n, "type"); - String *name = Getattr(n, "name"); - String *parms = Getattr(n, "parms"); - String *cbname = Getattr(n, "feature:callback:name"); - String *calltype = NewStringf("(%s (*)(%s))(%s)", SwigType_str(type, 0), ParmList_str(parms), SwigType_namestr(name)); - SwigType *cbty = Copy(type); - SwigType_add_function(cbty, parms); - SwigType_add_pointer(cbty); - - Setattr(n, "sym:name", cbname); - Setattr(n, "type", cbty); - Setattr(n, "value", calltype); - - Node *ns = symbolLookup(cbname); - if (!ns) - constantWrapper(n); - - Delete(cbty); - - Swig_restore(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::memberfunctionHandler() - * ---------------------------------------------------------------------- */ - -int Language::memberfunctionHandler(Node *n) { - - Swig_require("memberfunctionHandler", n, "*name", "*sym:name", "*type", "?parms", "?value", NIL); - - String *storage = Getattr(n, "storage"); - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - String *value = Getattr(n, "value"); - ParmList *parms = Getattr(n, "parms"); - String *cb = GetFlagAttr(n, "feature:callback"); - - if (Cmp(storage, "virtual") == 0) { - if (Cmp(value, "0") == 0) { - IsVirtual = PURE_VIRTUAL; - } else { - IsVirtual = PLAIN_VIRTUAL; - } - } else { - IsVirtual = 0; - } - if (cb) { - Node *cbn = NewHash(); - String *cbname = Getattr(n, "feature:callback:name"); - if (!cbname) { - cbname = NewStringf(cb, symname); - } - - SwigType *cbty = Copy(type); - SwigType_add_function(cbty, parms); - SwigType_add_memberpointer(cbty, ClassName); - String *cbvalue = NewStringf("&%s::%s", ClassName, name); - Setattr(cbn, "sym:name", cbname); - Setattr(cbn, "type", cbty); - Setattr(cbn, "value", cbvalue); - Setattr(cbn, "name", name); - Setfile(cbn, Getfile(n)); - Setline(cbn, Getline(n)); - - memberconstantHandler(cbn); - Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname)); - - Delete(cb); - Delete(cbn); - Delete(cbvalue); - Delete(cbty); - Delete(cbname); - if (Cmp(cbname, symname) == 0) { - Swig_restore(n); - return SWIG_NOWRAP; - } - } - - String *fname = Swig_name_member(NSpace, ClassPrefix, symname); - if (Extend && SmartPointer) { - if (!Getattr(n, "extendsmartclassname")) { - Setattr(n, "extendsmartclassname", Getattr(CurrentClass, "allocate:smartpointerpointeeclassname")); - } - } - // Set up the type for the cast to this class for use when wrapping const director (virtual) methods. - // Note: protected director methods or when allprotected mode turned on. - String *director_type = 0; - if (!is_public(n) && (is_member_director(CurrentClass, n) || GetFlag(n, "explicitcall") || isNonVirtualProtectedAccess(n))) { - director_type = Copy(DirectorClassName); - String *qualifier = Getattr(n, "qualifier"); - if (qualifier) - SwigType_push(director_type, qualifier); - SwigType_add_pointer(director_type); - } - - int DirectorExtraCall = 0; - if (directorsEnabled() && is_member_director(CurrentClass, n) && !SmartPointer) - if (extraDirectorProtectedCPPMethodsRequired()) - DirectorExtraCall = CWRAP_DIRECTOR_TWO_CALLS; - - if (GetFlag(n, "explicitcall")) - DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL; - - int extendmember = GetFlag(n, "isextendmember") ? Extend : 0; - int flags = Getattr(n, "template") ? extendmember | SmartPointer : Extend | SmartPointer | DirectorExtraCall; - Swig_MethodToFunction(n, NSpace, ClassType, flags, director_type, is_member_director(CurrentClass, n)); - Setattr(n, "sym:name", fname); - /* Explicitly save low-level and high-level documentation names */ - Setattr(n, "doc:low:name", fname); - Setattr(n, "doc:high:name", symname); - - functionWrapper(n); - - Delete(director_type); - Delete(fname); - Swig_restore(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::staticmemberfunctionHandler() - * ---------------------------------------------------------------------- */ - -int Language::staticmemberfunctionHandler(Node *n) { - - Swig_require("staticmemberfunctionHandler", n, "*name", "*sym:name", "*type", NIL); - Swig_save("staticmemberfunctionHandler", n, "storage", NIL); - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - ParmList *parms = Getattr(n, "parms"); - String *cb = GetFlagAttr(n, "feature:callback"); - String *cname, *mrename; - - if (!Extend) { - Node *sb = Getattr(n, "cplus:staticbase"); - String *sname = Getattr(sb, "name"); - if (isNonVirtualProtectedAccess(n)) - cname = NewStringf("%s::%s", DirectorClassName, name); - else - cname = NewStringf("%s::%s", sname, name); - } else { - String *mname = Swig_name_mangle(ClassName); - cname = Swig_name_member(NSpace, mname, name); - Delete(mname); - } - mrename = Swig_name_member(NSpace, ClassPrefix, symname); - - if (Extend) { - String *code = Getattr(n, "code"); - String *defaultargs = Getattr(n, "defaultargs"); - String *mangled = Swig_name_mangle(mrename); - Delete(mrename); - mrename = mangled; - - if (code) { - // See Swig_MethodToFunction() for the explanation of this code. - if (Getattr(n, "sym:overloaded")) { - Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname")); - } else if (UseWrapperSuffix) { - Append(cname, "__SWIG"); - } - - if (!defaultargs) { - /* Hmmm. An added static member. We have to create a little wrapper for this */ - String *mangled_cname = Swig_name_mangle(cname); - Swig_add_extension_code(n, mangled_cname, parms, type, code, CPlusPlus, 0); - Setattr(n, "extendname", mangled_cname); - Delete(mangled_cname); - } - } - } - - Setattr(n, "name", cname); - Setattr(n, "sym:name", mrename); - /* Explicitly save low-level and high-level documentation names */ - Setattr(n, "doc:low:name", mrename); - Setattr(n, "doc:high:name", symname); - - if (cb) { - String *cbname = NewStringf(cb, symname); - Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname)); - Setattr(n, "feature:callback:staticname", name); - } - Delattr(n, "storage"); - - globalfunctionHandler(n); - - Delete(cname); - Delete(mrename); - Swig_restore(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::variableHandler() - * ---------------------------------------------------------------------- */ - -int Language::variableHandler(Node *n) { - - /* If not a smart-pointer access or added method. We clear - feature:except. There is no way C++ or C would throw - an exception merely for accessing a member data. - - Caveat: Some compilers seem to route attribute access through - methods which can generate exceptions. The feature:allowexcept - allows this. Also, the feature:exceptvar can be used to match - only variables. - */ - if (!(Extend | SmartPointer)) { - if (!GetFlag(n, "feature:allowexcept")) { - UnsetFlag(n, "feature:except"); - } - if (Getattr(n, "feature:exceptvar")) { - Setattr(n, "feature:except", Getattr(n, "feature:exceptvar")); - } - } - - if (!CurrentClass) { - globalvariableHandler(n); - } else { - Swig_save("variableHandler", n, "feature:immutable", NIL); - if (SmartPointer) { - /* If a smart-pointer and it's a constant access, we have to set immutable */ - if (!Getattr(CurrentClass, "allocate:smartpointermutable")) { - SetFlag(n, "feature:immutable"); - } - } - if (Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"))) { - staticmembervariableHandler(n); - } else { - membervariableHandler(n); - } - Swig_restore(n); - } - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::globalvariableHandler() - * ---------------------------------------------------------------------- */ - -int Language::globalvariableHandler(Node *n) { - variableWrapper(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::membervariableHandler() - * ---------------------------------------------------------------------- */ - -int Language::membervariableHandler(Node *n) { - - Swig_require("membervariableHandler", n, "*name", "*sym:name", "*type", NIL); - Swig_save("membervariableHandler", n, "parms", NIL); - - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - - if (!AttributeFunctionGet) { - String *mname = Swig_name_member(0, ClassPrefix, symname); - String *mrename_get = Swig_name_get(NSpace, mname); - String *mrename_set = Swig_name_set(NSpace, mname); - Delete(mname); - - /* Create a function to set the value of the variable */ - - int assignable = is_assignable(n); - - if (SmartPointer) { - if (!Getattr(CurrentClass, "allocate:smartpointermutable")) { - assignable = 0; - } - } - - if (assignable) { - int make_set_wrapper = 1; - String *tm = 0; - String *target = 0; - if (!Extend) { - if (SmartPointer) { - if (Swig_storage_isstatic(n)) { - Node *sn = Getattr(n, "cplus:staticbase"); - String *base = Getattr(sn, "name"); - target = NewStringf("%s::%s", base, name); - } else { - String *pname = Swig_cparm_name(0, 0); - target = NewStringf("(*%s)->%s", pname, name); - Delete(pname); - } - } else { - String *pname = isNonVirtualProtectedAccess(n) ? NewString("darg") : Swig_cparm_name(0, 0); - target = NewStringf("%s->%s", pname, name); - Delete(pname); - } - - // This is an input type typemap lookup and so it should not use Node n - // otherwise qualification is done on the parameter name for the setter function - Parm *nin = NewParm(type, name, n); - tm = Swig_typemap_lookup("memberin", nin, target, 0); - Delete(nin); - } - - int flags = Extend | SmartPointer | use_naturalvar_mode(n); - if (isNonVirtualProtectedAccess(n)) - flags = flags | CWRAP_ALL_PROTECTED_ACCESS; - - Swig_MembersetToFunction(n, ClassType, flags); - Setattr(n, "memberset", "1"); - if (!Extend) { - /* Check for a member in typemap here */ - - if (!tm) { - if (SwigType_isarray(type)) { - Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0)); - make_set_wrapper = 0; - } - } else { - String *pname0 = Swig_cparm_name(0, 0); - String *pname1 = Swig_cparm_name(0, 1); - Replace(tm, "$input", pname1, DOH_REPLACE_ANY); - Replace(tm, "$self", pname0, DOH_REPLACE_ANY); - Setattr(n, "wrap:action", tm); - Delete(tm); - Delete(pname0); - Delete(pname1); - } - Delete(target); - } - if (make_set_wrapper) { - Setattr(n, "sym:name", mrename_set); - functionWrapper(n); - } else { - SetFlag(n, "feature:immutable"); - } - /* Restore parameters */ - Setattr(n, "type", type); - Setattr(n, "name", name); - Setattr(n, "sym:name", symname); - Delattr(n, "memberset"); - - /* Delete all attached typemaps and typemap attributes */ - Iterator ki; - for (ki = First(n); ki.key; ki = Next(ki)) { - if (Strncmp(ki.key, "tmap:", 5) == 0) - Delattr(n, ki.key); - } - } - /* Emit get function */ - { - int flags = Extend | SmartPointer | use_naturalvar_mode(n); - if (isNonVirtualProtectedAccess(n)) - flags = flags | CWRAP_ALL_PROTECTED_ACCESS; - Swig_MembergetToFunction(n, ClassType, flags); - Setattr(n, "sym:name", mrename_get); - Setattr(n, "memberget", "1"); - functionWrapper(n); - Delattr(n, "memberget"); - } - Delete(mrename_get); - Delete(mrename_set); - - } else { - - /* This code is used to support the attributefunction directive - where member variables are converted automagically to - accessor functions */ - -#if 0 - Parm *p; - String *gname; - SwigType *vty; - p = NewParm(type, 0, n); - gname = NewStringf(AttributeFunctionGet, symname); - if (!Extend) { - ActionFunc = Copy(Swig_cmemberget_call(name, type)); - cpp_member_func(Char(gname), Char(gname), type, 0); - Delete(ActionFunc); - } else { - String *cname = Swig_name_get(NSpace, name); - cpp_member_func(Char(cname), Char(gname), type, 0); - Delete(cname); - } - Delete(gname); - if (!GetFlag(n, "feature:immutable")) { - gname = NewStringf(AttributeFunctionSet, symname); - vty = NewString("void"); - if (!Extend) { - ActionFunc = Copy(Swig_cmemberset_call(name, type)); - cpp_member_func(Char(gname), Char(gname), vty, p); - Delete(ActionFunc); - } else { - String *cname = Swig_name_set(NSpace, name); - cpp_member_func(Char(cname), Char(gname), vty, p); - Delete(cname); - } - Delete(gname); - } - ActionFunc = 0; -#endif - } - Swig_restore(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::staticmembervariableHandler() - * ---------------------------------------------------------------------- */ - -int Language::staticmembervariableHandler(Node *n) { - Swig_require("staticmembervariableHandler", n, "*name", "*sym:name", "*type", "?value", NIL); - String *value = Getattr(n, "value"); - String *classname = !SmartPointer ? (isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerpointeeclassname"); - - if (!value || !Getattr(n, "hasconsttype")) { - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - String *cname, *mrename; - - /* Create the variable name */ - mrename = Swig_name_member(0, ClassPrefix, symname); - cname = NewStringf("%s::%s", classname, name); - - Setattr(n, "sym:name", mrename); - Setattr(n, "name", cname); - - /* Wrap as an ordinary global variable */ - variableWrapper(n); - - Delete(mrename); - Delete(cname); - } else { - - /* This is a C++ static member declaration with an initializer and it's const. - Certain C++ compilers optimize this out so that there is no linkage to a - memory address. Example: - - class Foo { - public: - static const int x = 3; - }; - - Some discussion of this in section 9.4 of the C++ draft standard. - - Also, we have to manage the case: - - class Foo { - public: - %extend { - static const int x = 3; - } - }; - - in which there's no actual Foo::x variable to refer to. In this case, - the best we can do is to wrap the given value verbatim. - */ - - - String *name = Getattr(n, "name"); - String *cname = NewStringf("%s::%s", classname, name); - if (Extend) { - /* the variable is a synthesized one. - There's nothing we can do; we just keep the given value */ - } else { - /* we refer to the value as Foo::x */ - String *value = SwigType_namestr(cname); - Setattr(n, "value", value); - } - - SwigType *t1 = SwigType_typedef_resolve_all(Getattr(n, "type")); - SwigType *t2 = SwigType_strip_qualifiers(t1); - Setattr(n, "type", t2); - Delete(t1); - Delete(t2); - SetFlag(n, "wrappedasconstant"); - memberconstantHandler(n); - Delete(cname); - } - - Swig_restore(n); - return SWIG_OK; -} - - -/* ---------------------------------------------------------------------- - * Language::externDeclaration() - * ---------------------------------------------------------------------- */ - -int Language::externDeclaration(Node *n) { - return emit_children(n); -} - -/* ---------------------------------------------------------------------- - * Language::enumDeclaration() - * ---------------------------------------------------------------------- */ - -int Language::enumDeclaration(Node *n) { - if (CurrentClass && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - String *oldNSpace = NSpace; - NSpace = Getattr(n, "sym:nspace"); - - String *oldEnumClassPrefix = EnumClassPrefix; - if (GetFlag(n, "scopedenum")) { - assert(Getattr(n, "sym:name")); - assert(Getattr(n, "name")); - EnumClassPrefix = ClassPrefix ? NewStringf("%s_", ClassPrefix) : NewString(""); - Printv(EnumClassPrefix, Getattr(n, "sym:name"), NIL); - EnumClassName = Copy(Getattr(n, "name")); - } - if (!ImportMode) { - emit_children(n); - } - - if (GetFlag(n, "scopedenum")) { - Delete(EnumClassName); - EnumClassName = 0; - Delete(EnumClassPrefix); - EnumClassPrefix = oldEnumClassPrefix; - } - NSpace = oldNSpace; - - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::enumvalueDeclaration() - * ---------------------------------------------------------------------- */ - -int Language::enumvalueDeclaration(Node *n) { - if (CurrentClass && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - Swig_require("enumvalueDeclaration", n, "*name", "*sym:name", "?value", NIL); - String *value = Getattr(n, "value"); - String *name = Getattr(n, "name"); - String *tmpValue; - - if (value) - tmpValue = NewString(value); - else - tmpValue = NewString(name); - Setattr(n, "value", tmpValue); - - Node *parent = parentNode(n); - if (GetFlag(parent, "scopedenum")) { - String *symname = Swig_name_member(0, Getattr(parent, "sym:name"), Getattr(n, "sym:name")); - Setattr(n, "sym:name", symname); - Delete(symname); - } - - if (!CurrentClass || !cparse_cplusplus) { - Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */ - constantWrapper(n); - } else { - memberconstantHandler(n); - } - - Delete(tmpValue); - Swig_restore(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::enumforwardDeclaration() - * ---------------------------------------------------------------------- */ - -int Language::enumforwardDeclaration(Node *n) { - (void) n; - if (GetFlag(n, "enumMissing")) - enumDeclaration(n); // Generate an empty enum in target language - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Language::memberconstantHandler() - * ----------------------------------------------------------------------------- */ - -int Language::memberconstantHandler(Node *n) { - - Swig_require("memberconstantHandler", n, "*name", "*sym:name", "value", NIL); - - if (!GetFlag(n, "feature:allowexcept")) { - UnsetFlag(n, "feature:except"); - } - if (Getattr(n, "feature:exceptvar")) { - Setattr(n, "feature:except", Getattr(n, "feature:exceptvar")); - } - - String *enumvalue_symname = Getattr(n, "enumvalueDeclaration:sym:name"); // Only set if a strongly typed enum - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - String *value = Getattr(n, "value"); - - String *mrename = Swig_name_member(0, EnumClassPrefix, enumvalue_symname ? enumvalue_symname : symname); - Setattr(n, "sym:name", mrename); - - String *new_name = 0; - if (Extend) - new_name = Copy(value); - else if (EnumClassName) - new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : EnumClassName, name); - else - new_name = NewStringf("%s::%s", isNonVirtualProtectedAccess(n) ? DirectorClassName : ClassName, name); - Setattr(n, "name", new_name); - - constantWrapper(n); - Delete(mrename); - Delete(new_name); - Swig_restore(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::typedefHandler() - * ---------------------------------------------------------------------- */ - -int Language::typedefHandler(Node *n) { - /* since this is a recurring issue, we are going to remember the - typedef pointer, if already it is not a pointer or reference, as - in - - typedef void NT; - int func(NT *p); - - see director_basic.i for example. - */ - SwigType *name = Getattr(n, "name"); - SwigType *decl = Getattr(n, "decl"); - if (!SwigType_ispointer(decl) && !SwigType_isreference(decl)) { - SwigType *pname = Copy(name); - SwigType_add_pointer(pname); - SwigType_remember(pname); - Delete(pname); - } - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classDirectorMethod() - * ---------------------------------------------------------------------- */ - -int Language::classDirectorMethod(Node *n, Node *parent, String *super) { - (void) n; - (void) parent; - (void) super; - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classDirectorConstructor() - * ---------------------------------------------------------------------- */ - -int Language::classDirectorConstructor(Node *n) { - (void) n; - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classDirectorDefaultConstructor() - * ---------------------------------------------------------------------- */ - -int Language::classDirectorDefaultConstructor(Node *n) { - (void) n; - return SWIG_OK; -} - -static String *vtable_method_id(Node *n) { - String *nodeType = Getattr(n, "nodeType"); - int is_destructor = (Cmp(nodeType, "destructor") == 0); - if (is_destructor) - return 0; - String *name = Getattr(n, "name"); - String *decl = Getattr(n, "decl"); - String *local_decl = SwigType_typedef_resolve_all(decl); - String *tmp = SwigType_pop_function(local_decl); - Delete(local_decl); - local_decl = tmp; - String *method_id = NewStringf("%s|%s", name, local_decl); - Delete(local_decl); - return method_id; -} - -/* ---------------------------------------------------------------------- - * Language::unrollOneVirtualMethod() - * ---------------------------------------------------------------------- */ - -void Language::unrollOneVirtualMethod(String *classname, Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) { - if (!checkAttribute(n, "storage", "virtual")) - return; - if (GetFlag(n, "final")) - return; - - String *nodeType = Getattr(n, "nodeType"); - - /* we need to add methods(cdecl) and destructor (to check for throw decl) */ - int is_destructor = (Cmp(nodeType, "destructor") == 0); - if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) { - String *decl = Getattr(n, "decl"); - /* extra check for function type and proper access */ - if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(n)) || need_nonpublic_member(n))) { - String *name = Getattr(n, "name"); - String *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(n); - /* Make sure that the new method overwrites the existing: */ - int len = Len(vm); - const int DO_NOT_REPLACE = -1; - int replace = DO_NOT_REPLACE; - for (int i = 0; i < len; i++) { - Node *item = Getitem(vm, i); - String *check_vmid = Getattr(item, "vmid"); - - if (Strcmp(method_id, check_vmid) == 0) { - replace = i; - break; - } - } - /* filling a new method item */ - String *fqdname = NewStringf("%s::%s", classname, name); - Hash *item = NewHash(); - Setattr(item, "fqdname", fqdname); - Node *m = Copy(n); - - /* Store the complete return type - needed for non-simple return types (pointers, references etc.) */ - SwigType *ty = NewString(Getattr(m, "type")); - SwigType_push(ty, decl); - if (SwigType_isqualifier(ty)) { - Delete(SwigType_pop(ty)); - } - Delete(SwigType_pop_function(ty)); - Setattr(m, "returntype", ty); - - String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name); - /* apply the features of the original method found in the base class */ - Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m); - Setattr(item, "methodNode", m); - Setattr(item, "vmid", method_id); - if (replace == DO_NOT_REPLACE) - Append(vm, item); - else - Setitem(vm, replace, item); - Setattr(n, "directorNode", m); - - Delete(mname); - } - if (is_destructor) { - virtual_destructor = 1; - } - } -} - -/* ---------------------------------------------------------------------- - * Language::unrollVirtualMethods() - * ---------------------------------------------------------------------- */ -int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) { - bool first_base = false; - // recurse through all base classes to build the vtable - List *bl = Getattr(n, "bases"); - if (bl) { - Iterator bi; - for (bi = First(bl); bi.item; bi = Next(bi)) { - if (first_base && !director_multiple_inheritance) - break; - unrollVirtualMethods(bi.item, parent, vm, virtual_destructor); - first_base = true; - } - } - - // recurse through all protected base classes to build the vtable, as needed - bl = Getattr(n, "protectedbases"); - if (bl) { - Iterator bi; - for (bi = First(bl); bi.item; bi = Next(bi)) { - if (first_base && !director_multiple_inheritance) - break; - unrollVirtualMethods(bi.item, parent, vm, virtual_destructor, 1); - first_base = true; - } - } - - // find the methods that need directors - String *classname = Getattr(n, "name"); - for (Node *ni = firstChild(n); ni; ni = nextSibling(ni)) { - /* we only need to check the virtual members */ - if (Equal(nodeType(ni), "using")) { - for (Node *nn = firstChild(ni); nn; nn = Getattr(nn, "sym:nextSibling")) { - unrollOneVirtualMethod(classname, nn, parent, vm, virtual_destructor, protectedbase); - } - } - unrollOneVirtualMethod(classname, ni, parent, vm, virtual_destructor, protectedbase); - } - - /* - We delete all the nodirector methods. This prevents the - generation of 'empty' director classes. - - Done once we've collated all the virtual methods into vm. - */ - if (n == parent) { - int len = Len(vm); - for (int i = 0; i < len; i++) { - Node *item = Getitem(vm, i); - Node *m = Getattr(item, "methodNode"); - /* retrieve the director features */ - int mdir = GetFlag(m, "feature:director"); - int mndir = GetFlag(m, "feature:nodirector"); - /* 'nodirector' has precedence over 'director' */ - int dir = (mdir || mndir) ? (mdir && !mndir) : 1; - /* check if the method was found only in a base class */ - Node *p = Getattr(m, "parentNode"); - if (p != n) { - Node *c = Copy(m); - Setattr(c, "parentNode", n); - int cdir = GetFlag(c, "feature:director"); - int cndir = GetFlag(c, "feature:nodirector"); - dir = (cdir || cndir) ? (cdir && !cndir) : dir; - Delete(c); - } - if (dir) { - /* be sure the 'nodirector' feature is disabled */ - if (mndir) - Delattr(m, "feature:nodirector"); - } else { - /* or just delete from the vm, since is not a director method */ - Delitem(vm, i); - len--; - i--; - } - } - } - - return SWIG_OK; -} - - -/* ---------------------------------------------------------------------- - * Language::classDirectorDisown() - * ---------------------------------------------------------------------- */ - -int Language::classDirectorDisown(Node *n) { - Node *disown = NewHash(); - String *mrename; - String *symname = Getattr(n, "sym:name"); - mrename = Swig_name_disown(NSpace, symname); - String *type = NewString(ClassType); - String *name = NewString("self"); - SwigType_add_pointer(type); - Parm *p = NewParm(type, name, n); - Delete(name); - Delete(type); - type = NewString("void"); - String *action = NewString(""); - Printv(action, "{\n", "Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);\n", "if (director) director->swig_disown();\n", "}\n", NULL); - Setfile(disown, Getfile(n)); - Setline(disown, Getline(n)); - Setattr(disown, "wrap:action", action); - Setattr(disown, "name", mrename); - Setattr(disown, "sym:name", mrename); - Setattr(disown, "type", type); - Setattr(disown, "parms", p); - Delete(action); - Delete(mrename); - Delete(type); - Delete(p); - - functionWrapper(disown); - Delete(disown); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classDirectorConstructors() - * ---------------------------------------------------------------------- */ - -int Language::classDirectorConstructors(Node *n) { - Node *ni; - String *nodeType; - Node *parent = Swig_methodclass(n); - int default_ctor = Getattr(parent, "allocate:default_constructor") ? 1 : 0; - int protected_ctor = 0; - int constructor = 0; - - /* emit constructors */ - for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) { - nodeType = Getattr(ni, "nodeType"); - if (Cmp(nodeType, "constructor") == 0) { - if (GetFlag(ni, "feature:ignore")) - continue; - - Parm *parms = Getattr(ni, "parms"); - if (is_public(ni)) { - /* emit public constructor */ - classDirectorConstructor(ni); - constructor = 1; - if (default_ctor) - default_ctor = !ParmList_numrequired(parms); - } else { - /* emit protected constructor if needed */ - if (need_nonpublic_ctor(ni)) { - classDirectorConstructor(ni); - constructor = 1; - protected_ctor = 1; - if (default_ctor) - default_ctor = !ParmList_numrequired(parms); - } - } - } - } - /* emit default constructor if needed */ - if (!constructor) { - if (!default_ctor) { - /* we get here because the class has no public, protected or - default constructor, therefore, the director class can't be - created, ie, is kind of abstract. */ - Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n), "Director class '%s' can't be constructed\n", SwigType_namestr(Getattr(n, "name"))); - return SWIG_OK; - } - classDirectorDefaultConstructor(n); - default_ctor = 1; - } - /* this is just to support old java behavior, ie, the default - constructor is always emitted, even when protected, and not - needed, since there is a public constructor already defined. - - (scottm) This code is needed here to make the director_abstract + - test generate compilable code (Example2 in director_abstract.i). - - (mmatus) This is very strange, since swig compiled with gcc3.2.3 - doesn't need it here.... - */ - if (!default_ctor && !protected_ctor) { - if (Getattr(parent, "allocate:default_base_constructor")) { - classDirectorDefaultConstructor(n); - } - } - - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classDirectorMethods() - * ---------------------------------------------------------------------- */ - -int Language::classDirectorMethods(Node *n) { - Node *vtable = Getattr(n, "vtable"); - - int len = Len(vtable); - for (int i = 0; i < len; i++) { - Node *item = Getitem(vtable, i); - String *method = Getattr(item, "methodNode"); - String *fqdname = Getattr(item, "fqdname"); - if (GetFlag(method, "feature:nodirector") || GetFlag(method, "final")) - continue; - - String *wrn = Getattr(method, "feature:warnfilter"); - if (wrn) - Swig_warnfilter(wrn, 1); - - String *type = Getattr(method, "nodeType"); - if (!Cmp(type, "destructor")) { - classDirectorDestructor(method); - } else { - Swig_require("classDirectorMethods", method, "*type", NIL); - assert(Getattr(method, "returntype")); - Setattr(method, "type", Getattr(method, "returntype")); - if (classDirectorMethod(method, n, fqdname) == SWIG_OK) - SetFlag(item, "director"); - Swig_restore(method); - } - if (wrn) - Swig_warnfilter(wrn, 0); - } - - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classDirectorInit() - * ---------------------------------------------------------------------- */ - -int Language::classDirectorInit(Node *n) { - (void) n; - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classDirectorDestructor() - * ---------------------------------------------------------------------- */ - -int Language::classDirectorDestructor(Node *n) { - /* - Always emit the virtual destructor in the declaration and in the - compilation unit. Been explicit here can't make any damage, and - can solve some nasty C++ compiler problems. - */ - File *f_directors = Swig_filebyname("director"); - File *f_directors_h = Swig_filebyname("director_h"); - if (Getattr(n, "throw")) { - Printf(f_directors_h, " virtual ~%s() throw();\n", DirectorClassName); - Printf(f_directors, "%s::~%s() throw() {\n}\n\n", DirectorClassName, DirectorClassName); - } else { - Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName); - Printf(f_directors, "%s::~%s() {\n}\n\n", DirectorClassName, DirectorClassName); - } - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classDirectorEnd() - * ---------------------------------------------------------------------- */ - -int Language::classDirectorEnd(Node *n) { - (void) n; - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classDirector() - * ---------------------------------------------------------------------- */ - -int Language::classDirector(Node *n) { - Node *module = Getattr(n, "module"); - String *classtype = Getattr(n, "classtype"); - Hash *directormap = 0; - if (module) { - directormap = Getattr(module, "wrap:directormap"); - if (directormap == 0) { - directormap = NewHash(); - Setattr(module, "wrap:directormap", directormap); - } - } - List *vtable = NewList(); - int virtual_destructor = 0; - unrollVirtualMethods(n, n, vtable, virtual_destructor); - - // Emit all the using base::member statements for non virtual members (allprotected mode) - Node *ni; - String *using_protected_members_code = NewString(""); - for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) { - Node *nodeType = Getattr(ni, "nodeType"); - if (Cmp(nodeType, "destructor") == 0 && GetFlag(ni, "final")) { - String *classtype = Getattr(n, "classtype"); - SWIG_WARN_NODE_BEGIN(ni); - Swig_warning(WARN_LANG_DIRECTOR_FINAL, input_file, line_number, "Destructor %s is final, %s cannot be a director class.\n", Swig_name_decl(ni), classtype); - SWIG_WARN_NODE_END(ni); - SetFlag(n, "feature:nodirector"); - Delete(vtable); - Delete(using_protected_members_code); - return SWIG_OK; - } - bool cdeclaration = (Cmp(nodeType, "cdecl") == 0); - if (cdeclaration && !GetFlag(ni, "feature:ignore")) { - if (isNonVirtualProtectedAccess(ni)) { - Node *overloaded = Getattr(ni, "sym:overloaded"); - // emit the using base::member statement (but only once if the method is overloaded) - if (!overloaded || (overloaded && (overloaded == ni))) - Printf(using_protected_members_code, " using %s::%s;\n", SwigType_namestr(ClassName), Getattr(ni, "name")); - } - } - } - - if (virtual_destructor || Len(vtable) > 0) { - if (!virtual_destructor) { - String *classtype = Getattr(n, "classtype"); - Swig_warning(WARN_LANG_DIRECTOR_VDESTRUCT, input_file, line_number, "Director base class %s has no virtual destructor.\n", classtype); - } - - Setattr(n, "vtable", vtable); - if (directormap != 0) { - Setattr(directormap, classtype, n); - } - classDirectorInit(n); - classDirectorConstructors(n); - classDirectorMethods(n); - - File *f_directors_h = Swig_filebyname("director_h"); - Printv(f_directors_h, using_protected_members_code, NIL); - - classDirectorEnd(n); - } - Delete(vtable); - Delete(using_protected_members_code); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classDeclaration() - * ---------------------------------------------------------------------- */ - -static void addCopyConstructor(Node *n) { - Node *cn = NewHash(); - set_nodeType(cn, "constructor"); - Setattr(cn, "access", "public"); - Setfile(cn, Getfile(n)); - Setline(cn, Getline(n)); - - String *cname = Getattr(n, "name"); - SwigType *type = Copy(cname); - String *name = Swig_scopename_last(cname); - String *cc = NewStringf("r.q(const).%s", type); - String *decl = NewStringf("f(%s).", cc); - String *oldname = Getattr(n, "sym:name"); - - if (Getattr(n, "allocate:has_constructor")) { - // to work properly with '%rename Class', we must look - // for any other constructor in the class, which has not been - // renamed, and use its name as oldname. - Node *c; - for (c = firstChild(n); c; c = nextSibling(c)) { - const char *tag = Char(nodeType(c)); - if (strcmp(tag, "constructor") == 0) { - String *cname = Getattr(c, "name"); - String *csname = Getattr(c, "sym:name"); - String *clast = Swig_scopename_last(cname); - if (Equal(csname, clast)) { - oldname = csname; - break; - } - } - } - } - - String *symname = Swig_name_make(cn, cname, name, decl, oldname); - if (Strcmp(symname, "$ignore") != 0) { - Parm *p = NewParm(cc, "other", n); - - Setattr(cn, "name", name); - Setattr(cn, "sym:name", symname); - SetFlag(cn, "feature:new"); - Setattr(cn, "decl", decl); - Setattr(cn, "parentNode", n); - Setattr(cn, "parms", p); - Setattr(cn, "copy_constructor", "1"); - - Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab")); - Node *on = Swig_symbol_add(symname, cn); - Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn); - Swig_symbol_setscope(oldscope); - - if (on == cn) { - Node *access = NewHash(); - set_nodeType(access, "access"); - Setattr(access, "kind", "public"); - appendChild(n, access); - appendChild(n, cn); - Setattr(n, "has_copy_constructor", "1"); - Setattr(n, "copy_constructor_decl", decl); - Setattr(n, "allocate:copy_constructor", "1"); - Delete(access); - } - } - Delete(cn); - Delete(name); - Delete(decl); - Delete(symname); -} - -static void addDefaultConstructor(Node *n) { - Node *cn = NewHash(); - set_nodeType(cn, "constructor"); - Setattr(cn, "access", "public"); - Setfile(cn, Getfile(n)); - Setline(cn, Getline(n)); - - String *cname = Getattr(n, "name"); - String *name = Swig_scopename_last(cname); - String *decl = NewString("f()."); - String *oldname = Getattr(n, "sym:name"); - String *symname = Swig_name_make(cn, cname, name, decl, oldname); - if (Strcmp(symname, "$ignore") != 0) { - Setattr(cn, "name", name); - Setattr(cn, "sym:name", symname); - SetFlag(cn, "feature:new"); - Setattr(cn, "decl", decl); - Setattr(cn, "parentNode", n); - Setattr(cn, "default_constructor", "1"); - Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab")); - Node *on = Swig_symbol_add(symname, cn); - Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn); - Swig_symbol_setscope(oldscope); - - if (on == cn) { - Node *access = NewHash(); - set_nodeType(access, "access"); - Setattr(access, "kind", "public"); - appendChild(n, access); - appendChild(n, cn); - Setattr(n, "has_default_constructor", "1"); - Setattr(n, "allocate:default_constructor", "1"); - Delete(access); - } - } - Delete(cn); - Delete(name); - Delete(decl); - Delete(symname); -} - -static void addDestructor(Node *n) { - Node *cn = NewHash(); - set_nodeType(cn, "destructor"); - Setattr(cn, "access", "public"); - Setfile(cn, Getfile(n)); - Setline(cn, Getline(n)); - - String *cname = Getattr(n, "name"); - String *name = Swig_scopename_last(cname); - Insert(name, 0, "~"); - String *decl = NewString("f()."); - String *symname = Swig_name_make(cn, cname, name, decl, 0); - if (Strcmp(symname, "$ignore") != 0) { - String *possible_nonstandard_symname = NewStringf("~%s", Getattr(n, "sym:name")); - - Setattr(cn, "name", name); - Setattr(cn, "sym:name", symname); - Setattr(cn, "decl", "f()."); - Setattr(cn, "parentNode", n); - - Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab")); - Node *nonstandard_destructor = Equal(possible_nonstandard_symname, symname) ? 0 : Swig_symbol_clookup(possible_nonstandard_symname, 0); - Node *on = Swig_symbol_add(symname, cn); - Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn); - Swig_symbol_setscope(oldscope); - - if (on == cn) { - // SWIG accepts a non-standard named destructor in %extend that uses a typedef for the destructor name - // For example: typedef struct X {} XX; %extend X { ~XX() {...} } - // Don't add another destructor if a nonstandard one has been declared - if (!nonstandard_destructor) { - Node *access = NewHash(); - set_nodeType(access, "access"); - Setattr(access, "kind", "public"); - appendChild(n, access); - appendChild(n, cn); - Setattr(n, "has_destructor", "1"); - Setattr(n, "allocate:destructor", "1"); - Delete(access); - } - } - Delete(possible_nonstandard_symname); - } - Delete(cn); - Delete(name); - Delete(decl); - Delete(symname); -} - -int Language::classDeclaration(Node *n) { - String *ochildren = Getattr(n, "feature:onlychildren"); - if (ochildren) { - Setattr(n, "feature:emitonlychildren", ochildren); - emit_children(n); - Delattr(n, "feature:emitonlychildren"); - SetFlag(n, "feature:ignore"); - return SWIG_NOWRAP; - } - - // save class local variables for nested classes support - int oldInClass = InClass; - String *oldClassType = ClassType; - String *oldClassPrefix = ClassPrefix; - String *oldEnumClassPrefix = EnumClassPrefix; - String *oldClassName = ClassName; - String *oldDirectorClassName = DirectorClassName; - String *oldNSpace = NSpace; - Node *oldCurrentClass = CurrentClass; - int dir = 0; - - String *kind = Getattr(n, "kind"); - String *name = Getattr(n, "name"); - String *tdname = Getattr(n, "tdname"); - String *unnamed = Getattr(n, "unnamed"); - String *symname = Getattr(n, "sym:name"); - - int strip = CPlusPlus ? 1 : unnamed && tdname; - - if (cplus_mode != PUBLIC) - return SWIG_NOWRAP; - if (!name) { - Swig_warning(WARN_LANG_CLASS_UNNAMED, input_file, line_number, "Can't generate wrappers for unnamed struct/class.\n"); - return SWIG_NOWRAP; - } - - /* Check symbol name for template. If not renamed. Issue a warning */ - if (!validIdentifier(symname)) { - Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap class %s unless renamed to a valid identifier.\n", SwigType_namestr(symname)); - return SWIG_NOWRAP; - } - AccessMode oldAccessMode = cplus_mode; - Node *outerClass = Getattr(n, "nested:outer"); - if (outerClass && oldAccessMode != PUBLIC) - return SWIG_NOWRAP; - ClassName = Copy(name); - ClassPrefix = Copy(symname); - if (Cmp(kind, "class") == 0) { - cplus_mode = PRIVATE; - } else { - cplus_mode = PUBLIC; - } - for (; outerClass; outerClass = Getattr(outerClass, "nested:outer")) { - Push(ClassPrefix, "_"); - Push(ClassPrefix, Getattr(outerClass, "sym:name")); - } - EnumClassPrefix = Copy(ClassPrefix); - if (strip) { - ClassType = Copy(name); - } else { - ClassType = NewStringf("%s %s", kind, name); - } - Setattr(n, "classtypeobj", Copy(ClassType)); - Setattr(n, "classtype", SwigType_namestr(ClassType)); - - InClass = 1; - CurrentClass = n; - NSpace = Getattr(n, "sym:nspace"); - int oldAbstract = Abstract; - - /* Call classHandler() here */ - if (!ImportMode) { - if (directorsEnabled()) { - int ndir = GetFlag(n, "feature:director"); - int nndir = GetFlag(n, "feature:nodirector"); - /* 'nodirector' has precedence over 'director' */ - dir = (ndir || nndir) ? (ndir && !nndir) : 0; - } - int abstract = !dir && abstractClassTest(n); - int odefault = (GenerateDefault && !GetFlag(n, "feature:nodefault")); - - /* default constructor */ - if (!abstract && !GetFlag(n, "feature:nodefaultctor") && odefault) { - if (!Getattr(n, "has_constructor") && !Getattr(n, "allocate:has_constructor") && (Getattr(n, "allocate:default_constructor"))) { - addDefaultConstructor(n); - } - } - /* copy constructor */ - if (CPlusPlus && !abstract && GetFlag(n, "feature:copyctor")) { - if (!Getattr(n, "has_copy_constructor") && !Getattr(n, "allocate:has_copy_constructor") - && (Getattr(n, "allocate:copy_constructor")) - && (!GetFlag(n, "feature:ignore"))) { - addCopyConstructor(n); - } - } - /* default destructor */ - if (!GetFlag(n, "feature:nodefaultdtor") && odefault) { - if (!Getattr(n, "has_destructor") && (!Getattr(n, "allocate:has_destructor")) - && (Getattr(n, "allocate:default_destructor")) - && (!GetFlag(n, "feature:ignore"))) { - addDestructor(n); - } - } - - if (dir) { - DirectorClassName = directorClassName(n); - classDirector(n); - } - /* check for abstract after resolving directors */ - - Abstract = abstractClassTest(n); - classHandler(n); - } else { - Abstract = abstractClassTest(n); - Language::classHandler(n); - } - - Abstract = oldAbstract; - cplus_mode = oldAccessMode; - NSpace = oldNSpace; - InClass = oldInClass; - CurrentClass = oldCurrentClass; - Delete(ClassType); - ClassType = oldClassType; - Delete(EnumClassPrefix); - EnumClassPrefix = oldEnumClassPrefix; - Delete(ClassPrefix); - ClassPrefix = oldClassPrefix; - Delete(ClassName); - ClassName = oldClassName; - if (dir) { - Delete(DirectorClassName); - } - DirectorClassName = oldDirectorClassName; - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classHandler() - * ---------------------------------------------------------------------- */ - -int Language::classHandler(Node *n) { - save_value<int> oldExtend(Extend); - if (Getattr(n, "template")) - Extend = 0; - bool hasDirector = Swig_directorclass(n) ? true : false; - - /* Emit all of the class members */ - emit_children(n); - - /* Look for smart pointer handling */ - if (Getattr(n, "allocate:smartpointer")) { - List *methods = Getattr(n, "allocate:smartpointer"); - cplus_mode = PUBLIC; - SmartPointer = CWRAP_SMART_POINTER; - if (Getattr(n, "allocate:smartpointerconst") && Getattr(n, "allocate:smartpointermutable")) { - SmartPointer |= CWRAP_SMART_POINTER_OVERLOAD; - } - Iterator c; - for (c = First(methods); c.item; c = Next(c)) { - emit_one(c.item); - } - SmartPointer = 0; - } - - cplus_mode = PUBLIC; - - /* emit director disown method */ - if (hasDirector) { - classDirectorDisown(n); - - /* Emit additional protected virtual methods - only needed if the language module - * codes logic in the C++ layer instead of the director proxy class method - primarily - * to catch public use of protected methods by the scripting languages. */ - if (dirprot_mode() && extraDirectorProtectedCPPMethodsRequired()) { - Node *vtable = Getattr(n, "vtable"); - String *symname = Getattr(n, "sym:name"); - save_value<AccessMode> old_mode(cplus_mode); - cplus_mode = PROTECTED; - int len = Len(vtable); - for (int i = 0; i < len; i++) { - Node *item = Getitem(vtable, i); - Node *method = Getattr(item, "methodNode"); - SwigType *type = Getattr(method, "nodeType"); - if (Strcmp(type, "cdecl") != 0) - continue; - if (GetFlag(method, "feature:ignore")) - continue; - String *methodname = Getattr(method, "sym:name"); - String *wrapname = NewStringf("%s_%s", symname, methodname); - if (!symbolLookup(wrapname, "") && (!is_public(method))) { - Node *m = Copy(method); - Setattr(m, "director", "1"); - Setattr(m, "parentNode", n); - /* - * There is a bug that needs fixing still... - * This area of code is creating methods which have not been overridden in a derived class (director methods that are protected in the base) - * If the method is overloaded, then Swig_overload_dispatch() incorrectly generates a call to the base wrapper, _wrap_xxx method - * See director_protected_overloaded.i - Possibly sym:overname needs correcting here. - Printf(stdout, "new method: %s::%s(%s)\n", Getattr(parentNode(m), "name"), Getattr(m, "name"), ParmList_str_defaultargs(Getattr(m, "parms"))); - */ - cDeclaration(m); - Delete(m); - } - Delete(wrapname); - } - } - } - - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::classforwardDeclaration() - * ---------------------------------------------------------------------- */ - -int Language::classforwardDeclaration(Node *n) { - (void) n; - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::constructorDeclaration() - * ---------------------------------------------------------------------- */ - -int Language::constructorDeclaration(Node *n) { - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - - if (!symname) - return SWIG_NOWRAP; - if (!CurrentClass) - return SWIG_NOWRAP; - if (ImportMode) - return SWIG_NOWRAP; - - if (Extend) { - /* extend default constructor can be safely ignored if there is already one */ - int num_required = ParmList_numrequired(Getattr(n, "parms")); - if ((num_required == 0) && Getattr(CurrentClass, "has_default_constructor")) { - return SWIG_NOWRAP; - } - if ((num_required == 1) && Getattr(CurrentClass, "has_copy_constructor")) { - String *ccdecl = Getattr(CurrentClass, "copy_constructor_decl"); - if (ccdecl && (Strcmp(ccdecl, Getattr(n, "decl")) == 0)) { - return SWIG_NOWRAP; - } - } - } - - /* clean protected overloaded constructors, in case they are not needed anymore */ - Node *over = Swig_symbol_isoverloaded(n); - if (over && !Getattr(CurrentClass, "sym:cleanconstructor")) { - int dirclass = Swig_directorclass(CurrentClass); - Node *nn = over; - while (nn) { - if (!is_public(nn)) { - if (!dirclass || !need_nonpublic_ctor(nn)) { - SetFlag(nn, "feature:ignore"); - } - } - nn = Getattr(nn, "sym:nextSibling"); - } - clean_overloaded(over); - Setattr(CurrentClass, "sym:cleanconstructor", "1"); - } - - if ((cplus_mode != PUBLIC)) { - /* check only for director classes */ - if (!Swig_directorclass(CurrentClass) || !need_nonpublic_ctor(n)) - return SWIG_NOWRAP; - } - - /* Name adjustment for %name */ - Swig_save("constructorDeclaration", n, "sym:name", NIL); - - { - String *base = Swig_scopename_last(name); - if ((Strcmp(base, symname) == 0) && (Strcmp(symname, ClassPrefix) != 0)) { - Setattr(n, "sym:name", ClassPrefix); - } - Delete(base); - } - - /* Only create a constructor if the class is not abstract */ - if (!Abstract) { - Node *over; - over = Swig_symbol_isoverloaded(n); - if (over) - over = first_nontemplate(over); - if ((over) && (!overloading)) { - /* If the symbol is overloaded. We check to see if it is a copy constructor. If so, - we invoke copyconstructorHandler() as a special case. */ - if (Getattr(n, "copy_constructor") && (!Getattr(CurrentClass, "has_copy_constructor"))) { - copyconstructorHandler(n); - Setattr(CurrentClass, "has_copy_constructor", "1"); - } else { - if (Getattr(over, "copy_constructor")) - over = Getattr(over, "sym:nextSibling"); - if (over != n) { - Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, input_file, line_number, - "Overloaded constructor ignored. %s\n", Swig_name_decl(n)); - Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, Getfile(over), Getline(over), - "Previous declaration is %s\n", Swig_name_decl(over)); - } else { - constructorHandler(n); - } - } - } else { - String *expected_name = ClassName; - String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0; - String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name); - Delete(scope); - if (!Equal(actual_name, expected_name) && !SwigType_istemplate(expected_name) && !SwigType_istemplate(actual_name)) { - // Checking templates is skipped but they ought to be checked... they are just somewhat more tricky to check correctly - bool illegal_name = true; - if (Extend) { - // Check for typedef names used as a constructor name in %extend. This is deprecated except for anonymous - // typedef structs which have had their symbol names adjusted to the typedef name in the parser. - SwigType *name_resolved = SwigType_typedef_resolve_all(actual_name); - SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name); - - if (!CPlusPlus) { - if (Strncmp(name_resolved, "struct ", 7) == 0) - Replace(name_resolved, "struct ", "", DOH_REPLACE_FIRST); - else if (Strncmp(name_resolved, "union ", 6) == 0) - Replace(name_resolved, "union ", "", DOH_REPLACE_FIRST); - } - - illegal_name = !Equal(name_resolved, expected_name_resolved); - if (!illegal_name) - Swig_warning(WARN_LANG_EXTEND_CONSTRUCTOR, input_file, line_number, "Use of an illegal constructor name '%s' in %%extend is deprecated, the constructor name should be '%s'.\n", - SwigType_str(Swig_scopename_last(actual_name), 0), SwigType_str(Swig_scopename_last(expected_name), 0)); - Delete(name_resolved); - Delete(expected_name_resolved); - } - if (illegal_name) { - Swig_warning(WARN_LANG_RETURN_TYPE, input_file, line_number, "Function %s must have a return type. Ignored.\n", Swig_name_decl(n)); - Swig_restore(n); - return SWIG_NOWRAP; - } - } - constructorHandler(n); - } - } - Setattr(CurrentClass, "has_constructor", "1"); - - Swig_restore(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * get_director_ctor_code() - * ---------------------------------------------------------------------- */ - -static String *get_director_ctor_code(Node *n, String *director_ctor_code, String *director_prot_ctor_code, List *&abstracts) { - String *director_ctor = director_ctor_code; - int use_director = Swig_directorclass(n); - if (use_director) { - Node *pn = Swig_methodclass(n); - abstracts = Getattr(pn, "abstracts"); - if (director_prot_ctor_code) { - int is_notabstract = GetFlag(pn, "feature:notabstract"); - int is_abstract = abstracts && !is_notabstract; - if (is_protected(n) || is_abstract) { - director_ctor = director_prot_ctor_code; - abstracts = Copy(abstracts); - Delattr(pn, "abstracts"); - } else { - if (is_notabstract) { - abstracts = Copy(abstracts); - Delattr(pn, "abstracts"); - } else { - abstracts = 0; - } - } - } - } - return director_ctor; -} - - -/* ---------------------------------------------------------------------- - * Language::constructorHandler() - * ---------------------------------------------------------------------- */ - -int Language::constructorHandler(Node *n) { - Swig_require("constructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL); - String *symname = Getattr(n, "sym:name"); - String *mrename = Swig_name_construct(NSpace, symname); - String *nodeType = Getattr(n, "nodeType"); - int constructor = (!Cmp(nodeType, "constructor")); - List *abstracts = 0; - String *director_ctor = get_director_ctor_code(n, director_ctor_code, - director_prot_ctor_code, - abstracts); - if (!constructor) { - /* if not originally a constructor, still handle it as one */ - Setattr(n, "handled_as_constructor", "1"); - } - - int extendmember = GetFlag(n, "isextendmember") ? Extend : 0; - int flags = Getattr(n, "template") ? extendmember : Extend; - Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, flags, DirectorClassName); - Setattr(n, "sym:name", mrename); - functionWrapper(n); - Delete(mrename); - Swig_restore(n); - if (abstracts) - Setattr(Swig_methodclass(n), "abstracts", abstracts); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::copyconstructorHandler() - * ---------------------------------------------------------------------- */ - -int Language::copyconstructorHandler(Node *n) { - Swig_require("copyconstructorHandler", n, "?name", "*sym:name", "?type", "?parms", NIL); - String *symname = Getattr(n, "sym:name"); - String *mrename = Swig_name_copyconstructor(NSpace, symname); - List *abstracts = 0; - String *director_ctor = get_director_ctor_code(n, director_ctor_code, - director_prot_ctor_code, - abstracts); - Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend, DirectorClassName); - Setattr(n, "sym:name", mrename); - functionWrapper(n); - Delete(mrename); - Swig_restore(n); - if (abstracts) - Setattr(Swig_methodclass(n), "abstracts", abstracts); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::destructorDeclaration() - * ---------------------------------------------------------------------- */ - -int Language::destructorDeclaration(Node *n) { - - if (!CurrentClass) - return SWIG_NOWRAP; - if (cplus_mode != PUBLIC && !Getattr(CurrentClass, "feature:unref")) - return SWIG_NOWRAP; - if (ImportMode) - return SWIG_NOWRAP; - - Swig_save("destructorDeclaration", n, "name", "sym:name", NIL); - - char *c = GetChar(n, "sym:name"); - if (c && (*c == '~')) { - Setattr(n, "sym:name", c + 1); - } - - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - - if ((Strcmp(name, symname) == 0) || (Strcmp(symname, ClassPrefix) != 0)) { - Setattr(n, "sym:name", ClassPrefix); - } - - String *expected_name = ClassName; - String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0; - String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name); - Delete(scope); - Replace(actual_name, "~", "", DOH_REPLACE_FIRST); - if (!Equal(actual_name, expected_name) && !(Getattr(n, "template"))) { - bool illegal_name = true; - if (Extend) { - // Check for typedef names used as a destructor name in %extend. This is deprecated except for anonymous - // typedef structs which have had their symbol names adjusted to the typedef name in the parser. - SwigType *name_resolved = SwigType_typedef_resolve_all(actual_name); - SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name); - - if (!CPlusPlus) { - if (Strncmp(name_resolved, "struct ", 7) == 0) - Replace(name_resolved, "struct ", "", DOH_REPLACE_FIRST); - else if (Strncmp(name_resolved, "union ", 6) == 0) - Replace(name_resolved, "union ", "", DOH_REPLACE_FIRST); - } - - illegal_name = !Equal(name_resolved, expected_name_resolved); - if (!illegal_name) - Swig_warning(WARN_LANG_EXTEND_DESTRUCTOR, input_file, line_number, "Use of an illegal destructor name '%s' in %%extend is deprecated, the destructor name should be '%s'.\n", - SwigType_str(Swig_scopename_last(actual_name), 0), SwigType_str(Swig_scopename_last(expected_name), 0)); - Delete(name_resolved); - Delete(expected_name_resolved); - } - - if (illegal_name) { - Swig_warning(WARN_LANG_ILLEGAL_DESTRUCTOR, input_file, line_number, "Illegal destructor name %s. Ignored.\n", Swig_name_decl(n)); - Swig_restore(n); - return SWIG_NOWRAP; - } - } - destructorHandler(n); - - Setattr(CurrentClass, "has_destructor", "1"); - Swig_restore(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::destructorHandler() - * ---------------------------------------------------------------------- */ - -int Language::destructorHandler(Node *n) { - Swig_require("destructorHandler", n, "?name", "*sym:name", NIL); - Swig_save("destructorHandler", n, "type", "parms", NIL); - - String *symname = Getattr(n, "sym:name"); - String *mrename; - char *csymname = Char(symname); - if (*csymname == '~') - csymname += 1; - - mrename = Swig_name_destroy(NSpace, csymname); - - Swig_DestructorToFunction(n, NSpace, ClassType, CPlusPlus, Extend); - Setattr(n, "sym:name", mrename); - functionWrapper(n); - Delete(mrename); - Swig_restore(n); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::accessDeclaration() - * ---------------------------------------------------------------------- */ - -int Language::accessDeclaration(Node *n) { - String *kind = Getattr(n, "kind"); - if (Cmp(kind, "public") == 0) { - cplus_mode = PUBLIC; - } else if (Cmp(kind, "private") == 0) { - cplus_mode = PRIVATE; - } else if (Cmp(kind, "protected") == 0) { - cplus_mode = PROTECTED; - } - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Language::namespaceDeclaration() - * ----------------------------------------------------------------------------- */ - -int Language::namespaceDeclaration(Node *n) { - if (Getattr(n, "alias")) - return SWIG_OK; - if (Getattr(n, "unnamed")) - return SWIG_OK; - emit_children(n); - return SWIG_OK; -} - -int Language::validIdentifier(String *s) { - char *c = Char(s); - while (*c) { - if (!(isalnum(*c) || (*c == '_'))) - return 0; - c++; - } - return 1; -} - -/* ----------------------------------------------------------------------------- - * Language::usingDeclaration() - * ----------------------------------------------------------------------------- */ - -int Language::usingDeclaration(Node *n) { - if ((cplus_mode == PUBLIC) || (!is_public(n) && dirprot_mode())) { - Node *np = Copy(n); - Node *c; - for (c = firstChild(np); c; c = nextSibling(c)) { - /* it seems for some cases this is needed, like A* A::boo() */ - if (CurrentClass) - Setattr(c, "parentNode", CurrentClass); - emit_one(c); - } - Delete(np); - } - return SWIG_OK; -} - -/* Stubs. Language modules need to implement these */ - -/* ---------------------------------------------------------------------- - * Language::constantWrapper() - * ---------------------------------------------------------------------- */ - -int Language::constantWrapper(Node *n) { - String *name = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - String *value = Getattr(n, "value"); - String *str = SwigType_str(type, name); - Printf(stdout, "constantWrapper : %s = %s\n", str, value); - Delete(str); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::variableWrapper() - * ---------------------------------------------------------------------- */ - -int Language::variableWrapper(Node *n) { - Swig_require("variableWrapper", n, "*name", "*sym:name", "*type", "?parms", "?varset", "?varget", NIL); - String *symname = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - String *name = Getattr(n, "name"); - - Delattr(n,"varset"); - Delattr(n,"varget"); - - String *newsymname = 0; - if (!CurrentClass && EnumClassPrefix) { - newsymname = Swig_name_member(0, EnumClassPrefix, symname); - symname = newsymname; - } - - /* If no way to set variables. We simply create functions */ - int assignable = is_assignable(n); - int flags = use_naturalvar_mode(n); - if (!GetFlag(n, "wrappedasconstant")) - flags = flags | Extend; - - if (assignable) { - int make_set_wrapper = 1; - String *tm = Swig_typemap_lookup("globalin", n, name, 0); - - Swig_VarsetToFunction(n, flags); - String *sname = Swig_name_set(NSpace, symname); - Setattr(n, "sym:name", sname); - Delete(sname); - - if (!tm) { - if (SwigType_isarray(type)) { - Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0)); - make_set_wrapper = 0; - } - } else { - String *pname0 = Swig_cparm_name(0, 0); - Replace(tm, "$input", pname0, DOH_REPLACE_ANY); - Setattr(n, "wrap:action", tm); - Delete(tm); - Delete(pname0); - } - if (make_set_wrapper) { - Setattr(n, "varset", "1"); - functionWrapper(n); - } else { - SetFlag(n, "feature:immutable"); - } - /* Restore parameters */ - Setattr(n, "sym:name", symname); - Setattr(n, "type", type); - Setattr(n, "name", name); - Delattr(n, "varset"); - - /* Delete all attached typemaps and typemap attributes */ - Iterator ki; - for (ki = First(n); ki.key; ki = Next(ki)) { - if (Strncmp(ki.key, "tmap:", 5) == 0) - Delattr(n, ki.key); - } - } - - Swig_VargetToFunction(n, flags); - String *gname = Swig_name_get(NSpace, symname); - Setattr(n, "sym:name", gname); - Delete(gname); - Setattr(n, "varget", "1"); - functionWrapper(n); - Delattr(n, "varget"); - Swig_restore(n); - Delete(newsymname); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * Language::functionWrapper() - * ---------------------------------------------------------------------- */ - -int Language::functionWrapper(Node *n) { - String *name = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - ParmList *parms = Getattr(n, "parms"); - - Printf(stdout, "functionWrapper : %s\n", SwigType_str(type, NewStringf("%s(%s)", name, ParmList_str_defaultargs(parms)))); - Printf(stdout, " action : %s\n", Getattr(n, "wrap:action")); - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Language::nativeWrapper() - * ----------------------------------------------------------------------------- */ - -int Language::nativeWrapper(Node *n) { - (void) n; - return SWIG_OK; -} - -void Language::main(int argc, char *argv[]) { - (void) argc; - (void) argv; -} - -/* ----------------------------------------------------------------------------- - * Language::addSymbol() - * - * Adds a symbol entry into the target language symbol tables. - * Returns 1 if the symbol is added successfully. - * Prints an error message and returns 0 if a conflict occurs. - * The scope is optional for target languages and if supplied must be a fully - * qualified scope and the symbol s must not contain any scope qualifiers. - * ----------------------------------------------------------------------------- */ - -int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) { - //Printf( stdout, "addSymbol: %s %s\n", s, scope ); - Hash *symbols = Getattr(symtabs, scope ? scope : ""); - if (!symbols) { - symbols = symbolAddScope(scope); - } else { - Node *c = Getattr(symbols, s); - if (c && (c != n)) { - if (scope && Len(scope) > 0) - Swig_error(input_file, line_number, "'%s' is multiply defined in the generated target language module in scope '%s'.\n", s, scope); - else - Swig_error(input_file, line_number, "'%s' is multiply defined in the generated target language module.\n", s); - Swig_error(Getfile(c), Getline(c), "Previous declaration of '%s'\n", s); - return 0; - } - } - Setattr(symbols, s, n); - return 1; -} - -/* ----------------------------------------------------------------------------- - * Language::addInterfaceSymbol() - * - * Adds a symbol entry into the target language symbol tables - for the interface - * feature only. - * Returns 1 if the symbol is added successfully. - * The scope is as per addSymbol. - * ----------------------------------------------------------------------------- */ - -int Language::addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope) { - if (interface_name) { - Node *existing_symbol = symbolLookup(interface_name, scope); - if (existing_symbol) { - String *proxy_class_name = Getattr(n, "sym:name"); - Swig_error(input_file, line_number, "The interface feature name '%s' for proxy class '%s' is already defined in the generated target language module in scope '%s'.\n", - interface_name, proxy_class_name, scope); - Swig_error(Getfile(existing_symbol), Getline(existing_symbol), "Previous declaration of '%s'\n", interface_name); - return 0; - } - if (!addSymbol(interface_name, n, scope)) - return 0; - } - return 1; -} - -/* ----------------------------------------------------------------------------- - * Language::symbolAddScope() - * - * Creates a scope (symbols Hash) for given name. This method is auxiliary, - * you don't have to call it - addSymbols will lazily create scopes automatically. - * If scope with given name already exists, then do nothing. - * Returns newly created (or already existing) scope. - * ----------------------------------------------------------------------------- */ -Hash* Language::symbolAddScope(const_String_or_char_ptr scope) { - Hash *symbols = symbolScopeLookup(scope); - if(!symbols) { - // The order in which the following code is executed is important. In the Language - // constructor addScope("") is called to create a top level scope. - // Thus we must first add a symbols hash to symtab and only then add pseudo - // symbols to the top-level scope. - - // New scope which has not been added by the target language - lazily created. - symbols = NewHash(); - Setattr(symtabs, scope, symbols); - - // Add the new scope as a symbol in the top level scope. - // Alternatively the target language must add it in before attempting to add symbols into the scope. - const_String_or_char_ptr top_scope = ""; - Hash *topscope_symbols = Getattr(symtabs, top_scope); - Hash *pseudo_symbol = NewHash(); - Setattr(pseudo_symbol, "sym:scope", "1"); - Setattr(topscope_symbols, scope, pseudo_symbol); - } - return symbols; -} - -/* ----------------------------------------------------------------------------- - * Language::symbolScopeLookup() - * - * Lookup and returns a symtable (hash) representing given scope. Hash contains - * all symbols in this scope. - * ----------------------------------------------------------------------------- */ -Hash* Language::symbolScopeLookup( const_String_or_char_ptr scope ) { - Hash *symbols = Getattr(symtabs, scope ? scope : ""); - return symbols; -} - -/* ----------------------------------------------------------------------------- - * Language::symbolScopePseudoSymbolLookup() - * - * For every scope there is a special pseudo-symbol in the top scope (""). It - * exists solely to detect name clashes. This pseudo symbol may contain a few properties, - * but more could be added. This is also true for the top level scope (""). - * It contains a pseudo symbol with name "" (empty). Pseudo symbol contains the - * following properties: - * sym:scope = "1" - a flag that this is a scope pseudo symbol - * - * Pseudo symbols are a Hash*, not a Node*. - * There is no difference from symbolLookup() method except for signature - * and return type. - * ----------------------------------------------------------------------------- */ -Hash* Language::symbolScopePseudoSymbolLookup( const_String_or_char_ptr scope ) -{ - /* Getting top scope */ - const_String_or_char_ptr top_scope = ""; - Hash *symbols = Getattr(symtabs, top_scope); - return Getattr(symbols, scope); -} - -/* ----------------------------------------------------------------------------- - * Language::dumpSymbols() - * ----------------------------------------------------------------------------- */ - -void Language::dumpSymbols() { - Printf(stdout, "LANGUAGE SYMBOLS start =======================================\n"); - - Node *table = symtabs; - Iterator ki = First(table); - while (ki.key) { - String *k = ki.key; - Printf(stdout, "===================================================\n"); - Printf(stdout, "%s -\n", k); - { - Symtab *symtab = Getattr(table, k); - Iterator it = First(symtab); - while (it.key) { - String *symname = it.key; - Printf(stdout, " %s\n", symname); - it = Next(it); - } - } - ki = Next(ki); - } - - Printf(stdout, "LANGUAGE SYMBOLS finish =======================================\n"); -} - -/* ----------------------------------------------------------------------------- - * Language::symbolLookup() - * ----------------------------------------------------------------------------- */ - -Node *Language::symbolLookup(const String *s, const_String_or_char_ptr scope) { - Hash *symbols = Getattr(symtabs, scope ? scope : ""); - if (!symbols) { - return NULL; - } - return Getattr(symbols, s); -} - -/* ----------------------------------------------------------------------------- - * Language::classLookup() - * - * Tries to locate a class from a type definition - * ----------------------------------------------------------------------------- */ - -Node *Language::classLookup(const SwigType *s) { - static Hash *classtypes = 0; - - Node *n = 0; - - /* Look in hash of cached values */ - n = classtypes ? Getattr(classtypes, s) : 0; - if (!n) { - Symtab *stab = 0; - SwigType *ty1 = SwigType_typedef_resolve_all(s); - SwigType *ty2 = SwigType_strip_qualifiers(ty1); - - String *base = SwigType_base(ty2); - - Replaceall(base, "class ", ""); - Replaceall(base, "struct ", ""); - Replaceall(base, "union ", ""); - - if (strncmp(Char(base), "::", 2) == 0) { - String *oldbase = base; - base = NewString(Char(base) + 2); - Delete(oldbase); - } - - String *prefix = SwigType_prefix(ty2); - - /* Do a symbol table search on the base type */ - while (!n) { - Hash *nstab; - n = Swig_symbol_clookup(base, stab); - if (!n) - break; - if (Strcmp(nodeType(n), "class") == 0) - break; - Node *sibling = n; - while (sibling) { - sibling = Getattr(sibling, "csym:nextSibling"); - if (sibling && Strcmp(nodeType(sibling), "class") == 0) - break; - } - if (sibling) - break; - n = parentNode(n); - if (!n) - break; - nstab = Getattr(n, "sym:symtab"); - n = 0; - if ((!nstab) || (nstab == stab)) { - break; - } - stab = nstab; - } - if (n) { - /* Found a match. Look at the prefix. We only allow - the cases where we want a proxy class for the particular type */ - bool acceptable_prefix = - (Len(prefix) == 0) || // simple type (pass by value) - (Strcmp(prefix, "p.") == 0) || // pointer - (Strcmp(prefix, "r.") == 0) || // reference - (Strcmp(prefix, "z.") == 0) || // rvalue reference - SwigType_prefix_is_simple_1D_array(prefix); // Simple 1D array (not arrays of pointers/references) - // Also accept pointer by const reference, not non-const pointer reference - if (!acceptable_prefix && (Strcmp(prefix, "r.p.") == 0)) { - Delete(prefix); - prefix = SwigType_prefix(ty1); - acceptable_prefix = (Strncmp(prefix, "r.q(const", 9) == 0); - } - if (acceptable_prefix) { - SwigType *cs = Copy(s); - if (!classtypes) - classtypes = NewHash(); - Setattr(classtypes, cs, n); - Delete(cs); - } else { - n = 0; - } - } - Delete(prefix); - Delete(base); - Delete(ty2); - Delete(ty1); - } - if (n && (GetFlag(n, "feature:ignore") || Getattr(n, "feature:onlychildren"))) { - n = 0; - } - - return n; -} - -/* ----------------------------------------------------------------------------- - * Language::enumLookup() - * - * Finds and returns the Node containing the enum declaration for the (enum) - * type passed in. - * ----------------------------------------------------------------------------- */ - -Node *Language::enumLookup(SwigType *s) { - static Hash *enumtypes = 0; - - Node *n = 0; - - /* Look in hash of cached values */ - n = enumtypes ? Getattr(enumtypes, s) : 0; - if (!n) { - Symtab *stab = 0; - SwigType *lt = SwigType_ltype(s); - SwigType *ty1 = SwigType_typedef_resolve_all(lt); - SwigType *ty2 = SwigType_strip_qualifiers(ty1); - - String *base = SwigType_base(ty2); - - Replaceall(base, "enum ", ""); - String *prefix = SwigType_prefix(ty2); - - if (strncmp(Char(base), "::", 2) == 0) { - String *oldbase = base; - base = NewString(Char(base) + 2); - Delete(oldbase); - } - - /* Look for type in symbol table */ - while (!n) { - Hash *nstab; - n = Swig_symbol_clookup(base, stab); - if (!n) - break; - if (Equal(nodeType(n), "enum")) - break; - if (Equal(nodeType(n), "enumforward") && GetFlag(n, "enumMissing")) - break; - n = parentNode(n); - if (!n) - break; - nstab = Getattr(n, "sym:symtab"); - n = 0; - if ((!nstab) || (nstab == stab)) { - break; - } - stab = nstab; - } - if (n) { - /* Found a match. Look at the prefix. We only allow simple types. */ - if (Len(prefix) == 0) { /* Simple type */ - if (!enumtypes) - enumtypes = NewHash(); - Setattr(enumtypes, Copy(s), n); - } else { - n = 0; - } - } - Delete(prefix); - Delete(base); - Delete(ty2); - Delete(ty1); - Delete(lt); - } - if (n && (GetFlag(n, "feature:ignore"))) { - n = 0; - } - - return n; -} - -/* ----------------------------------------------------------------------------- - * Language::allow_overloading() - * ----------------------------------------------------------------------------- */ - -void Language::allow_overloading(int val) { - overloading = val; -} - -/* ----------------------------------------------------------------------------- - * Language::allow_multiple_input() - * ----------------------------------------------------------------------------- */ - -void Language::allow_multiple_input(int val) { - multiinput = val; -} - -/* ----------------------------------------------------------------------------- - * Language::enable_cplus_runtime_mode() - * ----------------------------------------------------------------------------- */ - -void Language::enable_cplus_runtime_mode() { - cplus_runtime = 1; -} - -/* ----------------------------------------------------------------------------- - * Language::cplus_runtime_mode() - * ----------------------------------------------------------------------------- */ - -int Language::cplus_runtime_mode() { - return cplus_runtime; -} - -/* ----------------------------------------------------------------------------- - * Language::allow_directors() - * ----------------------------------------------------------------------------- */ - -void Language::allow_directors(int val) { - directors = val; -} - -/* ----------------------------------------------------------------------------- - * Language::directorsEnabled() - * ----------------------------------------------------------------------------- */ - -int Language::directorsEnabled() const { - return director_language && CPlusPlus && (directors || director_mode); -} - -/* ----------------------------------------------------------------------------- - * Language::allow_dirprot() - * ----------------------------------------------------------------------------- */ - -void Language::allow_dirprot(int val) { - director_protected_mode = val; -} - -/* ----------------------------------------------------------------------------- - * Language::allow_allprotected() - * ----------------------------------------------------------------------------- */ - -void Language::allow_allprotected(int val) { - all_protected_mode = val; -} - -/* ----------------------------------------------------------------------------- - * Language::dirprot_mode() - * ----------------------------------------------------------------------------- */ - -int Language::dirprot_mode() const { - return directorsEnabled() ? director_protected_mode : 0; -} - -/* ----------------------------------------------------------------------------- - * Language::need_nonpublic_ctor() - * ----------------------------------------------------------------------------- */ - -int Language::need_nonpublic_ctor(Node *n) { - /* - detects when a protected constructor is needed, which is always - the case if 'dirprot' mode is used. However, if that is not the - case, we will try to strictly emit what is minimal to don't break - the generated, while preserving compatibility with java, which - always try to emit the default constructor. - - rules: - - - when dirprot mode is used, the protected constructors are - always needed. - - - the protected default constructor is always needed. - - - if dirprot mode is not used, the protected constructors will be - needed only if: - - - there is no any public constructor in the class, and - - there is no protected default constructor - - In that case, all the declared protected constructors are - needed since we don't know which one to pick up. - - Note: given all the complications here, I am always in favor to - always enable 'dirprot', since is the C++ idea of protected - members, and use %ignore for the method you don't want to add in - the director class. - */ - if (directorsEnabled()) { - if (is_protected(n)) { - if (dirprot_mode()) { - /* when using dirprot mode, the protected constructors are - always needed */ - return 1; - } else { - int is_default_ctor = !ParmList_numrequired(Getattr(n, "parms")); - if (is_default_ctor) { - /* the default protected constructor is always needed, for java compatibility */ - return 1; - } else { - /* check if there is a public constructor */ - Node *parent = Swig_methodclass(n); - int public_ctor = Getattr(parent, "allocate:default_constructor") - || Getattr(parent, "allocate:public_constructor"); - if (!public_ctor) { - /* if not, the protected constructor will be needed only - if there is no protected default constructor declared */ - int no_prot_default_ctor = !Getattr(parent, "allocate:default_base_constructor"); - return no_prot_default_ctor; - } - } - } - } - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * Language::need_nonpublic_member() - * ----------------------------------------------------------------------------- */ -int Language::need_nonpublic_member(Node *n) { - if (directorsEnabled() && DirectorClassName) { - if (is_protected(n)) { - if (dirprot_mode()) { - /* when using dirprot mode, the protected members are always needed. */ - return 1; - } else { - /* if the method is pure virtual, we need it. */ - int pure_virtual = (Cmp(Getattr(n, "value"), "0") == 0); - return pure_virtual; - } - } - } - return 0; -} - - -/* ----------------------------------------------------------------------------- - * Language::is_smart_pointer() - * ----------------------------------------------------------------------------- */ - -int Language::is_smart_pointer() const { - return SmartPointer; -} - -/* ----------------------------------------------------------------------------- - * Language::makeParameterName() - * - * Inputs: - * n - Node - * p - parameter node - * arg_num - parameter argument number - * setter - set this flag when wrapping variables - * Return: - * arg - a unique parameter name - * ----------------------------------------------------------------------------- */ -String *Language::makeParameterName(Node *n, Parm *p, int arg_num, bool setter) const { - - String *arg = 0; - String *pn = Getattr(p, "name"); - - // Check if parameter name is a duplicate. - int count = 0; - ParmList *plist = Getattr(n, "parms"); - while (plist) { - if ((Cmp(pn, Getattr(plist, "name")) == 0)) - count++; - plist = nextSibling(plist); - } - - // If the parameter has no name at all or has a non-unique name, replace it with "argN". - if (!pn || count > 1) { - arg = NewStringf("arg%d", arg_num); - } else { - // Otherwise, try to use the original C name, but modify it if necessary to avoid conflicting with the language keywords. - arg = Swig_name_make(p, 0, pn, 0, 0); - } - - if (setter && Cmp(arg, "self") != 0) { - // Some languages (C#) insist on calling the input variable "value" while - // others (D, Java) could, in principle, use something different but this - // would require more work, and so we just use "value" for them too. - // For setters the parameter name sometimes includes C++ scope resolution which needs removing. - Delete(arg); - arg = NewString("value"); - } - - return arg; -} - -/* ----------------------------------------------------------------------------- - * Language::() - * ----------------------------------------------------------------------------- */ - -bool Language::isNonVirtualProtectedAccess(Node *n) const { - // Ideally is_non_virtual_protected_access() would contain all this logic, see - // comments therein about vtable. - return DirectorClassName && is_non_virtual_protected_access(n); -} - -/* ----------------------------------------------------------------------------- - * Language::extraDirectorProtectedCPPMethodsRequired() - * ----------------------------------------------------------------------------- */ - -bool Language::extraDirectorProtectedCPPMethodsRequired() const { - return true; -} - -/* ----------------------------------------------------------------------------- - * Language::nestedClassesSupport() - * ----------------------------------------------------------------------------- */ - -Language::NestedClassSupport Language::nestedClassesSupport() const { - return NCS_Unknown; -} - -/* ----------------------------------------------------------------------------- - * Language::kwargsSupport() - * ----------------------------------------------------------------------------- */ - -bool Language::kwargsSupport() const { - return false; -} - -/* ----------------------------------------------------------------------------- - * Language::is_wrapping_class() - * ----------------------------------------------------------------------------- */ - -int Language::is_wrapping_class() const { - return InClass; -} - -/* ----------------------------------------------------------------------------- - * Language::getCurrentClass() - * ----------------------------------------------------------------------------- */ - -Node *Language::getCurrentClass() const { - return CurrentClass; -} - -/* ----------------------------------------------------------------------------- - * Language::getNSpace() - * ----------------------------------------------------------------------------- */ - -String *Language::getNSpace() const { - return NSpace; -} - -/* ----------------------------------------------------------------------------- - * Language::getClassName() - * ----------------------------------------------------------------------------- */ - -String *Language::getClassName() const { - return ClassName; -} - -/* ----------------------------------------------------------------------------- - * Language::getClassPrefix() - * ----------------------------------------------------------------------------- */ - -String *Language::getClassPrefix() const { - return ClassPrefix; -} - -/* ----------------------------------------------------------------------------- - * Language::getEnumClassPrefix() - * ----------------------------------------------------------------------------- */ - -String *Language::getEnumClassPrefix() const { - return EnumClassPrefix; -} - -/* ----------------------------------------------------------------------------- - * Language::getClassType() - * ----------------------------------------------------------------------------- */ - -String *Language::getClassType() const { - return ClassType; -} - -/* ----------------------------------------------------------------------------- - * Language::abstractClassTest() - * ----------------------------------------------------------------------------- */ -//#define SWIG_DEBUG -int Language::abstractClassTest(Node *n) { - /* check for non public operator new */ - if (GetFlag(n, "feature:notabstract")) - return 0; - if (Getattr(n, "allocate:nonew")) - return 1; - - // A class cannot be instantiated if one of its bases has a private destructor - // Note that if the above does not hold the class can be instantiated if its own destructor is private - List *bases = Getattr(n, "bases"); - if (bases) { - for (int i = 0; i < Len(bases); i++) { - Node *b = Getitem(bases, i); - if (GetFlag(b, "allocate:private_destructor")) - return 1; - } - } - - /* now check for the rest */ - List *abstracts = Getattr(n, "abstracts"); - if (!abstracts) - return 0; - int labs = Len(abstracts); -#ifdef SWIG_DEBUG - List *allbases = Getattr(n, "allbases"); - Printf(stderr, "testing %s %d %d\n", Getattr(n, "name"), labs, Len(allbases)); -#endif - if (!labs) - return 0; /*strange, but need to be fixed */ - if (abstracts && !directorsEnabled()) - return 1; - if (!GetFlag(n, "feature:director")) - return 1; - - Node *dirabstract = 0; - Node *vtable = Getattr(n, "vtable"); - if (vtable) { -#ifdef SWIG_DEBUG - Printf(stderr, "vtable %s %d %d\n", Getattr(n, "name"), Len(vtable), labs); -#endif - for (int i = 0; i < labs; i++) { - Node *ni = Getitem(abstracts, i); - String *method_id = vtable_method_id(ni); - if (!method_id) - continue; - bool exists_item = false; - int len = Len(vtable); - for (int i = 0; i < len; i++) { - Node *item = Getitem(vtable, i); - String *check_item = Getattr(item, "vmid"); - if (Strcmp(method_id, check_item) == 0) { - exists_item = true; - break; - } - } -#ifdef SWIG_DEBUG - Printf(stderr, "method %s %d\n", method_id, exists_item ? 1 : 0); -#endif - Delete(method_id); - if (!exists_item) { - dirabstract = ni; - break; - } - } - if (dirabstract) { - if (is_public(dirabstract)) { - Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n), - "Director class '%s' is abstract, abstract method '%s' is not accessible, maybe due to multiple inheritance or 'nodirector' feature\n", - SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name")); - } else { - Swig_warning(WARN_LANG_DIRECTOR_ABSTRACT, Getfile(n), Getline(n), - "Director class '%s' is abstract, abstract method '%s' is private\n", SwigType_namestr(Getattr(n, "name")), Getattr(dirabstract, "name")); - } - return 1; - } - } else { - return 1; - } - return 0; -} - -void Language::setSubclassInstanceCheck(String *nc) { - none_comparison = nc; -} - -void Language::setOverloadResolutionTemplates(String *argc, String *argv) { - Delete(argc_template_string); - argc_template_string = Copy(argc); - Delete(argv_template_string); - argv_template_string = Copy(argv); -} - -int Language::is_assignable(Node *n) { - if (GetFlag(n, "feature:immutable")) - return 0; - SwigType *type = Getattr(n, "type"); - Node *cn = 0; - SwigType *ftd = SwigType_typedef_resolve_all(type); - SwigType *td = SwigType_strip_qualifiers(ftd); - if (SwigType_type(td) == T_USER) { - cn = Swig_symbol_clookup(td, 0); - if (cn) { - if ((Strcmp(nodeType(cn), "class") == 0)) { - if (Getattr(cn, "allocate:noassign")) { - SetFlag(n, "feature:immutable"); - Delete(ftd); - Delete(td); - return 0; - } - } - } - } - Delete(ftd); - Delete(td); - return 1; -} - -String *Language::runtimeCode() { - return NewString(""); -} - -String *Language::defaultExternalRuntimeFilename() { - return 0; -} - -/* ----------------------------------------------------------------------------- - * Language::replaceSpecialVariables() - * - * Language modules should implement this if special variables are to be handled - * correctly in the $typemap(...) special variable macro. - * method - typemap method name - * tm - string containing typemap contents - * parm - a parameter describing the typemap type to be handled - * ----------------------------------------------------------------------------- */ -void Language::replaceSpecialVariables(String *method, String *tm, Parm *parm) { - (void)method; - (void)tm; - (void)parm; -} - -Language *Language::instance() { - return this_; -} - -Hash *Language::getClassHash() const { - return classhash; -} - diff --git a/contrib/tools/swig/Source/Modules/lua.cxx b/contrib/tools/swig/Source/Modules/lua.cxx deleted file mode 100644 index d3cf96b5262..00000000000 --- a/contrib/tools/swig/Source/Modules/lua.cxx +++ /dev/null @@ -1,2240 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * lua.cxx - * - * Lua language module for SWIG. - * ----------------------------------------------------------------------------- */ - -/* NEW LANGUAGE NOTE: - * ver001 - this is simply a copy of tcl8.cxx, which has been renamed - * ver002 - all non essential code commented out, program now does virtually nothing - it prints to stderr the list of functions to wrap, but does not create - the XXX_wrap.c file - * ver003 - added back top(), still prints the list of fns to stderr - but now creates a rather empty XXX_wrap.c with some basic boilerplate code - * ver004 - very basic version of functionWrapper() - also uncommented usage_string() to keep compiler happy - this will start producing proper looking code soon (I hope) - produced the wrapper code, but without any type conversion (in or out) - generates a few warning because of no wrappering - does not generate SWIG_init() - reason for this is that lua.swg is empty - we will need to add code into this to make it work - * ver005/6 - massive rework, basing work on the pike module instead of tcl - (pike module it only 1/3 of the size)(though not as complete) - * ver007 - added simple type checking - * ver008 - INPUT, OUTPUT, INOUT typemaps handled (though not all types yet) - * ver009 - class support: ok for basic types, but methods still TDB - (code is VERY messed up & needs to be cleaned) - * ver010 - Added support for embedded Lua. Try swig -lua -help for more information -*/ - -#include "swigmod.h" -#include "cparse.h" - -/**** Diagnostics: - With the #define REPORT(), you can change the amount of diagnostics given - This helps me search the parse tree & figure out what is going on inside SWIG - (because it's not clear or documented) -*/ -#define REPORT(T,D) // no info: -//#define REPORT(T,D) {Printf(stdout,T"\n");} // only title -//#define REPORT(T,D) {Printf(stdout,T" %p\n",n);} // title & pointer -//#define REPORT(T,D) {Printf(stdout,T"\n");display_mapping(D);} // the works -//#define REPORT(T,D) {Printf(stdout,T"\n");if(D)Swig_print_node(D);} // the works - -void display_mapping(DOH *d) { - if (d == 0 || !DohIsMapping(d)) - return; - for (Iterator it = First(d); it.item; it = Next(it)) { - if (DohIsString(it.item)) - Printf(stdout, " %s = %s\n", it.key, it.item); - else if (DohIsMapping(it.item)) - Printf(stdout, " %s = <mapping>\n", it.key); - else if (DohIsSequence(it.item)) - Printf(stdout, " %s = <sequence>\n", it.key); - else - Printf(stdout, " %s = <unknown>\n", it.key); - } -} - -extern "C" -{ - static int compareByLen(const DOH *f, const DOH *s) { - return Len(s) - Len(f); - } -} - - -/* NEW LANGUAGE NOTE:*********************************************** - most of the default options are handled by SWIG - you can add new ones here - (though for now I have not bothered) -NEW LANGUAGE NOTE:END ************************************************/ -static const char *usage = "\ -Lua Options (available with -lua)\n\ - -elua - Generates LTR compatible wrappers for smaller devices running elua\n\ - -eluac - LTR compatible wrappers in \"crass compress\" mode for elua\n\ - -elua-emulate - Emulates behaviour of eLua. Useful only for testing.\n\ - Incompatible with -elua/-eluac options.\n\ - -nomoduleglobal - Do not register the module name as a global variable \n\ - but return the module table from calls to require.\n\ - -no-old-metatable-bindings\n\ - - Disable support for old-style bindings name generation, some\n\ - old-style members scheme etc.\n\ - -squash-bases - Squashes symbols from all inheritance tree of a given class\n\ - into itself. Emulates pre-SWIG3.0 inheritance. Insignificantly\n\ - speeds things up, but increases memory consumption.\n\ -\n"; - -static int nomoduleglobal = 0; -static int elua_ltr = 0; -static int eluac_ltr = 0; -static int elua_emulate = 0; -static int squash_bases = 0; -/* The new metatable bindings were introduced in SWIG 3.0.0. - * old_metatable_bindings in v2: - * 1. static methods will be put into the scope their respective class - * belongs to as well as into the class scope itself. (only for classes without %nspace given) - * 2. The layout in elua mode is somewhat different - */ -static int old_metatable_bindings = 1; -static int old_compatible_names = 1; // This flag can temporarily disable backward compatible names generation if old_metatable_bindings is enabled - -/* NEW LANGUAGE NOTE:*********************************************** - To add a new language, you need to derive your class from - Language and the overload various virtual functions - (more on this as I figure it out) -NEW LANGUAGE NOTE:END ************************************************/ - -class LUA:public Language { -private: - - File *f_begin; - File *f_runtime; - File *f_header; - File *f_wrappers; - File *f_init; - File *f_initbeforefunc; - String *s_luacode; // luacode to be called during init - String *module; //name of the module - - // Parameters for current class. NIL if not parsing class - int have_constructor; - int have_destructor; - String *destructor_action; - // This variable holds the name of the current class in Lua. Usually it is - // the same as C++ class name, but rename directives can change it. - String *proxy_class_name; - // This is a so called fully qualified symname - the above proxy class name - // prepended with class namespace. If class Lua name is the same as class C++ name, - // then it is basically C++ fully qualified name with colons replaced with dots. - String *full_proxy_class_name; - // All static methods and/or variables are treated as if they were in the - // special C++ namespace $(classname).SwigStatic. This is internal mechanism only - // and is not visible to user in any manner. This variable holds the name - // of such pseudo-namespace a.k.a the result of above expression evaluation - String *class_static_nspace; - // This variable holds the name of generated C function that acts as a constructor - // for the currently parsed class. - String *constructor_name; - - // Many wrappers forward calls to each other, for example staticmembervariableHandler - // forwards calls to variableHandler, which, in turn, makes to call to functionWrapper. - // In order to access information about whether it is a static member of class or just - // a plain old variable, the current array is kept and used as a 'log' of the call stack. - enum TState { - NO_CPP, - VARIABLE, - GLOBAL_FUNC, - GLOBAL_VAR, - MEMBER_FUNC, - CONSTRUCTOR, - DESTRUCTOR, - MEMBER_VAR, - STATIC_FUNC, - STATIC_VAR, - STATIC_CONST, // enums and things like static const int x = 5; - ENUM_CONST, // This is only needed for backward compatibility in C mode - - STATES_COUNT - }; - bool current[STATES_COUNT]; - -public: - - /* --------------------------------------------------------------------- - * LUA() - * - * Initialize member data - * --------------------------------------------------------------------- */ - - LUA(): - f_begin(0), - f_runtime(0), - f_header(0), - f_wrappers(0), - f_init(0), - f_initbeforefunc(0), - s_luacode(0), - module(0), - have_constructor(0), - have_destructor(0), - destructor_action(0), - proxy_class_name(0), - full_proxy_class_name(0), - class_static_nspace(0), - constructor_name(0) { - for (int i = 0; i < STATES_COUNT; i++) - current[i] = false; - } - - /* NEW LANGUAGE NOTE:*********************************************** - This is called to initialise the system & read any command line args - most of this is boilerplate code, except the command line args - which depends upon what args your code supports - NEW LANGUAGE NOTE:END *********************************************** */ - - /* --------------------------------------------------------------------- - * main() - * - * Parse command line options and initializes variables. - * --------------------------------------------------------------------- */ - - virtual void main(int argc, char *argv[]) { - - /* Set location of SWIG library */ - SWIG_library_directory("lua"); - - /* Look for certain command line options */ - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-help") == 0) { // usage flags - fputs(usage, stdout); - } else if (strcmp(argv[i], "-nomoduleglobal") == 0) { - nomoduleglobal = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-elua") == 0) { - elua_ltr = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-eluac") == 0) { - eluac_ltr = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-no-old-metatable-bindings") == 0) { - Swig_mark_arg(i); - old_metatable_bindings = 0; - } else if (strcmp(argv[i], "-squash-bases") == 0) { - Swig_mark_arg(i); - squash_bases = 1; - } else if (strcmp(argv[i], "-elua-emulate") == 0) { - Swig_mark_arg(i); - elua_emulate = 1; - } - } - } - - if (elua_emulate && (eluac_ltr || elua_ltr )) { - Printf(stderr, "Cannot have -elua-emulate with either -eluac or -elua\n"); - Swig_arg_error(); - } - - // Set elua_ltr if elua_emulate is requested - if(elua_emulate) - elua_ltr = 1; - - /* NEW LANGUAGE NOTE:*********************************************** - This is the boilerplate code, setting a few #defines - and which lib directory to use - the SWIG_library_directory() is also boilerplate code - but it always seems to be the first line of code - NEW LANGUAGE NOTE:END *********************************************** */ - /* Add a symbol to the parser for conditional compilation */ - Preprocessor_define("SWIGLUA 1", 0); - - /* Set language-specific configuration file */ - SWIG_config_file("lua.swg"); - - /* Set typemap language */ - SWIG_typemap_lang("lua"); - - /* Enable overloaded methods support */ - allow_overloading(); - } - - - - - /* NEW LANGUAGE NOTE:*********************************************** - After calling main, SWIG parses the code to wrap (I believe) - then calls top() - in this is more boilerplate code to set everything up - and a call to Language::top() - which begins the code generations by calling the member fns - after all that is more boilerplate code to close all down - (overall there is virtually nothing here that needs to be edited - just use as is) - NEW LANGUAGE NOTE:END *********************************************** */ - /* --------------------------------------------------------------------- - * top() - * --------------------------------------------------------------------- */ - - virtual int top(Node *n) { - /* Get the module name */ - module = Getattr(n, "name"); - - /* Get the output file name */ - String *outfile = Getattr(n, "outfile"); - - /* Open the output file */ - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - f_wrappers = NewString(""); - f_initbeforefunc = NewString(""); - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", f_init); - Swig_register_filebyname("initbeforefunc", f_initbeforefunc); - - - s_luacode = NewString(""); - Swig_register_filebyname("luacode", s_luacode); - - current[NO_CPP] = true; - - /* Standard stuff for the SWIG runtime section */ - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "LUA"); - - emitLuaFlavor(f_runtime); - - if (nomoduleglobal) { - Printf(f_runtime, "#define SWIG_LUA_NO_MODULE_GLOBAL\n"); - } else { - Printf(f_runtime, "#define SWIG_LUA_MODULE_GLOBAL\n"); - } - if (squash_bases) - Printf(f_runtime, "#define SWIG_LUA_SQUASH_BASES\n"); - - // if (NoInclude) { - // Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); - // } - - Printf(f_runtime, "\n"); - - //String *init_name = NewStringf("%(title)s_Init", module); - //Printf(f_header, "#define SWIG_init %s\n", init_name); - //Printf(f_header, "#define SWIG_name \"%s\"\n", module); - /* SWIG_import is a special function name for importing within Lua5.1 */ - //Printf(f_header, "#define SWIG_import luaopen_%s\n\n", module); - Printf(f_header, "#define SWIG_name \"%s\"\n", module); - Printf(f_header, "#define SWIG_init luaopen_%s\n", module); - Printf(f_header, "#define SWIG_init_user luaopen_%s_user\n\n", module); - Printf(f_header, "#define SWIG_LUACODE luaopen_%s_luacode\n", module); - - Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); - - /* %init code inclusion, effectively in the SWIG_init function */ - Printf(f_init, "void SWIG_init_user(lua_State* L)\n{\n"); - Language::top(n); - Printf(f_init, "/* exec Lua code if applicable */\nSWIG_Lua_dostring(L,SWIG_LUACODE);\n"); - Printf(f_init, "}\n"); - - // Done. Close up the module & write to the wrappers - closeNamespaces(f_wrappers); - Printf(f_wrappers, "#ifdef __cplusplus\n}\n#endif\n"); - - SwigType_emit_type_table(f_runtime, f_wrappers); - - /* NEW LANGUAGE NOTE:*********************************************** - this basically combines several of the strings together - and then writes it all to a file - NEW LANGUAGE NOTE:END *********************************************** */ - Dump(f_runtime, f_begin); - Dump(f_header, f_begin); - Dump(f_wrappers, f_begin); - Dump(f_initbeforefunc, f_begin); - /* for the Lua code it needs to be properly escaped to be added into the C/C++ code */ - escapeCode(s_luacode); - Printf(f_begin, "const char* SWIG_LUACODE=\n \"%s\";\n\n", s_luacode); - Wrapper_pretty_print(f_init, f_begin); - /* Close all of the files */ - Delete(s_luacode); - Delete(f_header); - Delete(f_wrappers); - Delete(f_init); - Delete(f_initbeforefunc); - Delete(f_runtime); - Delete(f_begin); - - /* Done */ - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * importDirective() - * ------------------------------------------------------------ */ - - virtual int importDirective(Node *n) { - return Language::importDirective(n); - } - - /* ------------------------------------------------------------ - * cDeclaration() - * It copies sym:name to lua:name to preserve its original value - * ------------------------------------------------------------ */ - - virtual int cDeclaration(Node *n) { - // class 'Language' is messing with symname in a really heavy way. - // Although documentation states that sym:name is a name in - // the target language space, it is not true. sym:name and - // its derivatives are used in various places, including - // behind-the-scene C code generation. The best way is not to - // touch it at all. - // But we need to know what was the name of function/variable - // etc that user desired, that's why we store correct symname - // as lua:name - String *symname = Getattr(n, "sym:name"); - if (symname) - Setattr(n, "lua:name", symname); - return Language::cDeclaration(n); - } - virtual int constructorDeclaration(Node *n) { - Setattr(n, "lua:name", Getattr(n, "sym:name")); - return Language::constructorDeclaration(n); - } - virtual int destructorDeclaration(Node *n) { - Setattr(n, "lua:name", Getattr(n, "sym:name")); - return Language::destructorDeclaration(n); - } - /* NEW LANGUAGE NOTE:*********************************************** - This is it! - you get this one right, and most of your work is done - but it's going to take some file to get it working right - quite a bit of this is generally boilerplate code - (or stuff I don't understand) - that which matters will have extra added comments - NEW LANGUAGE NOTE:END *********************************************** */ - /* --------------------------------------------------------------------- - * functionWrapper() - * - * Create a function declaration and register it with the interpreter. - * --------------------------------------------------------------------- */ - - /* ----------------------------------------------------------------------- - * registerMethod() - * - * Determines wrap name of a method, its scope etc and calls - * registerMethod overload with correct arguments - * Overloaded variant adds method to the "methods" array of specified lua scope/class - * ---------------------------------------------------------------------- */ - - void registerMethod(Node *n, bool overwrite = false, String *overwriteLuaScope = 0) { - String *symname = Getattr(n, "sym:name"); - assert(symname); - - if (Getattr(n, "sym:nextSibling")) - return; - - // Lua scope. It is not symbol NSpace, it is the actual key to retrieve getCArraysHash. - String *luaScope = luaCurrentSymbolNSpace(); - if (overwrite) - luaScope = overwriteLuaScope; - - String *wrapname = 0; - String *mrename; - if (current[NO_CPP] || !getCurrentClass()) { - mrename = symname; - } else { - assert(!current[NO_CPP]); - if (current[STATIC_FUNC] || current[MEMBER_FUNC]) { - mrename = Swig_name_member(getNSpace(), getClassPrefix(), symname); - } else { - mrename = symname; - } - } - wrapname = Swig_name_wrapper(mrename); - registerMethod(n, wrapname, luaScope); - } - - /* ----------------------------------------------------------------------- - * registerMethod() - * - * Add method to the "methods" C array of given namespace/class - * ---------------------------------------------------------------------- */ - - void registerMethod(Node *n, String* wname, String *luaScope) { - assert(n); - Hash *nspaceHash = getCArraysHash(luaScope); - String *s_ns_methods_tab = Getattr(nspaceHash, "methods"); - String *lua_name = Getattr(n, "lua:name"); - if (elua_ltr || eluac_ltr) - Printv(s_ns_methods_tab, tab4, "{LSTRKEY(\"", lua_name, "\")", ", LFUNCVAL(", wname, ")", "},\n", NIL); - else - Printv(s_ns_methods_tab, tab4, "{ \"", lua_name, "\", ", wname, "},\n", NIL); - // Add to the metatable if method starts with '__' - const char * tn = Char(lua_name); - if (tn[0]=='_' && tn[1] == '_' && !eluac_ltr) { - String *metatable_tab = Getattr(nspaceHash, "metatable"); - assert(metatable_tab); - if (elua_ltr) - Printv(metatable_tab, tab4, "{LSTRKEY(\"", lua_name, "\")", ", LFUNCVAL(", wname, ")", "},\n", NIL); - else - Printv(metatable_tab, tab4, "{ \"", lua_name, "\", ", wname, "},\n", NIL); - } - } - - virtual int functionWrapper(Node *n) { - REPORT("functionWrapper", n); - - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - String *lua_name = Getattr(n, "lua:name"); - assert(lua_name); - SwigType *d = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - Parm *p; - String *tm; - int i; - //Printf(stdout,"functionWrapper %s %s %d\n",name,iname,current); - - String *overname = 0; - if (Getattr(n, "sym:overloaded")) { - overname = Getattr(n, "sym:overname"); - } else { - if (!luaAddSymbol(lua_name, n)) { - return SWIG_ERROR; - } - } - - /* NEW LANGUAGE NOTE:*********************************************** - the wrapper object holds all the wrapper code - we need to add a couple of local variables - NEW LANGUAGE NOTE:END *********************************************** */ - Wrapper *f = NewWrapper(); - Wrapper_add_local(f, "SWIG_arg", "int SWIG_arg = 0"); - - - String *wname = Swig_name_wrapper(iname); - if (overname) { - Append(wname, overname); - } - if (current[CONSTRUCTOR]) { - if (constructor_name != 0) - Delete(constructor_name); - constructor_name = Copy(wname); - } - - /* NEW LANGUAGE NOTE:*********************************************** - the format of a lua fn is: - static int wrap_XXX(lua_State* L){...} - this line adds this into the wrapper code - NEW LANGUAGE NOTE:END *********************************************** */ - Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL); - // SWIG_fail in lua leads to a call to lua_error() which calls longjmp() - // which means the destructors of any live function-local C++ objects won't - // get run. To avoid this happening, we wrap almost everything in the - // function in a block, and end that right before lua_error() at which - // point those destructors will get called. - if (CPlusPlus) Append(f->def, "\n{"); - - /* NEW LANGUAGE NOTE:*********************************************** - this prints the list of args, eg for a C fn - int gcd(int x,int y); - it will print - int arg1; - int arg2; - NEW LANGUAGE NOTE:END *********************************************** */ - /* Write code to extract function parameters. */ - emit_parameter_variables(l, f); - - /* Attach the standard typemaps */ - emit_attach_parmmaps(l, f); - Setattr(n, "wrap:parms", l); - - /* Get number of required and total arguments */ - int num_arguments = emit_num_arguments(l); - int num_required = emit_num_required(l); - int varargs = emit_isvarargs(l); - - // Check if we have to ignore arguments that are passed by LUA. - // Needed for unary minus, where lua passes two arguments and - // we have to ignore the second. - - int args_to_ignore = 0; - if (Getattr(n, "lua:ignore_args")) { - args_to_ignore = GetInt(n, "lua:ignore_args"); - } - - - /* NEW LANGUAGE NOTE:*********************************************** - from here on in, it gets rather hairy - this is the code to convert from the scripting language to C/C++ - some of the stuff will refer to the typemaps code written in your swig file - (lua.swg), and some is done in the code here - I suppose you could do all the conversion in C, but it would be a nightmare to do - NEW LANGUAGE NOTE:END *********************************************** */ - /* Generate code for argument marshalling */ - // String *description = NewString(""); - /* NEW LANGUAGE NOTE:*********************************************** - argument_check is a new feature I added to check types of arguments: - eg for int gcd(int,int) - I want to check that arg1 & arg2 really are integers - NEW LANGUAGE NOTE:END *********************************************** */ - String *argument_check = NewString(""); - String *argument_parse = NewString(""); - String *checkfn = NULL; - char source[64]; - Printf(argument_check, "SWIG_check_num_args(\"%s\",%d,%d)\n", Swig_name_str(n), num_required + args_to_ignore, num_arguments + args_to_ignore); - - for (i = 0, p = l; i < num_arguments; i++) { - - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - /* Look for an input typemap */ - sprintf(source, "%d", i + 1); - if ((tm = Getattr(p, "tmap:in"))) { - Replaceall(tm, "$input", source); - Setattr(p, "emit:input", source); - if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - /* NEW LANGUAGE NOTE:*********************************************** - look for a 'checkfn' typemap - this an additional parameter added to the in typemap - if found the type will be tested for - this will result in code either in the - argument_check or argument_parse string - NEW LANGUAGE NOTE:END *********************************************** */ - if ((checkfn = Getattr(p, "tmap:in:checkfn"))) { - if (i < num_required) { - Printf(argument_check, "if(!%s(L,%s))", checkfn, source); - } else { - Printf(argument_check, "if(lua_gettop(L)>=%s && !%s(L,%s))", source, checkfn, source); - } - Printf(argument_check, " SWIG_fail_arg(\"%s\",%s,\"%s\");\n", Swig_name_str(n), source, SwigType_str(pt, 0)); - } - /* NEW LANGUAGE NOTE:*********************************************** - lua states the number of arguments passed to a function using the fn - lua_gettop() - we can use this to deal with default arguments - NEW LANGUAGE NOTE:END *********************************************** */ - if (i < num_required) { - Printf(argument_parse, "%s\n", tm); - } else { - Printf(argument_parse, "if(lua_gettop(L)>=%s){%s}\n", source, tm); - } - p = Getattr(p, "tmap:in:next"); - continue; - } else { - /* NEW LANGUAGE NOTE:*********************************************** - // why is this code not called when I don't have a typemap? - // instead of giving a warning, no code is generated - NEW LANGUAGE NOTE:END *********************************************** */ - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); - break; - } - } - - // add all argcheck code - Printv(f->code, argument_check, argument_parse, NIL); - - /* Check for trailing varargs */ - if (varargs) { - if (p && (tm = Getattr(p, "tmap:in"))) { - Replaceall(tm, "$input", "varargs"); - Printv(f->code, tm, "\n", NIL); - } - } - - /* Insert constraint checking code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert cleanup code */ - String *cleanup = NewString(""); - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:freearg"))) { - Printv(cleanup, tm, "\n", NIL); - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert argument output code */ - String *outarg = NewString(""); - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - // // managing the number of returning variables - // if (numoutputs=Getattr(p,"tmap:argout:numoutputs")){ - // int i=GetInt(p,"tmap:argout:numoutputs"); - // printf("got argout:numoutputs of %d\n",i); - // returnval+=GetInt(p,"tmap:argout:numoutputs"); - // } - // else returnval++; - Replaceall(tm, "$arg", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - // Remember C name of the wrapping function - Setattr(n, "wrap:name", wname); - - /* Emit the function call */ - String *actioncode = emit_action(n); - - /* NEW LANGUAGE NOTE:*********************************************** - FIXME: - returns 1 if there is a void return type - this is because there is a typemap for void - NEW LANGUAGE NOTE:END *********************************************** */ - // Return value if necessary - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { - // managing the number of returning variables - // if (numoutputs=Getattr(tm,"numoutputs")){ - // int i=GetInt(tm,"numoutputs"); - // printf("return numoutputs %d\n",i); - // returnval+=GetInt(tm,"numoutputs"); - // } - // else returnval++; - if (GetFlag(n, "feature:new")) { - Replaceall(tm, "$owner", "1"); - } else { - Replaceall(tm, "$owner", "0"); - } - Printf(f->code, "%s\n", tm); - // returnval++; - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name); - } - emit_return_variable(n, d, f); - - /* Output argument output code */ - Printv(f->code, outarg, NIL); - - /* Output cleanup code */ - Printv(f->code, cleanup, NIL); - - /* Look to see if there is any newfree cleanup code */ - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - } - } - - /* See if there is any return cleanup code */ - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - } - - - /* Close the function */ - Printv(f->code, "return SWIG_arg;\n", NIL); - // add the failure cleanup code: - Printv(f->code, "\nfail: SWIGUNUSED;\n", "$cleanup", NIL); - if (CPlusPlus) Append(f->code, "}\n"); - Printv(f->code, "lua_error(L);\n", NIL); - // lua_error() calls longjmp() but we need a dummy return to avoid compiler - // warnings. - Printv(f->code, "return 0;\n", NIL); - Printf(f->code, "}\n"); - - /* Substitute the cleanup code */ - Replaceall(f->code, "$cleanup", cleanup); - - /* Substitute the function name */ - Replaceall(f->code, "$symname", iname); - Replaceall(f->code, "$result", Swig_cresult_name()); - - /* Dump the function out */ - /* in Lua we will not emit the destructor as a wrapper function, - Lua will automatically call the destructor when the object is free'd - However: you cannot just skip this function as it will not emit - any custom destructor (using %extend), as you need to call emit_action() - Therefore we go though the whole function, - but do not write the code into the wrapper - */ - if (!current[DESTRUCTOR]) { - Wrapper_print(f, f_wrappers); - } - - /* NEW LANGUAGE NOTE:*********************************************** - register the function in SWIG - different language mappings seem to use different ideas - NEW LANGUAGE NOTE:END *********************************************** */ - /* Now register the function with the interpreter. */ - int result = SWIG_OK; - if (Getattr(n, "sym:overloaded")) { - if (!Getattr(n, "sym:nextSibling")) { - result = dispatchFunction(n); - } - } - - Delete(argument_check); - Delete(argument_parse); - - Delete(cleanup); - Delete(outarg); - // Delete(description); - DelWrapper(f); - - return result; - } - - /* ------------------------------------------------------------ - * dispatchFunction() - * - * Emit overloading dispatch function - * ------------------------------------------------------------ */ - - /* NEW LANGUAGE NOTE:*********************************************** - This is an extra function used for overloading of functions - it checks the args & then calls the relevant fn - most of the real work in again typemaps: - look for %typecheck(SWIG_TYPECHECK_*) in the .swg file - NEW LANGUAGE NOTE:END *********************************************** */ - int dispatchFunction(Node *n) { - //REPORT("dispatchFunction", n); - /* Last node in overloaded chain */ - - int maxargs; - String *tmp = NewString(""); - String *dispatch = Swig_overload_dispatch(n, "return %s(L);", &maxargs); - - /* Generate a dispatch wrapper for all overloaded functions */ - - Wrapper *f = NewWrapper(); - String *symname = Getattr(n, "sym:name"); - String *lua_name = Getattr(n, "lua:name"); - assert(lua_name); - String *wname = Swig_name_wrapper(symname); - - //Printf(stdout,"Swig_overload_dispatch %s %s '%s' %d\n",symname,wname,dispatch,maxargs); - - if (!luaAddSymbol(lua_name, n)) { - DelWrapper(f); - Delete(dispatch); - Delete(tmp); - return SWIG_ERROR; - } - - Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL); - Wrapper_add_local(f, "argc", "int argc"); - Printf(tmp, "int argv[%d]={1", maxargs + 1); - for (int i = 1; i <= maxargs; i++) { - Printf(tmp, ",%d", i + 1); - } - Printf(tmp, "}"); - Wrapper_add_local(f, "argv", tmp); - Printf(f->code, "argc = lua_gettop(L);\n"); - - Replaceall(dispatch, "$args", "self,args"); - Printv(f->code, dispatch, "\n", NIL); - - Node *sibl = n; - while (Getattr(sibl, "sym:previousSibling")) - sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up - String *protoTypes = NewString(""); - do { - String *fulldecl = Swig_name_decl(sibl); - Printf(protoTypes, "\n\" %s\\n\"", fulldecl); - Delete(fulldecl); - } while ((sibl = Getattr(sibl, "sym:nextSibling"))); - Printf(f->code, "SWIG_Lua_pusherrstring(L,\"Wrong arguments for overloaded function '%s'\\n\"\n" - "\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes); - Delete(protoTypes); - - Printf(f->code, "lua_error(L);return 0;\n"); - Printv(f->code, "}\n", NIL); - Wrapper_print(f, f_wrappers); - - // Remember C name of the wrapping function - Setattr(n, "wrap:name", wname); - - if (current[CONSTRUCTOR]) { - if (constructor_name != 0) - Delete(constructor_name); - constructor_name = Copy(wname); - } - - DelWrapper(f); - Delete(dispatch); - Delete(tmp); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * Add variable to "attributes" C arrays of given namespace or class. - * Input is node. Based on the state of "current" array it determines - * the name of the getter function, setter function etc and calls - * registerVariable overload with necessary params. - * Lua scope could be overwritten. (Used only for backward compatibility) - * ------------------------------------------------------------ */ - - void registerVariable(Node *n, bool overwrite = false, String *overwriteLuaScope = 0) { - int assignable = is_assignable(n); - String *symname = Getattr(n, "sym:name"); - assert(symname); - - // Lua scope. It is not symbol NSpace, it is the actual key to retrieve getCArraysHash. - String *luaScope = luaCurrentSymbolNSpace(); - if (overwrite) - luaScope = overwriteLuaScope; - - // Getter and setter - String *getName = 0; - String *setName = 0; - String *mrename = 0; - if (current[NO_CPP] || !getCurrentClass()) { - // Global variable - getName = Swig_name_get(getNSpace(), symname); - if (assignable) - setName = Swig_name_set(getNSpace(), symname); - } else { - assert(!current[NO_CPP]); - if (current[STATIC_VAR] ) { - mrename = Swig_name_member(getNSpace(), getClassPrefix(), symname); - getName = Swig_name_get(0, mrename); - if (assignable) - setName = Swig_name_set(0, mrename); - } else if (current[MEMBER_VAR]) { - mrename = Swig_name_member(0, getClassPrefix(), symname); - getName = Swig_name_get(getNSpace(), mrename); - if (assignable) - setName = Swig_name_set(getNSpace(), mrename); - } else { - assert(false); - } - } - - getName = Swig_name_wrapper(getName); - if (setName) - setName = Swig_name_wrapper(setName); - registerVariable(luaScope, n, getName, setName); - } - - /* ------------------------------------------------------------ - * registerVariable() - * - * Add variable to the "attributes" (or "get"/"set" in - * case of elua_ltr) C arrays of given namespace or class - * ------------------------------------------------------------ */ - - void registerVariable(String *lua_nspace_or_class_name, Node *n, String *getName, String *setName) { - String *unassignable = NewString("SWIG_Lua_set_immutable"); - if (setName == 0 || GetFlag(n, "feature:immutable")) { - setName = unassignable; - } - Hash *nspaceHash = getCArraysHash(lua_nspace_or_class_name); - String *s_ns_methods_tab = Getattr(nspaceHash, "methods"); - String *s_ns_var_tab = Getattr(nspaceHash, "attributes"); - String *lua_name = Getattr(n, "lua:name"); - if (elua_ltr) { - String *s_ns_dot_get = Getattr(nspaceHash, "get"); - String *s_ns_dot_set = Getattr(nspaceHash, "set"); - Printf(s_ns_dot_get, "%s{LSTRKEY(\"%s\"), LFUNCVAL(%s)},\n", tab4, lua_name, getName); - Printf(s_ns_dot_set, "%s{LSTRKEY(\"%s\"), LFUNCVAL(%s)},\n", tab4, lua_name, setName); - } else if (eluac_ltr) { - Printv(s_ns_methods_tab, tab4, "{LSTRKEY(\"", lua_name, "_get", "\")", ", LFUNCVAL(", getName, ")", "},\n", NIL); - Printv(s_ns_methods_tab, tab4, "{LSTRKEY(\"", lua_name, "_set", "\")", ", LFUNCVAL(", setName, ")", "},\n", NIL); - } else { - Printf(s_ns_var_tab, "%s{ \"%s\", %s, %s },\n", tab4, lua_name, getName, setName); - } - } - - /* ------------------------------------------------------------ - * variableWrapper() - * ------------------------------------------------------------ */ - - virtual int variableWrapper(Node *n) { - /* NEW LANGUAGE NOTE:*********************************************** - Language::variableWrapper(n) will generate two wrapper fns - Foo_get & Foo_set by calling functionWrapper() - so we will just add these into the variable lists - ideally we should not have registered these as functions, - only WRT this variable will look into this later. - NEW LANGUAGE NOTE:END *********************************************** */ - // REPORT("variableWrapper", n); - String *lua_name = Getattr(n, "lua:name"); - assert(lua_name); - (void)lua_name; - current[VARIABLE] = true; - // let SWIG generate the wrappers - int result = Language::variableWrapper(n); - - // It is impossible to use registerVariable, because sym:name of the Node is currently - // in an undefined state - the callees of this function may have modified it. - // registerVariable should be used from respective callees.* - current[VARIABLE] = false; - return result; - } - - - /* ------------------------------------------------------------ - * Add constant to appropriate C array. constantRecord is an array record. - * Actually, in current implementation it is resolved consttab typemap - * ------------------------------------------------------------ */ - - void registerConstant(String *nspace, String *constantRecord) { - Hash *nspaceHash = getCArraysHash(nspace); - String *s_const_tab = 0; - if (eluac_ltr || elua_ltr) - // In elua everything goes to "methods" tab - s_const_tab = Getattr(nspaceHash, "methods"); - else - s_const_tab = Getattr(nspaceHash, "constants"); - - assert(s_const_tab); - Printf(s_const_tab, " %s,\n", constantRecord); - - if ((eluac_ltr || elua_ltr) && old_metatable_bindings) { - s_const_tab = Getattr(nspaceHash, "constants"); - assert(s_const_tab); - Printf(s_const_tab, " %s,\n", constantRecord); - } - - } - - /* ------------------------------------------------------------ - * constantWrapper() - * ------------------------------------------------------------ */ - - virtual int constantWrapper(Node *n) { - REPORT("constantWrapper", n); - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - String *lua_name = Getattr(n, "lua:name"); - if (lua_name == 0) - lua_name = iname; - String *nsname = Copy(iname); - SwigType *type = Getattr(n, "type"); - String *rawval = Getattr(n, "rawval"); - String *value = rawval ? rawval : Getattr(n, "value"); - String *tm; - String *lua_name_v2 = 0; - String *tm_v2 = 0; - String *iname_v2 = 0; - Node *n_v2 = 0; - - if (!luaAddSymbol(lua_name, n)) - return SWIG_ERROR; - - Swig_save("lua_constantMember", n, "sym:name", NIL); - Setattr(n, "sym:name", lua_name); - /* Special hook for member pointer */ - if (SwigType_type(type) == T_MPOINTER) { - String *wname = Swig_name_wrapper(iname); - Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type, wname), value); - value = Char(wname); - } - - if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) { - Replaceall(tm, "$value", value); - Replaceall(tm, "$nsname", nsname); - registerConstant(luaCurrentSymbolNSpace(), tm); - } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) { - Replaceall(tm, "$value", value); - Replaceall(tm, "$nsname", nsname); - Printf(f_init, "%s\n", tm); - } else { - Delete(nsname); - nsname = 0; - Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); - Swig_restore(n); - return SWIG_NOWRAP; - } - - bool make_v2_compatible = old_metatable_bindings && getCurrentClass() && old_compatible_names; - - if (make_v2_compatible) { - // Don't do anything for enums in C mode - they are already - // wrapped correctly - if (CPlusPlus || !current[ENUM_CONST]) { - lua_name_v2 = Swig_name_member(0, proxy_class_name, lua_name); - iname_v2 = Swig_name_member(0, proxy_class_name, iname); - n_v2 = Copy(n); - if (!luaAddSymbol(iname_v2, n, getNSpace())) { - Swig_restore(n); - return SWIG_ERROR; - } - - Setattr(n_v2, "sym:name", lua_name_v2); - tm_v2 = Swig_typemap_lookup("consttab", n_v2, name, 0); - if (tm_v2) { - Replaceall(tm_v2, "$value", value); - Replaceall(tm_v2, "$nsname", nsname); - registerConstant(getNSpace(), tm_v2); - } else { - tm_v2 = Swig_typemap_lookup("constcode", n_v2, name, 0); - if (!tm_v2) { - // This can't be. - assert(false); - Swig_restore(n); - return SWIG_ERROR; - } - Replaceall(tm_v2, "$value", value); - Replaceall(tm_v2, "$nsname", nsname); - Printf(f_init, "%s\n", tm_v2); - } - Delete(n_v2); - } - } - - Swig_restore(n); - Delete(nsname); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * nativeWrapper() - * ------------------------------------------------------------ */ - - virtual int nativeWrapper(Node *n) { - // REPORT("nativeWrapper", n); - String *symname = Getattr(n, "sym:name"); - String *wrapname = Getattr(n, "wrap:name"); - if (!luaAddSymbol(wrapname, n)) - return SWIG_ERROR; - - Hash *nspaceHash = getCArraysHash(getNSpace()); - String *s_ns_methods_tab = Getattr(nspaceHash, "methods"); - Printv(s_ns_methods_tab, tab4, "{ \"", symname, "\",", wrapname, "},\n", NIL); - // return Language::nativeWrapper(n); // this does nothing... - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * enumDeclaration() - * ------------------------------------------------------------ */ - - virtual int enumDeclaration(Node *n) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - current[STATIC_CONST] = true; - current[ENUM_CONST] = true; - // There is some slightly specific behaviour with enums. Basically, - // their NSpace may be tracked separately. The code below tries to work around - // this issue to some degree. - // The idea is the same as in classHandler - to drop old names generation if - // enum is in class in namespace. - const int old_compatible_names_saved = old_compatible_names; - if (getNSpace() || ( Getattr(n, "sym:nspace") != 0 && Len(Getattr(n, "sym:nspace")) > 0 ) ) { - old_compatible_names = 0; - } - int result = Language::enumDeclaration(n); - current[STATIC_CONST] = false; - current[ENUM_CONST] = false; - old_compatible_names = old_compatible_names_saved; - return result; - } - - /* ------------------------------------------------------------ - * enumvalueDeclaration() - * ------------------------------------------------------------ */ - - virtual int enumvalueDeclaration(Node *n) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - Swig_require("enumvalueDeclaration", n, "*name", "?value", "*sym:name", NIL); - String *symname = Getattr(n, "sym:name"); - String *value = Getattr(n, "value"); - String *name = Getattr(n, "name"); - String *tmpValue; - Node *parent = parentNode(n); - - if (value) - tmpValue = NewString(value); - else - tmpValue = NewString(name); - Setattr(n, "value", tmpValue); - - Setattr(n, "name", tmpValue); /* for wrapping of enums in a namespace when emit_action is used */ - - if (GetFlag(parent, "scopedenum")) { - symname = Swig_name_member(0, Getattr(parent, "sym:name"), symname); - Setattr(n, "sym:name", symname); - Delete(symname); - } - - int result = constantWrapper(n); - - Delete(tmpValue); - Swig_restore(n); - return result; - } - - /* ------------------------------------------------------------ - * classDeclaration() - * ------------------------------------------------------------ */ - - virtual int classDeclaration(Node *n) { - return Language::classDeclaration(n); - } - - - /* ------------------------------------------------------------ - * Helper function that adds record to appropriate C arrays - * ------------------------------------------------------------ */ - - void registerClass(String *scope, String *wrap_class) { - assert(wrap_class); - Hash *nspaceHash = getCArraysHash(scope); - String *ns_classes = Getattr(nspaceHash, "classes"); - Printv(ns_classes, "&", wrap_class, ",\n", NIL); - if (elua_ltr || eluac_ltr) { - String *ns_methods = Getattr(nspaceHash, "methods"); - Hash *class_hash = getCArraysHash(class_static_nspace); - assert(class_hash); - String *cls_methods = Getattr(class_hash, "methods:name"); - assert(cls_methods); - Printv(ns_methods, tab4, "{LSTRKEY(\"", proxy_class_name, "\")", ", LROVAL(", cls_methods, ")", "},\n", NIL); - } - } - - /* ------------------------------------------------------------ - * classHandler() - * ------------------------------------------------------------ */ - - virtual int classHandler(Node *n) { - //REPORT("classHandler", n); - - String *mangled_full_proxy_class_name = 0; - String *destructor_name = 0; - String *nspace = getNSpace(); - - constructor_name = 0; - have_constructor = 0; - have_destructor = 0; - destructor_action = 0; - assert(class_static_nspace == 0); - assert(full_proxy_class_name == 0); - assert(proxy_class_name == 0); - - current[NO_CPP] = false; - - proxy_class_name = Getattr(n, "sym:name"); - // We have to enforce nspace here, because technically we are already - // inside class parsing (getCurrentClass != 0), but we should register - // class in its parent namespace - if (!luaAddSymbol(proxy_class_name, n, nspace)) - return SWIG_ERROR; - - if (nspace == 0) - full_proxy_class_name = NewStringf("%s", proxy_class_name); - else - full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name); - - assert(full_proxy_class_name); - mangled_full_proxy_class_name = Swig_name_mangle(full_proxy_class_name); - - SwigType *t = Copy(Getattr(n, "name")); - SwigType *fr_t = SwigType_typedef_resolve_all(t); /* Create fully resolved type */ - SwigType *t_tmp = 0; - t_tmp = SwigType_typedef_qualified(fr_t); // Temporal variable - Delete(fr_t); - fr_t = SwigType_strip_qualifiers(t_tmp); - String *mangled_fr_t = 0; - mangled_fr_t = SwigType_manglestr(fr_t); - // not sure exactly how this works, - // but tcl has a static hashtable of all classes emitted and then only emits code for them once. - // this fixes issues in test suites: template_default2 & template_specialization - - // * if i understand correctly, this is a bug. - // * consider effect on template_specialization_defarg - - static Hash *emitted = NewHash(); - if (GetFlag(emitted, mangled_fr_t)) { - full_proxy_class_name = 0; - proxy_class_name = 0; - return SWIG_NOWRAP; - } - SetFlag(emitted, mangled_fr_t); - - // We treat class T as both 'class' and 'namespace'. All static members, attributes - // and constants are considered part of namespace T, all members - part of the 'class' - // Now, here is a trick. Static methods, attributes and non-static methods and attributes - // are described with same structures - swig_lua_attribute/swig_lua_method. Instead of calling - // getCArraysHash(class name) to initialize things for static methods/attributes and then - // manually doing same initialization for non-static methods, we call getCArraysHash 2 times: - // 1) With name "class name" + "." + "SwigStatic" to initialize static things - // 2) With "class name" to initialize non-static things - Hash *instance_cls = getCArraysHash(full_proxy_class_name, false); - assert(instance_cls); - String *s_attr_tab_name = Getattr(instance_cls, "attributes:name"); - String *s_methods_tab_name = Getattr(instance_cls, "methods:name"); - SetFlag(instance_cls, "lua:no_namespaces"); - SetFlag(instance_cls, "lua:no_classes"); - SetFlag(instance_cls, "lua:class_instance"); - - /* There is no use for "constants", "classes" and "namespaces" arrays. - * All constants are considered part of static part of class. - */ - - class_static_nspace = NewStringf("%s%sSwigStatic", full_proxy_class_name, NSPACE_SEPARATOR); - Hash *static_cls = getCArraysHash(class_static_nspace, false); - assert(static_cls); - SetFlag(static_cls, "lua:no_namespaces"); - SetFlag(static_cls, "lua:class_static"); - - // Notifying instance_cls and static_cls hashes about each other - Setattr(instance_cls, "lua:class_instance:static_hash", static_cls); - Setattr(static_cls, "lua:class_static:instance_hash", instance_cls); - - const int old_compatible_names_saved = old_compatible_names; - // If class has %nspace enabled, then generation of backward compatible names - // should be disabled - if (getNSpace()) { - old_compatible_names = 0; - } - - /* There is no use for "classes" and "namespaces" arrays. Subclasses are not supported - * by SWIG and namespaces couldn't be nested inside classes (C++ Standard) - */ - // Generate normal wrappers - Language::classHandler(n); - - old_compatible_names = old_compatible_names_saved; - - SwigType_add_pointer(t); - - // Catch all: eg. a class with only static functions and/or variables will not have 'remembered' - String *wrap_class_name = Swig_name_wrapper(NewStringf("class_%s", mangled_full_proxy_class_name)); - String *wrap_class = NewStringf("&%s", wrap_class_name); - SwigType_remember_clientdata(t, wrap_class); - - String *rt = Copy(getClassType()); - SwigType_add_pointer(rt); - - // Adding class to appropriate namespace - registerClass(nspace, wrap_class_name); - Hash *nspaceHash = getCArraysHash(nspace); - - // Register the class structure with the type checker - // Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_full_proxy_class_name); - - // emit a function to be called to delete the object - if (have_destructor) { - destructor_name = NewStringf("swig_delete_%s", mangled_full_proxy_class_name); - Printv(f_wrappers, "static void ", destructor_name, "(void *obj) {\n", NIL); - if (destructor_action) { - Printv(f_wrappers, SwigType_str(rt, "arg1"), " = (", SwigType_str(rt, 0), ") obj;\n", NIL); - Printv(f_wrappers, destructor_action, "\n", NIL); - } else { - if (CPlusPlus) { - Printv(f_wrappers, " delete (", SwigType_str(rt, 0), ") obj;\n", NIL); - } else { - Printv(f_wrappers, " free((char *) obj);\n", NIL); - } - } - Printf(f_wrappers, "}\n"); - } - // Wrap constructor wrapper into one more proxy function. It will be used as class namespace __call method, thus - // allowing both - // Module.ClassName.StaticMethod to access static method/variable/constant - // Module.ClassName() to create new object - if (have_constructor) { - assert(constructor_name); - String *constructor_proxy_name = NewStringf("_proxy_%s", constructor_name); - Printv(f_wrappers, "static int ", constructor_proxy_name, "(lua_State *L) {\n", NIL); - Printv(f_wrappers, - tab4, "assert(lua_istable(L,1));\n", - tab4, "lua_pushcfunction(L,", constructor_name, ");\n", - tab4, "assert(!lua_isnil(L,-1));\n", - tab4, "lua_replace(L,1); /* replace our table with real constructor */\n", - tab4, "lua_call(L,lua_gettop(L)-1,1);\n", - tab4, "return 1;\n}\n", NIL); - Delete(constructor_name); - constructor_name = constructor_proxy_name; - if (elua_ltr) { - String *static_cls_metatable_tab = Getattr(static_cls, "metatable"); - assert(static_cls_metatable_tab); - Printf(static_cls_metatable_tab, " {LSTRKEY(\"__call\"), LFUNCVAL(%s)},\n", constructor_name); - } else if (eluac_ltr) { - String *ns_methods_tab = Getattr(nspaceHash, "methods"); - assert(ns_methods_tab); - Printv(ns_methods_tab, tab4, "{LSTRKEY(\"", "new_", proxy_class_name, "\")", ", LFUNCVAL(", constructor_name, ")", "},\n", NIL); - } - } - if (have_destructor) { - if (eluac_ltr) { - String *ns_methods_tab = Getattr(nspaceHash, "methods"); - assert(ns_methods_tab); - Printv(ns_methods_tab, tab4, "{LSTRKEY(\"", "free_", mangled_full_proxy_class_name, "\")", ", LFUNCVAL(", destructor_name, ")", "},\n", NIL); - } - } - - closeCArraysHash(full_proxy_class_name, f_wrappers); - closeCArraysHash(class_static_nspace, f_wrappers); - - - // Handle inheritance - // note: with the idea of class hierarchies spread over multiple modules - // cf test-suite: imports.i - // it is not possible to just add the pointers to the base classes to the code - // (as sometimes these classes are not present) - // therefore we instead hold the name of the base class and a null pointer - // at runtime: we can query the swig type manager & see if the class exists - // if so, we can get the pointer to the base class & replace the null pointer - // if the type does not exist, then we cannot... - String *base_class = NewString(""); - String *base_class_names = NewString(""); - - List *baselist = Getattr(n, "bases"); - if (baselist && Len(baselist)) { - Iterator b; - b = First(baselist); - while (b.item) { - String *bname = Getattr(b.item, "name"); - if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) { - b = Next(b); - continue; - } - // stores a null pointer & the name - Printf(base_class, "0,"); - Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname)); - - b = Next(b); - } - } - // First, print class static part - printCArraysDefinition(class_static_nspace, proxy_class_name, f_wrappers); - - assert(mangled_full_proxy_class_name); - assert(base_class); - assert(base_class_names); - assert(proxy_class_name); - assert(full_proxy_class_name); - - // Then print class instance part - Printv(f_wrappers, "static swig_lua_class *swig_", mangled_full_proxy_class_name, "_bases[] = {", base_class, "0};\n", NIL); - Delete(base_class); - Printv(f_wrappers, "static const char *swig_", mangled_full_proxy_class_name, "_base_names[] = {", base_class_names, "0};\n", NIL); - Delete(base_class_names); - - Printv(f_wrappers, "static swig_lua_class _wrap_class_", mangled_full_proxy_class_name, " = { \"", proxy_class_name, "\", \"", full_proxy_class_name, "\", &SWIGTYPE", - SwigType_manglestr(t), ",", NIL); - - if (have_constructor) { - Printv(f_wrappers, constructor_name, NIL); - Delete(constructor_name); - constructor_name = 0; - } else { - Printf(f_wrappers, "0"); - } - - if (have_destructor) { - Printv(f_wrappers, ", ", destructor_name, NIL); - } else { - Printf(f_wrappers, ",0"); - } - Printf(f_wrappers, ", %s, %s, &%s", s_methods_tab_name, s_attr_tab_name, Getattr(static_cls, "cname")); - - if (!eluac_ltr) { - Printf(f_wrappers, ", %s", Getattr(instance_cls,"metatable:name")); - } - else - Printf(f_wrappers, ", 0"); - - Printf(f_wrappers, ", swig_%s_bases, swig_%s_base_names };\n\n", mangled_full_proxy_class_name, mangled_full_proxy_class_name); - - current[NO_CPP] = true; - Delete(class_static_nspace); - class_static_nspace = 0; - Delete(mangled_full_proxy_class_name); - mangled_full_proxy_class_name = 0; - Delete(destructor_name); - destructor_name = 0; - Delete(full_proxy_class_name); - full_proxy_class_name = 0; - proxy_class_name = 0; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * memberfunctionHandler() - * ------------------------------------------------------------ */ - - virtual int memberfunctionHandler(Node *n) { - String *symname = GetChar(n, "sym:name"); - //Printf(stdout,"memberfunctionHandler %s %s\n",name,iname); - - // Special case unary minus: LUA passes two parameters for the - // wrapper function while we want only one. Tell our - // functionWrapper to ignore a parameter. - - if (Cmp(symname, "__unm") == 0) { - //Printf(stdout, "unary minus: ignore one argument\n"); - SetInt(n, "lua:ignore_args", 1); - } - - current[MEMBER_FUNC] = true; - Language::memberfunctionHandler(n); - - registerMethod(n); - current[MEMBER_FUNC] = false; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * membervariableHandler() - * ------------------------------------------------------------ */ - - virtual int membervariableHandler(Node *n) { - // REPORT("membervariableHandler",n); - current[MEMBER_VAR] = true; - Language::membervariableHandler(n); - registerVariable(n); - current[MEMBER_VAR] = false; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constructorHandler() - * - * Method for adding C++ member constructor - * ------------------------------------------------------------ */ - - virtual int constructorHandler(Node *n) { - // REPORT("constructorHandler", n); - current[CONSTRUCTOR] = true; - Language::constructorHandler(n); - current[CONSTRUCTOR] = false; - //constructor_name = NewString(Getattr(n, "sym:name")); - have_constructor = 1; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * destructorHandler() - * ------------------------------------------------------------ */ - - virtual int destructorHandler(Node *n) { - REPORT("destructorHandler", n); - current[DESTRUCTOR] = true; - Language::destructorHandler(n); - current[DESTRUCTOR] = false; - have_destructor = 1; - destructor_action = Getattr(n, "wrap:action"); - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * globalfunctionHandler() - * - * It can be called: - * 1. Usual C/C++ global function. - * 2. During class parsing for functions declared/defined as friend - * 3. During class parsing from staticmemberfunctionHandler - * ---------------------------------------------------------------------- */ - - virtual int globalfunctionHandler(Node *n) { - bool oldVal = current[NO_CPP]; - if (!current[STATIC_FUNC]) // If static function, don't switch to NO_CPP - current[NO_CPP] = true; - const int result = Language::globalfunctionHandler(n); - - if (!current[STATIC_FUNC]) // Register only if not called from static function handler - registerMethod(n); - current[NO_CPP] = oldVal; - return result; - } - - /* ---------------------------------------------------------------------- - * globalvariableHandler() - * - * Sets "current" array correctly - * ---------------------------------------------------------------------- */ - - virtual int globalvariableHandler(Node *n) { - bool oldVal = current[NO_CPP]; - current[GLOBAL_VAR] = true; - current[NO_CPP] = true; - - const int result = Language::globalvariableHandler(n); - registerVariable(n); - - current[GLOBAL_VAR] = false; - current[NO_CPP] = oldVal; - return result; - } - - - /* ----------------------------------------------------------------------- - * staticmemberfunctionHandler() - * - * Wrap a static C++ function - * ---------------------------------------------------------------------- */ - - virtual int staticmemberfunctionHandler(Node *n) { - REPORT("staticmemberfunctionHandler", n); - current[STATIC_FUNC] = true; - - const int result = Language::staticmemberfunctionHandler(n); - registerMethod(n); - - if (old_metatable_bindings && result == SWIG_OK && old_compatible_names) { - Swig_require("lua_staticmemberfunctionHandler", n, "*lua:name", NIL); - String *lua_name = Getattr(n, "lua:name"); - // Although this function uses Swig_name_member, it actually generates the Lua name, - // not the C++ name. This is because an earlier version used such a scheme for static function - // name generation and we have to maintain backward compatibility. - String *compat_name = Swig_name_member(0, proxy_class_name, lua_name); - Setattr(n, "lua:name", compat_name); - registerMethod(n, true, getNSpace()); - Delete(compat_name); - Swig_restore(n); - } - - current[STATIC_FUNC] = false;; - return result; - } - - /* ------------------------------------------------------------ - * memberconstantHandler() - * - * Create a C++ constant - * ------------------------------------------------------------ */ - - virtual int memberconstantHandler(Node *n) { - REPORT("memberconstantHandler", n); - int result = Language::memberconstantHandler(n); - - return result; - } - - /* --------------------------------------------------------------------- - * staticmembervariableHandler() - * --------------------------------------------------------------------- */ - - virtual int staticmembervariableHandler(Node *n) { - REPORT("staticmembervariableHandler", n); - current[STATIC_VAR] = true; - //String *symname = Getattr(n, "sym:name"); - int result = Language::staticmembervariableHandler(n); - if (!GetFlag(n, "wrappedasconstant")) { - registerVariable(n); - } - - if (result == SWIG_OK) { - // This will add static member variable to the class namespace with name ClassName_VarName - if (old_metatable_bindings && old_compatible_names) { - Swig_save("lua_staticmembervariableHandler", n, "lua:name", NIL); - String *lua_name = Getattr(n, "lua:name"); - // Although this function uses Swig_name_member, it actually generates the Lua name, - // not the C++ name. This is because an earlier version used such a scheme for static function - // name generation and we have to maintain backward compatibility. - String *v2_name = Swig_name_member(NIL, proxy_class_name, lua_name); - if (!GetFlag(n, "wrappedasconstant")) { - Setattr(n, "lua:name", v2_name); - // Registering static var in the class parent nspace - registerVariable(n, true, getNSpace()); - } - // If static member variable was wrapped as a constant, then - // constant wrapper has already performed all actions necessary for old_metatable_bindings - Delete(v2_name); - Swig_restore(n); - } - } - current[STATIC_VAR] = false; - - return result; - } - - - /* --------------------------------------------------------------------- - * external runtime generation - * --------------------------------------------------------------------- */ - - /* This is to support the usage - SWIG -external-runtime <filename> - The code consists of two functions: - String *runtimeCode() // returns a large string with all the runtimes in - String *defaultExternalRuntimeFilename() // returns the default filename - I am writing a generic solution, even though SWIG-Lua only has one file right now... - */ - String *runtimeCode() { - String *s = NewString(""); - const char *filenames[] = { "luarun.swg", 0 }; // must be 0 terminated - - emitLuaFlavor(s); - - String *sfile = 0; - for (int i = 0; filenames[i] != 0; i++) { - sfile = Swig_include_sys(filenames[i]); - if (!sfile) { - Printf(stderr, "*** Unable to open '%s'\n", filenames[i]); - } else { - Append(s, sfile); - Delete(sfile); - } - } - - return s; - } - - String *defaultExternalRuntimeFilename() { - return NewString("swigluarun.h"); - } - - /* --------------------------------------------------------------------- - * helpers - * --------------------------------------------------------------------- */ - - void emitLuaFlavor(String *s) { - if (elua_emulate) { - Printf(s, "/*This is only emulation!*/\n"); - Printf(s, "#define SWIG_LUA_TARGET SWIG_LUA_FLAVOR_ELUA\n"); - Printf(s, "#define SWIG_LUA_ELUA_EMULATE\n"); - } else if (elua_ltr) - Printf(s, "#define SWIG_LUA_TARGET SWIG_LUA_FLAVOR_ELUA\n"); - else if (eluac_ltr) - Printf(s, "#define SWIG_LUA_TARGET SWIG_LUA_FLAVOR_ELUAC\n"); - else - Printf(s, "#define SWIG_LUA_TARGET SWIG_LUA_FLAVOR_LUA\n"); - } - - - /* ----------------------------------------------------------------------------- - * escapeCode() - * - * This is to convert the string of Lua code into a proper string, which can then be - * emitted into the C/C++ code. - * Basically it is a lot of search & replacing of odd sequences - * ---------------------------------------------------------------------------- */ - - void escapeCode(String *str) { - //Printf(f_runtime,"/* original luacode:[[[\n%s\n]]]\n*/\n",str); - Chop(str); // trim - Replace(str, "\\", "\\\\", DOH_REPLACE_ANY); // \ to \\ (this must be done first) - Replace(str, "\"", "\\\"", DOH_REPLACE_ANY); // " to \" - Replace(str, "\n", "\\n\"\n \"", DOH_REPLACE_ANY); // \n to \n"\n" (ie quoting every line) - //Printf(f_runtime,"/* hacked luacode:[[[\n%s\n]]]\n*/\n",str); - } - - /* ----------------------------------------------------------------------------- - * rawGetCArraysHash(String *name) - * - * A small helper to hide implementation of how CArrays hashes are stored - * ---------------------------------------------------------------------------- */ - - Hash *rawGetCArraysHash(const_String_or_char_ptr name) { - Hash *scope = symbolScopeLookup( name ? name : "" ); - if(!scope) - return 0; - - Hash *carrays_hash = Getattr(scope, "lua:cdata"); - return carrays_hash; - } - - /* ----------------------------------------------------------------------------- - * getCArraysHash() - * - * Each namespace can be described with a hash that stores C arrays - * where members of the namespace should be added. All these hashes are stored - * inside the symbols table, in pseudo-symbol for every namespace. - * nspace could be NULL (NSPACE_TODO), that means functions and variables and classes - * that are not in any namespace (this is default for SWIG unless %nspace feature is used). - * You can later set some attributes that will affect behaviour of functions that use this hash: - * "lua:no_namespaces" will disable "namespaces" array. - * "lua:no_classes" will disable "classes" array. - * For every component ("attributes", "methods", etc) there are subcomponents: - * XXX:name - name of the C array that stores data for component - * XXX:decl - statement with forward declaration of this array; - * Namespace could be automatically registered to its parent if 'reg' == true. This can only be - * done during the first call (a.k.a when nspace is created). - * ---------------------------------------------------------------------------- */ - - Hash *getCArraysHash(String *nspace, bool reg = true) { - Hash *scope = symbolScopeLookup(nspace ? nspace : ""); - if(!scope) { - symbolAddScope( nspace ? nspace : "" ); - scope = symbolScopeLookup(nspace ? nspace : ""); - assert(scope); - } - Hash *carrays_hash = Getattr(scope, "lua:cdata"); - if (carrays_hash != 0) - return carrays_hash; - carrays_hash = NewHash(); - String *mangled_name = 0; - if (nspace == 0 || Len(nspace) == 0) - mangled_name = NewString("SwigModule"); - else - mangled_name = Swig_name_mangle(nspace); - String *cname = NewStringf("swig_%s", mangled_name); - - Setattr(carrays_hash, "cname", cname); - - String *attr_tab = NewString(""); - String *attr_tab_name = NewStringf("swig_%s_attributes", mangled_name); - String *attr_tab_decl = NewString(""); - Printv(attr_tab, "static swig_lua_attribute ", NIL); - Printv(attr_tab, attr_tab_name, "[]", NIL); - Printv(attr_tab_decl, attr_tab, ";\n", NIL); - Printv(attr_tab, " = {\n", NIL); - Setattr(carrays_hash, "attributes", attr_tab); - Setattr(carrays_hash, "attributes:name", attr_tab_name); - Setattr(carrays_hash, "attributes:decl", attr_tab_decl); - - String *methods_tab = NewString(""); - String *methods_tab_name = NewStringf("swig_%s_methods", mangled_name); - String *methods_tab_decl = NewString(""); - if (elua_ltr || eluac_ltr) // In this case methods array also acts as namespace rotable - Printf(methods_tab, "const LUA_REG_TYPE "); - else - Printf(methods_tab, "static swig_lua_method "); - Printv(methods_tab, methods_tab_name, "[]", NIL); - Printv(methods_tab_decl, methods_tab, ";\n", NIL); - Printv(methods_tab, "= {\n", NIL); - Setattr(carrays_hash, "methods", methods_tab); - Setattr(carrays_hash, "methods:name", methods_tab_name); - Setattr(carrays_hash, "methods:decl", methods_tab_decl); - - String *const_tab = NewString(""); - String *const_tab_name = NewStringf("swig_%s_constants", mangled_name); - String *const_tab_decl = NewString(""); - if (elua_ltr || eluac_ltr) // In this case const array holds rotable with namespace constants - Printf(const_tab, "const LUA_REG_TYPE "); - else - Printf(const_tab, "static swig_lua_const_info "); - Printv(const_tab, const_tab_name, "[]", NIL); - Printv(const_tab_decl, const_tab, ";", NIL); - Printv(const_tab, "= {\n", NIL); - Setattr(carrays_hash, "constants", const_tab); - Setattr(carrays_hash, "constants:name", const_tab_name); - Setattr(carrays_hash, "constants:decl", const_tab_decl); - - String *classes_tab = NewString(""); - String *classes_tab_name = NewStringf("swig_%s_classes", mangled_name); - String *classes_tab_decl = NewString(""); - Printf(classes_tab, "static swig_lua_class* "); - Printv(classes_tab, classes_tab_name, "[]", NIL); - Printv(classes_tab_decl, classes_tab, ";", NIL); - Printv(classes_tab, "= {\n", NIL); - Setattr(carrays_hash, "classes", classes_tab); - Setattr(carrays_hash, "classes:name", classes_tab_name); - Setattr(carrays_hash, "classes:decl", classes_tab_decl); - - String *namespaces_tab = NewString(""); - String *namespaces_tab_name = NewStringf("swig_%s_namespaces", mangled_name); - String *namespaces_tab_decl = NewString(""); - Printf(namespaces_tab, "static swig_lua_namespace* "); - Printv(namespaces_tab, namespaces_tab_name, "[]", NIL); - Printv(namespaces_tab_decl, namespaces_tab, ";", NIL); - Printv(namespaces_tab, " = {\n", NIL); - Setattr(carrays_hash, "namespaces", namespaces_tab); - Setattr(carrays_hash, "namespaces:name", namespaces_tab_name); - Setattr(carrays_hash, "namespaces:decl", namespaces_tab_decl); - - if (elua_ltr) { - String *get_tab = NewString(""); - String *get_tab_name = NewStringf("swig_%s_get", mangled_name); - String *get_tab_decl = NewString(""); - Printv(get_tab, "const LUA_REG_TYPE ", get_tab_name, "[]", NIL); - Printv(get_tab_decl, get_tab, ";", NIL); - Printv(get_tab, " = {\n", NIL); - Setattr(carrays_hash, "get", get_tab); - Setattr(carrays_hash, "get:name", get_tab_name); - Setattr(carrays_hash, "get:decl", get_tab_decl); - - String *set_tab = NewString(""); - String *set_tab_name = NewStringf("swig_%s_set", mangled_name); - String *set_tab_decl = NewString(""); - Printv(set_tab, "const LUA_REG_TYPE ", set_tab_name, "[]", NIL); - Printv(set_tab_decl, set_tab, ";", NIL); - Printv(set_tab, " = {\n", NIL); - Setattr(carrays_hash, "set", set_tab); - Setattr(carrays_hash, "set:name", set_tab_name); - Setattr(carrays_hash, "set:decl", set_tab_decl); - - } - if (!eluac_ltr) { - String *metatable_tab = NewString(""); - String *metatable_tab_name = NewStringf("swig_%s_meta", mangled_name); - String *metatable_tab_decl = NewString(""); - if (elua_ltr) // In this case const array holds rotable with namespace constants - Printf(metatable_tab, "const LUA_REG_TYPE "); - else - Printf(metatable_tab, "static swig_lua_method "); - Printv(metatable_tab, metatable_tab_name, "[]", NIL); - Printv(metatable_tab_decl, metatable_tab, ";", NIL); - Printv(metatable_tab, " = {\n", NIL); - Setattr(carrays_hash, "metatable", metatable_tab); - Setattr(carrays_hash, "metatable:name", metatable_tab_name); - Setattr(carrays_hash, "metatable:decl", metatable_tab_decl); - } - - Setattr(scope, "lua:cdata", carrays_hash); - assert(rawGetCArraysHash(nspace)); - - if (reg && nspace != 0 && Len(nspace) != 0 && GetFlag(carrays_hash, "lua:no_reg") == 0) { - // Split names into components - List *components = Split(nspace, '.', -1); - String *parent_path = NewString(""); - int len = Len(components); - String *name = Copy(Getitem(components, len - 1)); - for (int i = 0; i < len - 1; i++) { - if (i > 0) - Printv(parent_path, NSPACE_SEPARATOR, NIL); - String *item = Getitem(components, i); - Printv(parent_path, item, NIL); - } - Hash *parent = getCArraysHash(parent_path, true); - String *namespaces_tab = Getattr(parent, "namespaces"); - Printv(namespaces_tab, "&", cname, ",\n", NIL); - if (elua_ltr || eluac_ltr) { - String *methods_tab = Getattr(parent, "methods"); - Printv(methods_tab, tab4, "{LSTRKEY(\"", name, "\")", ", LROVAL(", methods_tab_name, ")", "},\n", NIL); - } - Setattr(carrays_hash, "name", name); - - Delete(components); - Delete(parent_path); - } else if (!reg) // This namespace shouldn't be registered. Lets remember it. - SetFlag(carrays_hash, "lua:no_reg"); - - Delete(mangled_name); - mangled_name = 0; - return carrays_hash; - } - - /* ----------------------------------------------------------------------------- - * closeCArraysHash() - * - * Functions add end markers {0,0,...,0} to all arrays, prints them to - * output and marks hash as closed (lua:closed). Consequent attempts to - * close the same hash will result in an error. - * closeCArraysHash DOES NOT print structure that describes namespace, it only - * prints array. You can use printCArraysDefinition to print structure. - * if "lua:no_namespaces" is set, then array for "namespaces" won't be printed - * if "lua:no_classes" is set, then array for "classes" won't be printed - * ----------------------------------------------------------------------------- */ - - void closeCArraysHash(String *nspace, File *output) { - Hash *carrays_hash = rawGetCArraysHash(nspace); - assert(carrays_hash); - assert(GetFlag(carrays_hash, "lua:closed") == 0); - - SetFlag(carrays_hash, "lua:closed"); - - // Do arrays describe class instance part or class static part - const int is_instance = GetFlag(carrays_hash, "lua:class_instance"); - - - String *attr_tab = Getattr(carrays_hash, "attributes"); - Printf(attr_tab, " {0,0,0}\n};\n"); - Printv(output, attr_tab, NIL); - - String *const_tab = Getattr(carrays_hash, "constants"); - String *const_tab_name = Getattr(carrays_hash, "constants:name"); - if (elua_ltr || eluac_ltr) - Printv(const_tab, tab4, "{LNILKEY, LNILVAL}\n", "};\n", NIL); - else - Printf(const_tab, " {0,0,0,0,0,0}\n};\n"); - - // For the sake of compiling with -Wall -Werror we print constants - // only when necessary - int need_constants = 0; - if ( (elua_ltr || eluac_ltr) && (old_metatable_bindings) ) - need_constants = 1; - else if (!is_instance) // static part need constants tab - need_constants = 1; - - if (need_constants) - Printv(output, const_tab, NIL); - - if (elua_ltr) { - // Put forward declaration of metatable array - Printv(output, "extern ", Getattr(carrays_hash, "metatable:decl"), "\n", NIL); - } - String *methods_tab = Getattr(carrays_hash, "methods"); - String *metatable_tab_name = Getattr(carrays_hash, "metatable:name"); - if (elua_ltr || eluac_ltr) { - if (old_metatable_bindings) - Printv(methods_tab, tab4, "{LSTRKEY(\"const\"), LROVAL(", const_tab_name, ")},\n", NIL); - if (elua_ltr) { - Printv(methods_tab, tab4, "{LSTRKEY(\"__metatable\"), LROVAL(", metatable_tab_name, ")},\n", NIL); - } - - Printv(methods_tab, tab4, "{LSTRKEY(\"__disown\"), LFUNCVAL(SWIG_Lua_class_disown)},\n", NIL); - Printv(methods_tab, tab4, "{LNILKEY, LNILVAL}\n};\n", NIL); - } else - Printf(methods_tab, " {0,0}\n};\n"); - Printv(output, methods_tab, NIL); - - if (!GetFlag(carrays_hash, "lua:no_classes")) { - String *classes_tab = Getattr(carrays_hash, "classes"); - Printf(classes_tab, " 0\n};\n"); - Printv(output, classes_tab, NIL); - } - - if (!GetFlag(carrays_hash, "lua:no_namespaces")) { - String *namespaces_tab = Getattr(carrays_hash, "namespaces"); - Printf(namespaces_tab, " 0\n};\n"); - Printv(output, namespaces_tab, NIL); - } - if (elua_ltr) { - String *get_tab = Getattr(carrays_hash, "get"); - String *set_tab = Getattr(carrays_hash, "set"); - Printv(get_tab, tab4, "{LNILKEY, LNILVAL}\n};\n", NIL); - Printv(set_tab, tab4, "{LNILKEY, LNILVAL}\n};\n", NIL); - Printv(output, get_tab, NIL); - Printv(output, set_tab, NIL); - } - - // Heuristic whether we need to print metatable or not. - // For the sake of compiling with -Wall -Werror we don't print - // metatable for static part. - int need_metatable = 0; - if (eluac_ltr) - need_metatable = 0; - else if(!is_instance) - need_metatable = 0; - else - need_metatable = 1; - - if (need_metatable) { - String *metatable_tab = Getattr(carrays_hash, "metatable"); - assert(metatable_tab); - if (elua_ltr) { - String *get_tab_name = Getattr(carrays_hash, "get:name"); - String *set_tab_name = Getattr(carrays_hash, "set:name"); - - if (GetFlag(carrays_hash, "lua:class_instance")) { - Printv(metatable_tab, tab4, "{LSTRKEY(\"__index\"), LFUNCVAL(SWIG_Lua_class_get)},\n", NIL); - Printv(metatable_tab, tab4, "{LSTRKEY(\"__newindex\"), LFUNCVAL(SWIG_Lua_class_set)},\n", NIL); - } else { - Printv(metatable_tab, tab4, "{LSTRKEY(\"__index\"), LFUNCVAL(SWIG_Lua_namespace_get)},\n", NIL); - Printv(metatable_tab, tab4, "{LSTRKEY(\"__newindex\"), LFUNCVAL(SWIG_Lua_namespace_set)},\n", NIL); - } - - Printv(metatable_tab, tab4, "{LSTRKEY(\"__gc\"), LFUNCVAL(SWIG_Lua_class_destruct)},\n", NIL); - Printv(metatable_tab, tab4, "{LSTRKEY(\".get\"), LROVAL(", get_tab_name, ")},\n", NIL); - Printv(metatable_tab, tab4, "{LSTRKEY(\".set\"), LROVAL(", set_tab_name, ")},\n", NIL); - Printv(metatable_tab, tab4, "{LSTRKEY(\".fn\"), LROVAL(", Getattr(carrays_hash, "methods:name"), ")},\n", NIL); - - if (GetFlag(carrays_hash, "lua:class_instance")) { - String *static_cls = Getattr(carrays_hash, "lua:class_instance:static_hash"); - assert(static_cls); - // static_cls is swig_lua_namespace. This structure can't be used with eLua(LTR) - // Instead a structure describing its methods is used - String *static_cls_cname = Getattr(static_cls, "methods:name"); - assert(static_cls_cname); - Printv(metatable_tab, tab4, "{LSTRKEY(\".static\"), LROVAL(", static_cls_cname, ")},\n", NIL); - // Put forward declaration of this array - Printv(output, "extern ", Getattr(static_cls, "methods:decl"), "\n", NIL); - } else if (GetFlag(carrays_hash, "lua:class_static")) { - Hash *instance_cls = Getattr(carrays_hash, "lua:class_static:instance_hash"); - assert(instance_cls); - String *instance_cls_metatable_name = Getattr(instance_cls, "metatable:name"); - assert(instance_cls_metatable_name); - Printv(metatable_tab, tab4, "{LSTRKEY(\".instance\"), LROVAL(", instance_cls_metatable_name, ")},\n", NIL); - } - - Printv(metatable_tab, tab4, "{LNILKEY, LNILVAL}\n};\n", NIL); - } else { - Printf(metatable_tab, " {0,0}\n};\n"); - } - - Printv(output, metatable_tab, NIL); - } - - Printv(output, "\n", NIL); - } - - /* ----------------------------------------------------------------------------- - * closeNamespaces() - * - * Recursively close all non-closed namespaces. Prints data to dataOutput. - * ----------------------------------------------------------------------------- */ - - void closeNamespaces(File *dataOutput) { - // Special handling for empty module. - if (symbolScopeLookup("") == 0 || rawGetCArraysHash("") == 0) { - // Module is empty. Create hash for global scope in order to have swig_SwigModule - // variable in resulting file - getCArraysHash(0); - } - // Because we can't directly access 'symtabs', instead we access - // top-level scope and look on all scope pseudo-symbols in it. - Hash *top_scope = symbolScopeLookup(""); - assert(top_scope); - Iterator ki = First(top_scope); - List *to_close = NewList(); - while (ki.key) { - assert(ki.item); - if (Getattr(ki.item, "sym:scope")) { - // We have a pseudo symbol. Lets get actual scope for this pseudo symbol - Hash *carrays_hash = rawGetCArraysHash(ki.key); - assert(carrays_hash); - if (GetFlag(carrays_hash, "lua:closed") == 0) - Append(to_close, ki.key); - } - ki = Next(ki); - } - SortList(to_close, &compareByLen); - int len = Len(to_close); - for (int i = 0; i < len; i++) { - String *key = Getitem(to_close, i); - closeCArraysHash(key, dataOutput); - Hash *carrays_hash = rawGetCArraysHash(key); - String *name = 0; // name - name of the namespace as it should be visible in Lua - if (DohLen(key) == 0) // This is global module - name = module; - else - name = Getattr(carrays_hash, "name"); - assert(name); - printCArraysDefinition(key, name, dataOutput); - } - Delete(to_close); - } - - /* ----------------------------------------------------------------------------- - * printCArraysDefinition() - * - * This function prints to output a definition of namespace in form - * swig_lua_namespace $cname = { attr_array, methods_array, ... , namespaces_array }; - * You can call this function as many times as is necessary. - * 'name' is a user-visible name that this namespace will have in Lua. It shouldn't - * be a fully qualified name, just its own name. - * ----------------------------------------------------------------------------- */ - - void printCArraysDefinition(String *nspace, String *name, File *output) { - Hash *carrays_hash = getCArraysHash(nspace, false); - - String *cname = Getattr(carrays_hash, "cname"); // cname - name of the C structure that describes namespace - assert(cname); - Printv(output, "static swig_lua_namespace ", cname, " = ", NIL); - - String *null_string = NewString("0"); - String *attr_tab_name = Getattr(carrays_hash, "attributes:name"); - String *methods_tab_name = Getattr(carrays_hash, "methods:name"); - String *const_tab_name = Getattr(carrays_hash, "constants:name"); - String *classes_tab_name = Getattr(carrays_hash, "classes:name"); - String *namespaces_tab_name = Getattr(carrays_hash, "namespaces:name"); - bool has_classes = GetFlag(carrays_hash, "lua:no_classes") == 0; - bool has_namespaces = GetFlag(carrays_hash, "lua:no_namespaces") == 0; - - Printv(output, "{\n", - tab4, "\"", name, "\",\n", - tab4, methods_tab_name, ",\n", - tab4, attr_tab_name, ",\n", - tab4, const_tab_name, ",\n", - tab4, (has_classes) ? classes_tab_name : null_string, ",\n", - tab4, (has_namespaces) ? namespaces_tab_name : null_string, "\n};\n", NIL); - Delete(null_string); - } - - /* ----------------------------------------------------------------------------- - * luaCurrentSymbolNSpace() - * - * This function determines actual namespace/scope where any symbol at the - * current moment should be placed. It looks at the 'current' array - * and depending on where are we - static class member/function, - * instance class member/function or just global functions decides - * where symbol should be put. - * The namespace/scope doesn't depend from symbol, only from 'current' - * ----------------------------------------------------------------------------- */ - - String *luaCurrentSymbolNSpace() { - String *scope = 0; - // If outside class, than NSpace is used. - // If inside class, but current[NO_CPP], then this is friend function. It belongs to NSpace - if (!getCurrentClass() || current[NO_CPP]) { - scope = getNSpace(); - } else if (current[ENUM_CONST] && !CPlusPlus ) { - // Enums in C mode go to NSpace - scope = getNSpace(); - } else { - // If inside class, then either class static namespace or class fully qualified name is used - assert(!current[NO_CPP]); - if (current[STATIC_FUNC] || current[STATIC_VAR] || current[STATIC_CONST]) { - scope = class_static_nspace; - } else if (current[MEMBER_VAR] || current[CONSTRUCTOR] || current[DESTRUCTOR] - || current[MEMBER_FUNC]) { - scope = full_proxy_class_name; - } else { // Friend functions are handled this way - scope = class_static_nspace; - } - assert(scope); - } - return scope; - } - - /* ----------------------------------------------------------------------------- - * luaAddSymbol() - * - * Our implementation of addSymbol. Determines scope correctly, then - * forwards to Language::addSymbol - * ----------------------------------------------------------------------------- */ - - int luaAddSymbol(const String *s, const Node *n) { - String *scope = luaCurrentSymbolNSpace(); - return luaAddSymbol(s, n, scope); - } - - /* ----------------------------------------------------------------------------- - * luaAddSymbol() - * - * Overload. Enforces given scope. Actually, it simply forwards call to Language::addSymbol - * ----------------------------------------------------------------------------- */ - - int luaAddSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) { - int result = Language::addSymbol(s, n, scope); - if (!result) - Printf(stderr, "addSymbol(%s to scope %s) failed\n", s, scope); - return result; - } - -}; - -/* ----------------------------------------------------------------------------- - * swig_lua() - Instantiate module - * ----------------------------------------------------------------------------- */ - -extern "C" Language *swig_lua(void) { - return new LUA(); -} diff --git a/contrib/tools/swig/Source/Modules/main.cxx b/contrib/tools/swig/Source/Modules/main.cxx deleted file mode 100644 index f5bdec644c0..00000000000 --- a/contrib/tools/swig/Source/Modules/main.cxx +++ /dev/null @@ -1,1407 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * main.cxx - * - * Main entry point to the SWIG core. - * ----------------------------------------------------------------------------- */ - -#include "swigconfig.h" - -#if defined(_WIN32) -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#endif - -#include "swigmod.h" - -#include "swigwarn.h" -#include "cparse.h" -#include <ctype.h> -#include <errno.h> -#include <limits.h> // for INT_MAX - -// Global variables - -static Language *lang = 0; // Language method -int CPlusPlus = 0; -int Extend = 0; // Extend flag -int ForceExtern = 0; // Force extern mode -int GenerateDefault = 1; // Generate default constructors -int Verbose = 0; -int AddExtern = 0; -int NoExcept = 0; -int SwigRuntime = 0; // 0 = no option, 1 = -runtime, 2 = -noruntime -extern "C" { - int UseWrapperSuffix = 0; // If 1, append suffix to non-overloaded functions too. -} - -/* Suppress warning messages for private inheritance, etc by default. - These are enabled by command line option -Wextra. - - WARN_PARSE_PRIVATE_INHERIT 309 - WARN_PARSE_BUILTIN_NAME 321 - WARN_PARSE_REDUNDANT 322 - WARN_TYPE_ABSTRACT 403 - WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405 - WARN_LANG_OVERLOAD_CONST 512 - */ -#define EXTRA_WARNINGS "309,403,405,512,321,322" - -extern "C" { - extern String *ModuleName; - extern int ignore_nested_classes; - extern int kwargs_supported; -} - -/* usage string split into multiple parts otherwise string is too big for some compilers */ -/* naming conventions for commandline options - no underscores, no capital letters, join words together - * except when using a common prefix, then use '-' to separate, eg the debug-xxx options */ -static const char *usage1 = (const char *) "\ -\nGeneral Options\n\ - -addextern - Add extra extern declarations\n\ - -c++ - Enable C++ processing\n\ - -co <file> - Check <file> out of the SWIG library\n\ - -copyctor - Automatically generate copy constructors wherever possible\n\ - -cpperraswarn - Treat the preprocessor #error statement as #warning (default)\n\ - -cppext <ext> - Change file extension of generated C++ files to <ext>\n\ - (default is cxx)\n\ - -copyright - Display copyright notices\n\ - -debug-classes - Display information about the classes found in the interface\n\ - -debug-module <n>- Display module parse tree at stages 1-4, <n> is a csv list of stages\n\ - -debug-symtabs - Display symbol tables information\n\ - -debug-symbols - Display target language symbols in the symbol tables\n\ - -debug-csymbols - Display C symbols in the symbol tables\n\ - -debug-lsymbols - Display target language layer symbols\n\ - -debug-quiet - Display less parse tree node debug info when using other -debug options\n\ - -debug-tags - Display information about the tags found in the interface\n\ - -debug-template - Display information for debugging templates\n\ - -debug-top <n> - Display entire parse tree at stages 1-4, <n> is a csv list of stages\n\ - -debug-typedef - Display information about the types and typedefs in the interface\n\ - -debug-typemap - Display typemap debugging information\n\ - -debug-tmsearch - Display typemap search debugging information\n\ - -debug-tmused - Display typemaps used debugging information\n\ - -directors - Turn on director mode for all the classes, mainly for testing\n\ - -dirprot - Turn on wrapping of protected members for director classes (default)\n\ - -D<symbol> - Define a symbol <symbol> (for conditional compilation)\n\ -"; - -static const char *usage2 = (const char *) "\ - -E - Preprocess only, does not generate wrapper code\n\ - -external-runtime [file] - Export the SWIG runtime stack\n\ - -fakeversion <v>- Make SWIG fake the program version number to <v>\n\ - -fcompact - Compile in compact mode\n\ - -features <list>- Set global features, where <list> is a comma separated list of\n\ - features, eg -features directors,autodoc=1\n\ - If no explicit value is given to the feature, a default of 1 is used\n\ - -fastdispatch - Enable fast dispatch mode to produce faster overload dispatcher code\n\ - -Fmicrosoft - Display error/warning messages in Microsoft format\n\ - -Fstandard - Display error/warning messages in commonly used format\n\ - -fvirtual - Compile in virtual elimination mode\n\ - -help - Display help\n\ - -I- - Don't search the current directory\n\ - -I<dir> - Look for SWIG files in directory <dir>\n\ - -ignoremissing - Ignore missing include files\n\ - -importall - Follow all #include statements as imports\n\ - -includeall - Follow all #include statements\n\ - -l<ifile> - Include SWIG library file <ifile>\n\ -"; - -static const char *usage3 = (const char *) "\ - -macroerrors - Report errors inside macros\n\ - -makedefault - Create default constructors/destructors (the default)\n\ - -M - List all dependencies\n\ - -MD - Is equivalent to `-M -MF <file>', except `-E' is not implied\n\ - -MF <file> - Generate dependencies into <file> and continue generating wrappers\n\ - -MM - List dependencies, but omit files in SWIG library\n\ - -MMD - Like `-MD', but omit files in SWIG library\n\ - -module <name> - Set module name to <name>\n\ - -MP - Generate phony targets for all dependencies\n\ - -MT <target> - Set the target of the rule emitted by dependency generation\n\ - -nocontract - Turn off contract checking\n\ - -nocpperraswarn - Do not treat the preprocessor #error statement as #warning\n\ - -nodefault - Do not generate default constructors nor default destructors\n\ - -nodefaultctor - Do not generate implicit default constructors\n\ - -nodefaultdtor - Do not generate implicit default destructors\n\ - -nodirprot - Do not wrap director protected members\n\ - -noexcept - Do not wrap exception specifiers\n\ - -nofastdispatch - Disable fast dispatch mode (default)\n\ - -nopreprocess - Skip the preprocessor step\n\ - -notemplatereduce - Disable reduction of the typedefs in templates\n\ -"; - -static const char *usage4 = (const char *) "\ - -O - Enable the optimization options:\n\ - -fastdispatch -fvirtual\n\ - -o <outfile> - Set name of C/C++ output file to <outfile>\n\ - -oh <headfile> - Set name of C++ output header file for directors to <headfile>\n\ - -outcurrentdir - Set default output dir to current dir instead of input file's path\n\ - -outdir <dir> - Set language specific files output directory to <dir>\n\ - -pcreversion - Display PCRE2 version information\n\ - -small - Compile in virtual elimination and compact mode\n\ - -swiglib - Report location of SWIG library and exit\n\ - -templatereduce - Reduce all the typedefs in templates\n\ - -v - Run in verbose mode\n\ - -version - Display SWIG version number\n\ - -Wall - Remove all warning suppression, also implies -Wextra\n\ - -Wallkw - Enable keyword warnings for all the supported languages\n\ - -Werror - Treat warnings as errors\n\ - -Wextra - Adds the following additional warnings: " EXTRA_WARNINGS "\n\ - -w<list> - Suppress/add warning messages, eg -w401,+321 - see Warnings.html\n\ - -xmlout <file> - Write XML version of the parse tree to <file> after normal processing\n\ -\n\ -Options can also be defined using the SWIG_FEATURES environment variable, for example:\n\ -\n\ - $ SWIG_FEATURES=\"-Wall\"\n\ - $ export SWIG_FEATURES\n\ - $ swig -python interface.i\n\ -\n\ -is equivalent to:\n\ -\n\ - $ swig -Wall -python interface.i\n\ -\n\ -Arguments may also be passed in a file, separated by whitespace. For example:\n\ -\n\ - $ echo \"-Wall -python interface.i\" > args.txt\n\ - $ swig @args.txt\n\ -\n"; - -// Local variables -static String *LangSubDir = 0; // Target language library subdirectory -static String *SwigLib = 0; // Library directory -static String *SwigLibWinUnix = 0; // Extra library directory on Windows -static int freeze = 0; -static String *lang_config = 0; -static const char *hpp_extension = "h"; -static const char *cpp_extension = "cxx"; -static const char *depends_extension = "d"; -static String *outdir = 0; -static String *xmlout = 0; -static int outcurrentdir = 0; -static int help = 0; -static int checkout = 0; -static int cpp_only = 0; -static int no_cpp = 0; -static String *outfile_name = 0; -static String *outfile_name_h = 0; -static int tm_debug = 0; -static int dump_symtabs = 0; -static int dump_symbols = 0; -static int dump_csymbols = 0; -static int dump_lang_symbols = 0; -static int dump_tags = 0; -static int dump_module = 0; -static int dump_top = 0; -static int dump_xml = 0; -static int dump_typedef = 0; -static int dump_classes = 0; -static int werror = 0; -static int depend = 0; -static int depend_only = 0; -static int depend_phony = 0; -static int memory_debug = 0; -static int allkw = 0; -static DOH *cpps = 0; -static String *dependencies_file = 0; -static String *dependencies_target = 0; -static int external_runtime = 0; -static String *external_runtime_name = 0; -enum { STAGE1=1, STAGE2=2, STAGE3=4, STAGE4=8, STAGEOVERFLOW=16 }; -static List *libfiles = 0; -static List *all_output_files = 0; - -/* ----------------------------------------------------------------------------- - * check_extension() - * - * Checks the extension of a file to see if we should emit extern declarations. - * ----------------------------------------------------------------------------- */ - -static bool check_extension(String *filename) { - bool wanted = false; - const char *name = Char(filename); - if (!name) - return 0; - String *extension = Swig_file_extension(name); - const char *c = Char(extension); - if ((strcmp(c, ".c") == 0) || - (strcmp(c, ".C") == 0) || (strcmp(c, ".cc") == 0) || (strcmp(c, ".cxx") == 0) || (strcmp(c, ".c++") == 0) || (strcmp(c, ".cpp") == 0)) { - wanted = true; - } - Delete(extension); - return wanted; -} - -/* ----------------------------------------------------------------------------- - * install_opts() - * - * Install all command line options as preprocessor symbols - * ----------------------------------------------------------------------------- */ - -static void install_opts(int argc, char *argv[]) { - int i; - int noopt = 0; - char *c; - for (i = 1; i < (argc - 1); i++) { - if (argv[i]) { - if ((*argv[i] == '-') && (!isupper(*(argv[i] + 1)))) { - String *opt = NewStringf("SWIGOPT%(upper)s", argv[i]); - Replaceall(opt, "-", "_"); - c = Char(opt); - noopt = 0; - while (*c) { - if (!(isalnum(*c) || (*c == '_'))) { - noopt = 1; - break; - } - c++; - } - if (((i + 1) < (argc - 1)) && (argv[i + 1]) && (*argv[i + 1] != '-')) { - Printf(opt, " %s", argv[i + 1]); - i++; - } else { - Printf(opt, " 1"); - } - if (!noopt) { - /* Printf(stdout,"%s\n", opt); */ - Preprocessor_define(opt, 0); - } - Delete(opt); - } - } - } -} - -/* ----------------------------------------------------------------------------- - * decode_numbers_list() - * - * Decode comma separated list into a binary number of the inputs or'd together - * eg list="1,4" will return (2^0 || 2^3) = 0x1001 - * ----------------------------------------------------------------------------- */ - -static unsigned int decode_numbers_list(String *numlist) { - unsigned int decoded_number = 0; - if (numlist) { - List *numbers = Split(numlist, ',', INT_MAX); - if (numbers && Len(numbers) > 0) { - for (Iterator it = First(numbers); it.item; it = Next(it)) { - String *numstring = it.item; - // TODO: check that it is a number - int number = atoi(Char(numstring)); - if (number > 0 && number <= 16) { - decoded_number |= (1 << (number-1)); - } - } - } - } - return decoded_number; -} - -/* ----------------------------------------------------------------------------- - * Sets the output directory for language specific (proxy) files from the - * C wrapper file if not set and corrects the directory name and adds a trailing - * file separator if necessary. - * ----------------------------------------------------------------------------- */ - -static void configure_outdir(const String *c_wrapper_outfile) { - - // Use the C wrapper file's directory if the output directory has not been set by user - if (!outdir || Len(outdir) == 0) - outdir = Swig_file_dirname(c_wrapper_outfile); - - Swig_filename_correct(outdir); - - // Add trailing file delimiter if not present in output directory name - if (Len(outdir) > 0) { - const char *outd = Char(outdir); - if (strcmp(outd + strlen(outd) - strlen(SWIG_FILE_DELIMITER), SWIG_FILE_DELIMITER) != 0) - Printv(outdir, SWIG_FILE_DELIMITER, NIL); - } -} - -/* This function sets the name of the configuration file */ -void SWIG_config_file(const_String_or_char_ptr filename) { - lang_config = NewString(filename); -} - -/* Sets the target language subdirectory name */ -void SWIG_library_directory(const char *subdirectory) { - LangSubDir = NewString(subdirectory); -} - -// Returns the directory for generating language specific files (non C/C++ files) -const String *SWIG_output_directory() { - assert(outdir); - return outdir; -} - -void SWIG_config_cppext(const char *ext) { - cpp_extension = ext; -} - -List *SWIG_output_files() { - assert(all_output_files); - return all_output_files; -} - -void SWIG_setfeature(const char *cfeature, const char *cvalue) { - Hash *features_hash = Swig_cparse_features(); - String *name = NewString(""); - String *fname = NewString(cfeature); - String *fvalue = NewString(cvalue); - Swig_feature_set(features_hash, name, 0, fname, fvalue, 0); - Delete(name); - Delete(fname); - Delete(fvalue); -} - - -void SWIG_setfeatures(const char *c) { - char feature[64]; - char *fb = feature; - char *fe = fb + 63; - Hash *features_hash = Swig_cparse_features(); - String *name = NewString(""); - /* Printf(stderr,"all features %s\n", c); */ - while (*c) { - char *f = fb; - String *fname = NewString("feature:"); - String *fvalue = NewString(""); - while ((f != fe) && *c != '=' && *c != ',' && *c) { - *(f++) = *(c++); - } - *f = 0; - Printf(fname, "%s", feature); - if (*c && *(c++) == '=') { - char value[64]; - char *v = value; - char *ve = v + 63; - while ((v != ve) && *c != ',' && *c && !isspace(*c)) { - *(v++) = *(c++); - } - *v = 0; - Printf(fvalue, "%s", value); - } else { - Printf(fvalue, "1"); - } - /* Printf(stderr,"%s %s\n", fname, fvalue); */ - Swig_feature_set(features_hash, name, 0, fname, fvalue, 0); - Delete(fname); - Delete(fvalue); - } - Delete(name); -} - -/* This function handles the -external-runtime command option */ -static void SWIG_dump_runtime() { - String *outfile; - File *runtime; - String *s; - - outfile = external_runtime_name; - if (!outfile) { - outfile = lang->defaultExternalRuntimeFilename(); - if (!outfile) { - Printf(stderr, "*** Please provide a filename for the external runtime\n"); - Exit(EXIT_FAILURE); - } - } - - runtime = NewFile(outfile, "w", SWIG_output_files()); - if (!runtime) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - - Swig_banner(runtime); - Printf(runtime, "\n"); - - s = Swig_include_sys("swiglabels.swg"); - if (!s) { - Printf(stderr, "*** Unable to open 'swiglabels.swg'\n"); - Delete(runtime); - Exit(EXIT_FAILURE); - } - Printf(runtime, "%s", s); - Delete(s); - - s = Swig_include_sys("swigerrors.swg"); - if (!s) { - Printf(stderr, "*** Unable to open 'swigerrors.swg'\n"); - Delete(runtime); - Exit(EXIT_FAILURE); - } - Printf(runtime, "%s", s); - Delete(s); - - s = Swig_include_sys("swigrun.swg"); - if (!s) { - Printf(stderr, "*** Unable to open 'swigrun.swg'\n"); - Delete(runtime); - Exit(EXIT_FAILURE); - } - Printf(runtime, "%s", s); - Delete(s); - - s = lang->runtimeCode(); - Printf(runtime, "%s", s); - Delete(s); - - s = Swig_include_sys("runtime.swg"); - if (!s) { - Printf(stderr, "*** Unable to open 'runtime.swg'\n"); - Delete(runtime); - Exit(EXIT_FAILURE); - } - Printf(runtime, "%s", s); - Delete(s); - - Delete(runtime); - Exit(EXIT_SUCCESS); -} - -static void getoptions(int argc, char *argv[]) { - int i; - // Get options - for (i = 1; i < argc; i++) { - if (argv[i] && !Swig_check_marked(i)) { - if (strncmp(argv[i], "-I-", 3) == 0) { - // Don't push/pop directories - Swig_set_push_dir(0); - Swig_mark_arg(i); - } else if (strncmp(argv[i], "-I", 2) == 0) { - // Add a new directory search path - Swig_add_directory((String_or_char*)(argv[i] + 2)); - Swig_mark_arg(i); - } else if (strncmp(argv[i], "-D", 2) == 0) { - String *d = NewString(argv[i] + 2); - if (Replace(d, "=", " ", DOH_REPLACE_FIRST) == 0) { - // Match C preprocessor behaviour whereby -DFOO sets FOO=1. - Append(d, " 1"); - } - Preprocessor_define((DOH *) d, 0); - Delete(d); - // Create a symbol - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-E") == 0) { - cpp_only = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nopreprocess") == 0) { - no_cpp = 1; - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-verbose") == 0) || (strcmp(argv[i], "-v") == 0)) { - Verbose = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-c++") == 0) { - CPlusPlus = 1; - Preprocessor_define((DOH *) "__cplusplus __cplusplus", 0); - Swig_cparse_cplusplus(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-c++out") == 0) { - // Undocumented - Swig_cparse_cplusplusout(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-fcompact") == 0) { - Wrapper_compact_print_mode_set(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-fvirtual") == 0) { - Wrapper_virtual_elimination_mode_set(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-fastdispatch") == 0) { - Wrapper_fast_dispatch_mode_set(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nofastdispatch") == 0) { - Wrapper_fast_dispatch_mode_set(0); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-naturalvar") == 0) { - Wrapper_naturalvar_mode_set(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-directors") == 0) { - SWIG_setfeature("feature:director", "1"); - Wrapper_director_mode_set(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-dirprot") == 0) { - Wrapper_director_protected_mode_set(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nodirprot") == 0) { - Wrapper_director_protected_mode_set(0); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-pcreversion") == 0) { - String *version = Swig_pcre_version(); - Printf(stdout, "%s\n", version); - Delete(version); - Swig_mark_arg(i); - Exit(EXIT_SUCCESS); - } else if (strcmp(argv[i], "-small") == 0) { - Wrapper_compact_print_mode_set(1); - Wrapper_virtual_elimination_mode_set(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-runtime") == 0) { // Used to also accept -c. removed in swig-1.3.36 - Swig_mark_arg(i); - Swig_warning(WARN_DEPRECATED_OPTC, "SWIG", 1, "-runtime, -noruntime command line options are deprecated.\n"); - SwigRuntime = 1; - } else if (strcmp(argv[i], "-noruntime") == 0) { - Swig_mark_arg(i); - Swig_warning(WARN_DEPRECATED_OPTC, "SWIG", 1, "-runtime, -noruntime command line options are deprecated.\n"); - SwigRuntime = 2; - } else if (strcmp(argv[i], "-external-runtime") == 0) { - external_runtime = 1; - Swig_mark_arg(i); - if (argv[i + 1]) { - external_runtime_name = NewString(argv[i + 1]); - Swig_mark_arg(i + 1); - i++; - } - } else if ((strcmp(argv[i], "-make_default") == 0) || (strcmp(argv[i], "-makedefault") == 0)) { - GenerateDefault = 1; - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-no_default") == 0) || (strcmp(argv[i], "-nodefault") == 0)) { - GenerateDefault = 0; - Swig_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use -nodefaultctor, -nodefaultdtor instead.\n"); - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-nodefaultctor") == 0)) { - SWIG_setfeature("feature:nodefaultctor", "1"); - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-nodefaultdtor") == 0)) { - SWIG_setfeature("feature:nodefaultdtor", "1"); - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-copyctor") == 0)) { - SWIG_setfeature("feature:copyctor", "1"); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-noexcept") == 0) { - NoExcept = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-noextern") == 0) { - Swig_warning(WARN_DEPRECATED_NOEXTERN, "SWIG", 1, "-noextern command line option is deprecated; extern is no longer generated by default.\n"); - AddExtern = 0; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-addextern") == 0) { - AddExtern = 1; - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-debug-template") == 0) || (strcmp(argv[i], "-debug_template") == 0) || (strcmp(argv[i], "-show_templates") == 0)) { - Swig_cparse_debug_templates(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-templatereduce") == 0) { - SWIG_cparse_template_reduce(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-notemplatereduce") == 0) { - SWIG_cparse_template_reduce(0); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-macroerrors") == 0) { - Swig_cparse_follow_locators(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-swiglib") == 0) { - Printf(stdout, "%s\n", SwigLib); - if (SwigLibWinUnix) - Printf(stdout, "%s\n", SwigLibWinUnix); - Exit(EXIT_SUCCESS); - } else if (strcmp(argv[i], "-o") == 0) { - Swig_mark_arg(i); - if (argv[i + 1]) { - outfile_name = NewString(argv[i + 1]); - Swig_filename_correct(outfile_name); - if (!outfile_name_h || !dependencies_file) { - char *ext = strrchr(Char(outfile_name), '.'); - String *basename = ext ? NewStringWithSize(Char(outfile_name), (int)(Char(ext) - Char(outfile_name))) : NewString(outfile_name); - if (!dependencies_file) { - dependencies_file = NewStringf("%s.%s", basename, depends_extension); - } - if (!outfile_name_h) { - Printf(basename, ".%s", hpp_extension); - outfile_name_h = NewString(basename); - } - Delete(basename); - } - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-oh") == 0) { - Swig_mark_arg(i); - if (argv[i + 1]) { - outfile_name_h = NewString(argv[i + 1]); - Swig_filename_correct(outfile_name_h); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-fakeversion") == 0) { - Swig_mark_arg(i); - if (argv[i + 1]) { - Swig_set_fakeversion(argv[i + 1]); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-version") == 0) { - fprintf(stdout, "\nSWIG Version %s\n", Swig_package_version()); - fprintf(stdout, "\nCompiled with %s [%s]\n", SWIG_CXX, SWIG_PLATFORM); - fprintf(stdout, "\nConfigured options: %cpcre\n", -#ifdef HAVE_PCRE - '+' -#else - '-' -#endif - ); - fprintf(stdout, "\nPlease see %s for reporting bugs and further information\n", PACKAGE_BUGREPORT); - Exit(EXIT_SUCCESS); - } else if (strcmp(argv[i], "-copyright") == 0) { - fprintf(stdout, "\nSWIG Version %s\n", Swig_package_version()); - fprintf(stdout, "Copyright (c) 1995-1998\n"); - fprintf(stdout, "University of Utah and the Regents of the University of California\n"); - fprintf(stdout, "Copyright (c) 1998-2005\n"); - fprintf(stdout, "University of Chicago\n"); - fprintf(stdout, "Copyright (c) 2005-2006\n"); - fprintf(stdout, "Arizona Board of Regents (University of Arizona)\n"); - Exit(EXIT_SUCCESS); - } else if (strncmp(argv[i], "-l", 2) == 0) { - // Add a new directory search path - Append(libfiles, argv[i] + 2); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-co") == 0) { - checkout = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-features") == 0) { - Swig_mark_arg(i); - if (argv[i + 1]) { - SWIG_setfeatures(argv[i + 1]); - Swig_mark_arg(i + 1); - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-freeze") == 0) { - freeze = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-includeall") == 0) { - Preprocessor_include_all(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-importall") == 0) { - Preprocessor_import_all(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-ignoremissing") == 0) { - Preprocessor_ignore_missing(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-cpperraswarn") == 0) { - Preprocessor_error_as_warning(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nocpperraswarn") == 0) { - Preprocessor_error_as_warning(0); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-cppext") == 0) { - Swig_mark_arg(i); - if (argv[i + 1]) { - SWIG_config_cppext(argv[i + 1]); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if ((strcmp(argv[i], "-debug-typemap") == 0) || (strcmp(argv[i], "-debug_typemap") == 0) || (strcmp(argv[i], "-tm_debug") == 0)) { - tm_debug = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-debug-tmsearch") == 0) { - Swig_typemap_search_debug_set(); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-debug-tmused") == 0) { - Swig_typemap_used_debug_set(); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-module") == 0) { - Swig_mark_arg(i); - if (argv[i + 1]) { - ModuleName = NewString(argv[i + 1]); - Swig_mark_arg(i + 1); - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-M") == 0) { - depend = 1; - depend_only = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-MM") == 0) { - depend = 2; - depend_only = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-MF") == 0) { - Swig_mark_arg(i); - if (argv[i + 1]) { - dependencies_file = NewString(argv[i + 1]); - Swig_mark_arg(i + 1); - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-MD") == 0) { - depend = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-MMD") == 0) { - depend = 2; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-MP") == 0) { - depend_phony = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-MT") == 0) { - Swig_mark_arg(i); - if (argv[i + 1]) { - if (!dependencies_target) - dependencies_target = NewString(argv[i + 1]); - else - Printf(dependencies_target, " %s", argv[i + 1]); - Swig_mark_arg(i + 1); - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-outdir") == 0) { - Swig_mark_arg(i); - if (argv[i + 1]) { - outdir = NewString(argv[i + 1]); - Swig_mark_arg(i + 1); - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-outcurrentdir") == 0) { - Swig_mark_arg(i); - outcurrentdir = 1; - } else if (strcmp(argv[i], "-Wall") == 0) { - Swig_mark_arg(i); - Swig_warnall(); - } else if (strcmp(argv[i], "-Wallkw") == 0) { - allkw = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-Werror") == 0) { - werror = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-Wextra") == 0) { - Swig_mark_arg(i); - Swig_warnfilter(EXTRA_WARNINGS, 0); - } else if (strncmp(argv[i], "-w", 2) == 0) { - Swig_mark_arg(i); - Swig_warnfilter(argv[i] + 2, 1); - } else if (strcmp(argv[i], "-debug-quiet") == 0) { - Swig_print_quiet(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-debug-symtabs") == 0) { - dump_symtabs = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-debug-symbols") == 0) { - dump_symbols = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-debug-csymbols") == 0) { - dump_csymbols = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-debug-lsymbols") == 0) { - dump_lang_symbols = 1; - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-debug-tags") == 0) || (strcmp(argv[i], "-dump_tags") == 0)) { - dump_tags = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-debug-top") == 0) { - Swig_mark_arg(i); - if (argv[i + 1]) { - String *dump_list = NewString(argv[i + 1]); - dump_top = decode_numbers_list(dump_list); - if (dump_top < STAGE1 || dump_top >= STAGEOVERFLOW) - Swig_arg_error(); - else - Swig_mark_arg(i + 1); - Delete(dump_list); - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-debug-module") == 0) { - Swig_mark_arg(i); - if (argv[i + 1]) { - String *dump_list = NewString(argv[i + 1]); - dump_module = decode_numbers_list(dump_list); - if (dump_module < STAGE1 || dump_module >= STAGEOVERFLOW) - Swig_arg_error(); - else - Swig_mark_arg(i + 1); - Delete(dump_list); - } else { - Swig_arg_error(); - } - } else if ((strcmp(argv[i], "-dump_tree") == 0) || (strcmp(argv[i], "-dump_top") == 0)) { - dump_top |= STAGE4; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-dump_module") == 0) { - dump_module |= STAGE4; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-dump_parse_module") == 0) { - dump_module |= STAGE1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-dump_parse_top") == 0) { - dump_top |= STAGE1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-dump_xml") == 0) { - dump_xml = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-xmlout") == 0) { - dump_xml = 1; - Swig_mark_arg(i); - if (argv[i + 1]) { - xmlout = NewString(argv[i + 1]); - Swig_mark_arg(i + 1); - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-nocontract") == 0) { - Swig_mark_arg(i); - Swig_contract_mode_set(0); - } else if ((strcmp(argv[i], "-debug-typedef") == 0) || (strcmp(argv[i], "-dump_typedef") == 0)) { - dump_typedef = 1; - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-debug-classes") == 0) || (strcmp(argv[i], "-dump_classes") == 0)) { - dump_classes = 1; - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-debug-memory") == 0) || (strcmp(argv[i], "-dump_memory") == 0)) { - memory_debug = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-Fstandard") == 0) { - Swig_error_msg_format(EMF_STANDARD); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-Fmicrosoft") == 0) { - Swig_error_msg_format(EMF_MICROSOFT); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-O") == 0) { - Wrapper_virtual_elimination_mode_set(1); - Wrapper_fast_dispatch_mode_set(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-help") == 0) { - fputs(usage1, stdout); - fputs(usage2, stdout); - fputs(usage3, stdout); - fputs(usage4, stdout); - Swig_mark_arg(i); - help = 1; - } - } - } -} - -static void SWIG_exit_handler(int status); - -int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) { - char *c; - - /* Set function for Exit() to call. */ - SetExitHandler(SWIG_exit_handler); - - /* Initialize the SWIG core */ - Swig_init(); - - // Default warning suppression - Swig_warnfilter(EXTRA_WARNINGS, 1); - - // Initialize the preprocessor - Preprocessor_init(); - - // Set lang to a dummy value if no target language was specified so we - // can process options enough to handle -version, etc. - lang = tlm ? tlm->fac() : new Language; - - // Set up some default symbols (available in both SWIG interface files - // and C files) - - Preprocessor_define((DOH *) "SWIG 1", 0); - Preprocessor_define((DOH *) "__STDC__", 0); - - String *vers = Swig_package_version_hex(); - Preprocessor_define(vers, 0); - Delete(vers); - - Swig_contract_mode_set(1); - - /* Turn off directors mode */ - Wrapper_director_mode_set(0); - Wrapper_director_protected_mode_set(1); - - // Inform the parser if the nested classes should be ignored unless explicitly told otherwise via feature:flatnested - ignore_nested_classes = lang->nestedClassesSupport() == Language::NCS_Unknown ? 1 : 0; - - kwargs_supported = lang->kwargsSupport() ? 1 : 0; - - // Create Library search directories - - // Check for SWIG_LIB environment variable - if ((c = getenv("SWIG_LIB")) == (char *) 0) { -#if defined(_WIN32) - char buf[MAX_PATH]; - char *p; - if (!(GetModuleFileName(0, buf, MAX_PATH) == 0 || (p = strrchr(buf, '\\')) == 0)) { - *(p + 1) = '\0'; - SwigLib = NewStringf("%sLib", buf); // Native windows installation path - } else { - SwigLib = NewStringf(""); // Unexpected error - } - if (Len(SWIG_LIB_WIN_UNIX) > 0) - SwigLibWinUnix = NewString(SWIG_LIB_WIN_UNIX); // Unix installation path using a drive letter (for msys/mingw) -#else - SwigLib = NewString(SWIG_LIB); -#endif - } else { - SwigLib = NewString(c); - } - - libfiles = NewList(); - all_output_files = NewList(); - - /* Check for SWIG_FEATURES environment variable */ - - getoptions(argc, argv); - - // Define the __cplusplus symbol - if (CPlusPlus) - Preprocessor_define((DOH *) "__cplusplus __cplusplus", 0); - - // Parse language dependent options - lang->main(argc, argv); - - if (help) { - Printf(stdout, "\nNote: 'swig -<lang> -help' displays options for a specific target language.\n\n"); - Exit(EXIT_SUCCESS); // Exit if we're in help mode - } - - // Check all of the options to make sure we're cool. - // Don't check for an input file if -external-runtime is passed - Swig_check_options(external_runtime ? 0 : 1); - - if (CPlusPlus && cparse_cplusplusout) { - Printf(stderr, "The -c++out option is for C input but C++ input has been requested via -c++\n"); - Exit(EXIT_FAILURE); - } - - install_opts(argc, argv); - - // Add language dependent directory to the search path - { - String *rl = NewString(""); - Printf(rl, ".%sswig_lib%s%s", SWIG_FILE_DELIMITER, SWIG_FILE_DELIMITER, LangSubDir); - Swig_add_directory(rl); - if (SwigLibWinUnix) { - rl = NewString(""); - Printf(rl, "%s%s%s", SwigLibWinUnix, SWIG_FILE_DELIMITER, LangSubDir); - Swig_add_directory(rl); - } - rl = NewString(""); - Printf(rl, "%s%s%s", SwigLib, SWIG_FILE_DELIMITER, LangSubDir); - Swig_add_directory(rl); - } - - Swig_add_directory((String *) "." SWIG_FILE_DELIMITER "swig_lib"); - if (SwigLibWinUnix) - Swig_add_directory((String *) SwigLibWinUnix); - Swig_add_directory(SwigLib); - - if (Verbose) { - Printf(stdout, "Language subdirectory: %s\n", LangSubDir); - Printf(stdout, "Search paths:\n"); - List *sp = Swig_search_path(); - Iterator s; - for (s = First(sp); s.item; s = Next(s)) { - Printf(stdout, " %s\n", s.item); - } - } - // handle the -external-runtime argument - if (external_runtime) - SWIG_dump_runtime(); - - // If we made it this far, looks good. go for it.... - - input_file = NewString(argv[argc - 1]); - Swig_filename_correct(input_file); - - // If the user has requested to check out a file, handle that - if (checkout) { - DOH *s; - String *outfile = input_file; - if (outfile_name) - outfile = outfile_name; - - if (Verbose) - Printf(stdout, "Handling checkout...\n"); - - s = Swig_include(input_file); - if (!s) { - Printf(stderr, "Unable to locate '%s' in the SWIG library.\n", input_file); - } else { - FILE *f = Swig_open(outfile); - if (f) { - fclose(f); - Printf(stderr, "File '%s' already exists. Checkout aborted.\n", outfile); - } else { - File *f_outfile = NewFile(outfile, "w", SWIG_output_files()); - if (!f_outfile) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } else { - if (Verbose) - Printf(stdout, "'%s' checked out from the SWIG library.\n", outfile); - Printv(f_outfile, s, NIL); - Delete(f_outfile); - } - } - } - } else { - // Run the preprocessor - if (Verbose) - Printf(stdout, "Preprocessing...\n"); - - { - int i; - String *fs = NewString(""); - FILE *df = Swig_open(input_file); - if (!df) { - df = Swig_include_open(input_file); - if (!df) { - char *cfile = Char(input_file); - if (cfile && cfile[0] == '-') { - Printf(stderr, "Unable to find option or file '%s', ", input_file); - Printf(stderr, "Use 'swig -help' for more information.\n"); - } else { - Printf(stderr, "Unable to find file '%s'.\n", input_file); - } - Exit(EXIT_FAILURE); - } else { - Swig_warning(WARN_DEPRECATED_INPUT_FILE, "SWIG", 1, "Use of the include path to find the input file is deprecated and will not work with ccache. Please include the path when specifying the input file.\n"); // so that behaviour is like c/c++ compilers - } - } - - if (!tlm) { - Printf(stderr, "No target language specified.\n"); - Printf(stderr, "Use 'swig -help' for more information.\n"); - Exit(EXIT_FAILURE); - } - - if (!no_cpp) { - fclose(df); - Printf(fs, "%%include <swig.swg>\n"); - if (allkw) { - Printf(fs, "%%include <allkw.swg>\n"); - } - if (lang_config) { - Printf(fs, "\n%%include <%s>\n", lang_config); - } - Printf(fs, "%%include(maininput=\"%s\") \"%s\"\n", Swig_filename_escape(input_file), Swig_filename_escape(Swig_last_file())); - for (i = 0; i < Len(libfiles); i++) { - Printf(fs, "\n%%include \"%s\"\n", Swig_filename_escape(Getitem(libfiles, i))); - } - Seek(fs, 0, SEEK_SET); - cpps = Preprocessor_parse(fs); - Delete(fs); - } else { - cpps = Swig_read_file(df); - fclose(df); - } - if (Swig_error_count()) { - Exit(EXIT_FAILURE); - } - if (cpp_only) { - Printf(stdout, "%s", cpps); - Exit(EXIT_SUCCESS); - } - if (depend) { - if (!no_cpp) { - String *outfile; - File *f_dependencies_file = 0; - - String *inputfile_filename = outcurrentdir ? Swig_file_filename(input_file): Copy(input_file); - String *basename = Swig_file_basename(inputfile_filename); - if (!outfile_name) { - if (CPlusPlus || lang->cplus_runtime_mode()) { - outfile = NewStringf("%s_wrap.%s", basename, cpp_extension); - } else { - outfile = NewStringf("%s_wrap.c", basename); - } - } else { - outfile = NewString(outfile_name); - } - if (dependencies_file && Len(dependencies_file) != 0) { - f_dependencies_file = NewFile(dependencies_file, "w", SWIG_output_files()); - if (!f_dependencies_file) { - FileErrorDisplay(dependencies_file); - Exit(EXIT_FAILURE); - } - } else if (!depend_only) { - String *filename = NewStringf("%s_wrap.%s", basename, depends_extension); - f_dependencies_file = NewFile(filename, "w", SWIG_output_files()); - if (!f_dependencies_file) { - FileErrorDisplay(filename); - Exit(EXIT_FAILURE); - } - } else - f_dependencies_file = stdout; - if (dependencies_target) { - Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(dependencies_target)); - } else { - Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(outfile)); - } - List *files = Preprocessor_depend(); - List *phony_targets = NewList(); - for (int i = 0; i < Len(files); i++) { - int use_file = 1; - if (depend == 2) { - if ((Strncmp(Getitem(files, i), SwigLib, Len(SwigLib)) == 0) || (SwigLibWinUnix && (Strncmp(Getitem(files, i), SwigLibWinUnix, Len(SwigLibWinUnix)) == 0))) - use_file = 0; - } - if (use_file) { - Printf(f_dependencies_file, "\\\n %s ", Swig_filename_escape_space(Getitem(files, i))); - if (depend_phony) - Append(phony_targets, Getitem(files, i)); - } - } - Printf(f_dependencies_file, "\n"); - if (depend_phony) { - for (int i = 0; i < Len(phony_targets); i++) { - Printf(f_dependencies_file, "\n%s:\n", Swig_filename_escape_space(Getitem(phony_targets, i))); - } - } - - if (f_dependencies_file != stdout) - Delete(f_dependencies_file); - if (depend_only) - Exit(EXIT_SUCCESS); - Delete(inputfile_filename); - Delete(basename); - Delete(phony_targets); - } else { - Printf(stderr, "Cannot generate dependencies with -nopreprocess\n"); - // Actually we could but it would be inefficient when just generating dependencies, as it would be done after Swig_cparse - Exit(EXIT_FAILURE); - } - } - Seek(cpps, 0, SEEK_SET); - } - - /* Register a null file with the file handler */ - Swig_register_filebyname("null", NewString("")); - - // Pass control over to the specific language interpreter - if (Verbose) { - fprintf(stdout, "Starting language-specific parse...\n"); - fflush(stdout); - } - - Node *top = Swig_cparse(cpps); - - if (dump_top & STAGE1) { - Printf(stdout, "debug-top stage 1\n"); - Swig_print_tree(top); - } - if (dump_module & STAGE1) { - Printf(stdout, "debug-module stage 1\n"); - Swig_print_tree(Getattr(top, "module")); - } - if (!CPlusPlus) { - if (Verbose) - Printf(stdout, "Processing unnamed structs...\n"); - Swig_nested_name_unnamed_c_structs(top); - } - Swig_extend_unused_check(); - - if (Verbose) { - Printf(stdout, "Processing types...\n"); - } - Swig_process_types(top); - - if (dump_top & STAGE2) { - Printf(stdout, "debug-top stage 2\n"); - Swig_print_tree(top); - } - if (dump_module & STAGE2) { - Printf(stdout, "debug-module stage 2\n"); - Swig_print_tree(Getattr(top, "module")); - } - - if (Verbose) { - Printf(stdout, "C++ analysis...\n"); - } - Swig_default_allocators(top); - - if (CPlusPlus) { - if (Verbose) - Printf(stdout, "Processing nested classes...\n"); - Swig_nested_process_classes(top); - } - - if (dump_top & STAGE3) { - Printf(stdout, "debug-top stage 3\n"); - Swig_print_tree(top); - } - if (top && (dump_module & STAGE3)) { - Printf(stdout, "debug-module stage 3\n"); - Swig_print_tree(Getattr(top, "module")); - } - - if (Verbose) { - Printf(stdout, "Generating wrappers...\n"); - } - - if (top && dump_classes) { - Hash *classes = Getattr(top, "classes"); - if (classes) { - Printf(stdout, "Classes\n"); - Printf(stdout, "------------\n"); - Iterator ki; - for (ki = First(classes); ki.key; ki = Next(ki)) { - Printf(stdout, "%s\n", ki.key); - } - } - } - - if (dump_typedef) { - SwigType_print_scope(); - } - - if (dump_symtabs) { - Swig_symbol_print_tables(Swig_symbol_global_scope()); - Swig_symbol_print_tables_summary(); - } - - if (dump_symbols) { - Swig_symbol_print_symbols(); - } - - if (dump_csymbols) { - Swig_symbol_print_csymbols(); - } - - if (dump_tags) { - Swig_print_tags(top, 0); - } - if (top) { - if (!Getattr(top, "name")) { - Printf(stderr, "No module name specified using %%module or -module.\n"); - Exit(EXIT_FAILURE); - } else { - /* Set some filename information on the object */ - String *infile = scanner_get_main_input_file(); - if (!infile) { - Printf(stderr, "Missing input file in preprocessed output.\n"); - Exit(EXIT_FAILURE); - } - Setattr(top, "infile", infile); // Note: if nopreprocess then infile is the original input file, otherwise input_file - Setattr(top, "inputfile", input_file); - - String *infile_filename = outcurrentdir ? Swig_file_filename(infile): Copy(infile); - String *basename = Swig_file_basename(infile_filename); - if (!outfile_name) { - if (CPlusPlus || lang->cplus_runtime_mode()) { - Setattr(top, "outfile", NewStringf("%s_wrap.%s", basename, cpp_extension)); - } else { - Setattr(top, "outfile", NewStringf("%s_wrap.c", basename)); - } - } else { - Setattr(top, "outfile", outfile_name); - } - if (!outfile_name_h) { - Setattr(top, "outfile_h", NewStringf("%s_wrap.%s", basename, hpp_extension)); - } else { - Setattr(top, "outfile_h", outfile_name_h); - } - configure_outdir(Getattr(top, "outfile")); - if (Swig_contract_mode_get()) { - Swig_contracts(top); - } - - // Check the extension for a c/c++ file. If so, we're going to declare everything we see as "extern" - ForceExtern = check_extension(input_file); - - if (tlm->status == Experimental) { - Swig_warning(WARN_LANG_EXPERIMENTAL, "SWIG", 1, "Experimental target language. " - "Target language %s specified by %s is an experimental language. " - "Please read about SWIG experimental languages, https://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n", - tlm->help ? tlm->help : "", tlm->name); - } - - lang->top(top); - - Delete(infile_filename); - Delete(basename); - } - } - if (dump_lang_symbols) { - lang->dumpSymbols(); - } - if (dump_top & STAGE4) { - Printf(stdout, "debug-top stage 4\n"); - Swig_print_tree(top); - } - if (dump_module & STAGE4) { - Printf(stdout, "debug-module stage 4\n"); - Swig_print_tree(Getattr(top, "module")); - } - if (dump_xml && top) { - delete lang; - lang = 0; - Swig_print_xml(top, xmlout); - } - Delete(top); - } - if (tm_debug) - Swig_typemap_debug(); - if (memory_debug) - DohMemoryDebug(); - - char *outfiles = getenv("CCACHE_OUTFILES"); - if (outfiles) { - File *f_outfiles = NewFile(outfiles, "w", 0); - if (!f_outfiles) { - Printf(stderr, "Failed to write list of output files to the filename '%s' specified in CCACHE_OUTFILES environment variable - ", outfiles); - FileErrorDisplay(outfiles); - Exit(EXIT_FAILURE); - } else { - int i; - for (i = 0; i < Len(all_output_files); i++) - Printf(f_outfiles, "%s\n", Getitem(all_output_files, i)); - Delete(f_outfiles); - } - } - - // Deletes - Delete(libfiles); - Preprocessor_delete(); - - while (freeze) { - } - - delete lang; - - int error_count = werror ? Swig_warn_count() : 0; - error_count += Swig_error_count(); - - if (error_count != 0) - Exit(EXIT_FAILURE); - - return 0; -} - -/* ----------------------------------------------------------------------------- - * SWIG_exit_handler() - * - * Cleanup and either freeze or exit - * ----------------------------------------------------------------------------- */ - -static void SWIG_exit_handler(int status) { - while (freeze) { - } - - if (status > 0) { - CloseAllOpenFiles(); - - /* Remove all generated files */ - if (all_output_files) { - for (int i = 0; i < Len(all_output_files); i++) { - String *filename = Getitem(all_output_files, i); - int removed = remove(Char(filename)); - if (removed == -1) - fprintf(stderr, "On exit, could not delete file %s: %s\n", Char(filename), strerror(errno)); - } - } - } -} diff --git a/contrib/tools/swig/Source/Modules/mzscheme.cxx b/contrib/tools/swig/Source/Modules/mzscheme.cxx deleted file mode 100644 index e22f8bb7adb..00000000000 --- a/contrib/tools/swig/Source/Modules/mzscheme.cxx +++ /dev/null @@ -1,802 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * mzscheme.cxx - * - * Mzscheme language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include <ctype.h> - -static const char *usage = "\ -Mzscheme Options (available with -mzscheme)\n\ - -declaremodule - Create extension that declares a module\n\ - -dynamic-load <lib>,[lib,...] - Do not link with these libraries, dynamic load them\n\ - -noinit - Do not emit module initialization code\n\ - -prefix <name> - Set a prefix <name> to be prepended to all names\n\ -"; - -static String *fieldnames_tab = 0; -static String *convert_tab = 0; -static String *convert_proto_tab = 0; -static String *struct_name = 0; -static String *mangled_struct_name = 0; - -static String *prefix = 0; -static bool declaremodule = false; -static bool noinit = false; -static String *load_libraries = NULL; -static String *module = 0; -static const char *mzscheme_path = "mzscheme"; -static String *init_func_def = 0; - -static File *f_begin = 0; -static File *f_runtime = 0; -static File *f_header = 0; -static File *f_wrappers = 0; -static File *f_init = 0; - -// Used for garbage collection -static int exporting_destructor = 0; -static String *swigtype_ptr = 0; -static String *cls_swigtype = 0; - -class MZSCHEME:public Language { -public: - - /* ------------------------------------------------------------ - * main() - * ------------------------------------------------------------ */ - - virtual void main(int argc, char *argv[]) { - - int i; - - SWIG_library_directory(mzscheme_path); - - // Look for certain command line options - for (i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-help") == 0) { - fputs(usage, stdout); - Exit(EXIT_SUCCESS); - } else if (strcmp(argv[i], "-prefix") == 0) { - if (argv[i + 1]) { - prefix = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-declaremodule") == 0) { - declaremodule = true; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-noinit") == 0) { - noinit = true; - Swig_mark_arg(i); - } - else if (strcmp(argv[i], "-dynamic-load") == 0) { - if (argv[i + 1]) { - Delete(load_libraries); - load_libraries = NewString(argv[i + 1]); - Swig_mark_arg(i++); - Swig_mark_arg(i); - } else { - Swig_arg_error(); - } - } - } - } - - // If a prefix has been specified make sure it ends in a '_' (not actually used!) - if (prefix) { - const char *px = Char(prefix); - if (px[Len(prefix) - 1] != '_') - Printf(prefix, "_"); - } else - prefix = NewString("swig_"); - - // Add a symbol for this module - - Preprocessor_define("SWIGMZSCHEME 1", 0); - - // Set name of typemaps - - SWIG_typemap_lang("mzscheme"); - - // Read in default typemaps */ - SWIG_config_file("mzscheme.swg"); - allow_overloading(); - - } - - /* ------------------------------------------------------------ - * top() - * ------------------------------------------------------------ */ - - virtual int top(Node *n) { - - /* Initialize all of the output files */ - String *outfile = Getattr(n, "outfile"); - - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - f_wrappers = NewString(""); - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - - init_func_def = NewString(""); - Swig_register_filebyname("init", init_func_def); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "MZSCHEME"); - - module = Getattr(n, "name"); - - Language::top(n); - - SwigType_emit_type_table(f_runtime, f_wrappers); - if (!noinit) { - if (declaremodule) { - Printf(f_init, "#define SWIG_MZSCHEME_CREATE_MENV(env) scheme_primitive_module(scheme_intern_symbol(\"%s\"), env)\n", module); - } else { - Printf(f_init, "#define SWIG_MZSCHEME_CREATE_MENV(env) (env)\n"); - } - Printf(f_init, "%s\n", Char(init_func_def)); - if (declaremodule) { - Printf(f_init, "\tscheme_finish_primitive_module(menv);\n"); - } - Printf(f_init, "\treturn scheme_void;\n}\n"); - Printf(f_init, "Scheme_Object *scheme_initialize(Scheme_Env *env) {\n"); - - if (load_libraries) { - Printf(f_init, "mz_set_dlopen_libraries(\"%s\");\n", load_libraries); - } - - Printf(f_init, "\treturn scheme_reload(env);\n"); - Printf(f_init, "}\n"); - - Printf(f_init, "Scheme_Object *scheme_module_name(void) {\n"); - if (declaremodule) { - Printf(f_init, " return scheme_intern_symbol((char*)\"%s\");\n", module); - } else { - Printf(f_init, " return scheme_make_symbol((char*)\"%s\");\n", module); - } - Printf(f_init, "}\n"); - } - - /* Close all of the files */ - Dump(f_runtime, f_begin); - Dump(f_header, f_begin); - Dump(f_wrappers, f_begin); - Wrapper_pretty_print(f_init, f_begin); - Delete(f_header); - Delete(f_wrappers); - Delete(f_init); - Delete(f_runtime); - Delete(f_begin); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * functionWrapper() - * Create a function declaration and register it with the interpreter. - * ------------------------------------------------------------ */ - - void throw_unhandled_mzscheme_type_error(SwigType *d) { - Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s.\n", SwigType_str(d, 0)); - } - - /* Return true iff T is a pointer type */ - - int - is_a_pointer(SwigType *t) { - return SwigType_ispointer(SwigType_typedef_resolve_all(t)); - } - - virtual int functionWrapper(Node *n) { - char *iname = GetChar(n, "sym:name"); - SwigType *d = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - Parm *p; - - Wrapper *f = NewWrapper(); - String *proc_name = NewString(""); - String *target = NewString(""); - String *arg = NewString(""); - String *cleanup = NewString(""); - String *outarg = NewString(""); - String *build = NewString(""); - String *tm; - int i = 0; - int numargs; - int numreq; - String *overname = 0; - - if (load_libraries) { - ParmList *parms = Getattr(n, "parms"); - SwigType *type = Getattr(n, "type"); - String *name = NewString("caller"); - Setattr(n, "wrap:action", Swig_cresult(type, Swig_cresult_name(), Swig_cfunction_call(name, parms))); - } - - // Make a wrapper name for this - String *wname = Swig_name_wrapper(iname); - if (Getattr(n, "sym:overloaded")) { - overname = Getattr(n, "sym:overname"); - } else { - if (!addSymbol(iname, n)) { - DelWrapper(f); - return SWIG_ERROR; - } - } - if (overname) { - Append(wname, overname); - } - Setattr(n, "wrap:name", wname); - - // Build the name for Scheme. - Printv(proc_name, iname, NIL); - Replaceall(proc_name, "_", "-"); - - // writing the function wrapper function - Printv(f->def, "static Scheme_Object *", wname, " (", NIL); - Printv(f->def, "int argc, Scheme_Object **argv", NIL); - Printv(f->def, ")\n{", NIL); - - /* Define the scheme name in C. This define is used by several - macros. */ - Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); - - // Emit all of the local variables for holding arguments. - emit_parameter_variables(l, f); - - /* Attach the standard typemaps */ - emit_attach_parmmaps(l, f); - Setattr(n, "wrap:parms", l); - - numargs = emit_num_arguments(l); - numreq = emit_num_required(l); - - /* Add the holder for the pointer to the function to be opened */ - if (load_libraries) { - Wrapper_add_local(f, "_function_loaded", "static int _function_loaded=(1==0)"); - Wrapper_add_local(f, "_the_function", "static void *_the_function=NULL"); - { - String *parms = ParmList_protostr(l); - String *func = NewStringf("(*caller)(%s)", parms); - Wrapper_add_local(f, "caller", SwigType_lstr(d, func)); /*"(*caller)()")); */ - } - } - - // adds local variables - Wrapper_add_local(f, "lenv", "int lenv = 1"); - Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]"); - - if (load_libraries) { - Printf(f->code, "if (!_function_loaded) { _the_function=mz_load_function(\"%s\");_function_loaded=(1==1); }\n", iname); - Printf(f->code, "if (!_the_function) { scheme_signal_error(\"Cannot load C function '%s'\"); }\n", iname); - Printf(f->code, "caller=_the_function;\n"); - } - - // Now write code to extract the parameters (this is super ugly) - - for (i = 0, p = l; i < numargs; i++) { - /* Skip ignored arguments */ - - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *ln = Getattr(p, "lname"); - - // Produce names of source and target - Clear(target); - Clear(arg); - String *source = NewStringf("argv[%d]", i); - Printf(target, "%s", ln); - Printv(arg, Getattr(p, "name"), NIL); - - if (i >= numreq) { - Printf(f->code, "if (argc > %d) {\n", i); - } - // Handle parameter types. - if ((tm = Getattr(p, "tmap:in"))) { - Replaceall(tm, "$input", source); - Setattr(p, "emit:input", source); - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:in:next"); - } else { - // no typemap found - // check if typedef and resolve - throw_unhandled_mzscheme_type_error(pt); - p = nextSibling(p); - } - if (i >= numreq) { - Printf(f->code, "}\n"); - } - Delete(source); - } - - /* Insert constraint checking code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - - // Pass output arguments back to the caller. - - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - Replaceall(tm, "$arg", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - // Free up any memory allocated for the arguments. - - /* Insert cleanup code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:freearg"))) { - Printv(cleanup, tm, "\n", NIL); - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - // Now write code to make the function call - - String *actioncode = emit_action(n); - - // Now have return value, figure out what to do with it. - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { - Replaceall(tm, "$result", "values[0]"); - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "1"); - else - Replaceall(tm, "$owner", "0"); - Printv(f->code, tm, "\n", NIL); - } else { - throw_unhandled_mzscheme_type_error(d); - } - emit_return_variable(n, d, f); - - // Dump the argument output code - Printv(f->code, Char(outarg), NIL); - - // Dump the argument cleanup code - Printv(f->code, Char(cleanup), NIL); - - // Look for any remaining cleanup - - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - Printv(f->code, tm, "\n", NIL); - } - } - // Free any memory allocated by the function being wrapped.. - - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printv(f->code, tm, "\n", NIL); - } - // Wrap things up (in a manner of speaking) - - Printv(f->code, tab4, "return SWIG_MzScheme_PackageValues(lenv, values);\n", NIL); - Printf(f->code, "#undef FUNC_NAME\n"); - Printv(f->code, "}\n", NIL); - - /* Substitute the function name */ - Replaceall(f->code, "$symname", iname); - - Wrapper_print(f, f_wrappers); - - if (!Getattr(n, "sym:overloaded")) { - - // Now register the function - char temp[256]; - sprintf(temp, "%d", numargs); - if (exporting_destructor) { - Printf(init_func_def, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname); - } - Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, wname, proc_name, numreq, numargs); - } else { - if (!Getattr(n, "sym:nextSibling")) { - /* Emit overloading dispatch function */ - - int maxargs; - String *dispatch = Swig_overload_dispatch(n, "return %s(argc,argv);", &maxargs); - - /* Generate a dispatch wrapper for all overloaded functions */ - - Wrapper *df = NewWrapper(); - String *dname = Swig_name_wrapper(iname); - - Printv(df->def, "static Scheme_Object *\n", dname, "(int argc, Scheme_Object **argv) {", NIL); - Printv(df->code, dispatch, "\n", NIL); - Printf(df->code, "scheme_signal_error(\"No matching function for overloaded '%s'\");\n", iname); - Printf(df->code, "return NULL;\n"); - Printv(df->code, "}\n", NIL); - Wrapper_print(df, f_wrappers); - Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, dname, proc_name, 0, maxargs); - DelWrapper(df); - Delete(dispatch); - Delete(dname); - } - } - - Delete(proc_name); - Delete(target); - Delete(arg); - Delete(outarg); - Delete(cleanup); - Delete(build); - DelWrapper(f); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * variableWrapper() - * - * Create a link to a C variable. - * This creates a single function _wrap_swig_var_varname(). - * This function takes a single optional argument. If supplied, it means - * we are setting this variable to some value. If omitted, it means we are - * simply evaluating this variable. Either way, we return the variables - * value. - * ------------------------------------------------------------ */ - - virtual int variableWrapper(Node *n) { - - char *name = GetChar(n, "name"); - char *iname = GetChar(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - - String *proc_name = NewString(""); - String *tm; - String *tm2 = NewString(""); - String *argnum = NewString("0"); - String *arg = NewString("argv[0]"); - Wrapper *f; - - if (!addSymbol(iname, n)) - return SWIG_ERROR; - - f = NewWrapper(); - - // evaluation function names - String *var_name = Swig_name_wrapper(iname); - - // Build the name for scheme. - Printv(proc_name, iname, NIL); - Replaceall(proc_name, "_", "-"); - Setattr(n, "wrap:name", proc_name); - - if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) { - - Printf(f->def, "static Scheme_Object *%s(int argc, Scheme_Object** argv) {\n", var_name); - Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); - - Wrapper_add_local(f, "swig_result", "Scheme_Object *swig_result"); - - if (!GetFlag(n, "feature:immutable")) { - /* Check for a setting of the variable value */ - Printf(f->code, "if (argc) {\n"); - if ((tm = Swig_typemap_lookup("varin", n, name, 0))) { - Replaceall(tm, "$input", "argv[0]"); - Replaceall(tm, "$argnum", "1"); - emit_action_code(n, f->code, tm); - } else { - throw_unhandled_mzscheme_type_error(t); - } - Printf(f->code, "}\n"); - } - // Now return the value of the variable (regardless - // of evaluating or setting) - - if ((tm = Swig_typemap_lookup("varout", n, name, 0))) { - Replaceall(tm, "$result", "swig_result"); - /* Printf (f->code, "%s\n", tm); */ - emit_action_code(n, f->code, tm); - } else { - throw_unhandled_mzscheme_type_error(t); - } - Printf(f->code, "\nreturn swig_result;\n"); - Printf(f->code, "#undef FUNC_NAME\n"); - Printf(f->code, "}\n"); - - Wrapper_print(f, f_wrappers); - - // Now add symbol to the MzScheme interpreter - - Printv(init_func_def, - "scheme_add_global(\"", proc_name, "\", scheme_make_prim_w_arity(", var_name, ", \"", proc_name, "\", ", "0", ", ", "1", "), menv);\n", NIL); - - } else { - Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0)); - } - Delete(var_name); - Delete(proc_name); - Delete(argnum); - Delete(arg); - Delete(tm2); - DelWrapper(f); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constantWrapper() - * ------------------------------------------------------------ */ - - virtual int constantWrapper(Node *n) { - char *name = GetChar(n, "name"); - char *iname = GetChar(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - String *value = Getattr(n, "value"); - - String *var_name = NewString(""); - String *proc_name = NewString(""); - String *rvalue = NewString(""); - String *temp = NewString(""); - String *tm; - - // Make a static variable; - - Printf(var_name, "_wrap_const_%s", Swig_name_mangle(Getattr(n, "sym:name"))); - - // Build the name for scheme. - Printv(proc_name, iname, NIL); - Replaceall(proc_name, "_", "-"); - - if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) { - Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); - return SWIG_NOWRAP; - } - // See if there's a typemap - - Printv(rvalue, value, NIL); - if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) { - temp = Copy(rvalue); - Clear(rvalue); - Printv(rvalue, "\"", temp, "\"", NIL); - } - if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) { - Delete(temp); - temp = Copy(rvalue); - Clear(rvalue); - Printv(rvalue, "'", temp, "'", NIL); - } - if ((tm = Swig_typemap_lookup("constant", n, name, 0))) { - Replaceall(tm, "$value", rvalue); - Printf(f_init, "%s\n", tm); - } else { - // Create variable and assign it a value - - Printf(f_header, "static %s = ", SwigType_lstr(type, var_name)); - bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0); - if ((SwigType_type(type) == T_STRING)) { - Printf(f_header, "\"%s\";\n", value); - } else if (SwigType_type(type) == T_CHAR && !is_enum_item) { - Printf(f_header, "\'%s\';\n", value); - } else { - Printf(f_header, "%s;\n", value); - } - - // Now create a variable declaration - - { - /* Hack alert: will cleanup later -- Dave */ - Node *nn = NewHash(); - Setfile(nn, Getfile(n)); - Setline(nn, Getline(n)); - Setattr(nn, "name", var_name); - Setattr(nn, "sym:name", iname); - Setattr(nn, "type", type); - SetFlag(nn, "feature:immutable"); - variableWrapper(nn); - Delete(nn); - } - } - Delete(proc_name); - Delete(rvalue); - Delete(temp); - return SWIG_OK; - } - - virtual int destructorHandler(Node *n) { - exporting_destructor = true; - Language::destructorHandler(n); - exporting_destructor = false; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * classHandler() - * ------------------------------------------------------------ */ - virtual int classHandler(Node *n) { - String *mangled_classname = 0; - String *real_classname = 0; - String *scm_structname = NewString(""); - SwigType *ctype_ptr = NewStringf("p.%s", getClassType()); - - SwigType *t = NewStringf("p.%s", Getattr(n, "name")); - swigtype_ptr = SwigType_manglestr(t); - Delete(t); - - cls_swigtype = SwigType_manglestr(Getattr(n, "name")); - - - fieldnames_tab = NewString(""); - convert_tab = NewString(""); - convert_proto_tab = NewString(""); - - struct_name = Getattr(n, "sym:name"); - mangled_struct_name = Swig_name_mangle(Getattr(n, "sym:name")); - - Printv(scm_structname, struct_name, NIL); - Replaceall(scm_structname, "_", "-"); - - real_classname = Getattr(n, "name"); - mangled_classname = Swig_name_mangle(real_classname); - - Printv(fieldnames_tab, "static const char *_swig_struct_", cls_swigtype, "_field_names[] = { \n", NIL); - - Printv(convert_proto_tab, "static Scheme_Object *_swig_convert_struct_", cls_swigtype, "(", SwigType_str(ctype_ptr, "ptr"), ");\n", NIL); - - Printv(convert_tab, "static Scheme_Object *_swig_convert_struct_", cls_swigtype, "(", SwigType_str(ctype_ptr, "ptr"), ")\n {\n", NIL); - - Printv(convert_tab, - tab4, "Scheme_Object *obj;\n", tab4, "Scheme_Object *fields[_swig_struct_", cls_swigtype, "_field_names_cnt];\n", tab4, "int i = 0;\n\n", NIL); - - /* Generate normal wrappers */ - Language::classHandler(n); - - Printv(convert_tab, tab4, "obj = scheme_make_struct_instance(", "_swig_struct_type_", cls_swigtype, ", i, fields);\n", NIL); - Printv(convert_tab, tab4, "return obj;\n}\n\n", NIL); - - Printv(fieldnames_tab, "};\n", NIL); - - Printv(f_header, "static Scheme_Object *_swig_struct_type_", cls_swigtype, ";\n", NIL); - - Printv(f_header, fieldnames_tab, NIL); - Printv(f_header, "#define _swig_struct_", cls_swigtype, "_field_names_cnt (sizeof(_swig_struct_", cls_swigtype, "_field_names)/sizeof(char*))\n", NIL); - - Printv(f_header, convert_proto_tab, NIL); - Printv(f_wrappers, convert_tab, NIL); - - Printv(init_func_def, "_swig_struct_type_", cls_swigtype, - " = SWIG_MzScheme_new_scheme_struct(menv, \"", scm_structname, "\", ", - "_swig_struct_", cls_swigtype, "_field_names_cnt,", "(char**) _swig_struct_", cls_swigtype, "_field_names);\n", NIL); - - Delete(mangled_classname); - Delete(swigtype_ptr); - swigtype_ptr = 0; - Delete(fieldnames_tab); - Delete(convert_tab); - Delete(ctype_ptr); - Delete(convert_proto_tab); - struct_name = 0; - mangled_struct_name = 0; - Delete(cls_swigtype); - cls_swigtype = 0; - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * membervariableHandler() - * ------------------------------------------------------------ */ - - virtual int membervariableHandler(Node *n) { - Language::membervariableHandler(n); - - if (!is_smart_pointer()) { - String *symname = Getattr(n, "sym:name"); - String *name = Getattr(n, "name"); - SwigType *type = Getattr(n, "type"); - String *swigtype = SwigType_manglestr(Getattr(n, "type")); - String *tm = 0; - String *access_mem = NewString(""); - SwigType *ctype_ptr = NewStringf("p.%s", Getattr(n, "type")); - - Printv(fieldnames_tab, tab4, "\"", symname, "\",\n", NIL); - Printv(access_mem, "(ptr)->", name, NIL); - if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) { - Printv(convert_tab, tab4, "fields[i++] = ", NIL); - Printv(convert_tab, "_swig_convert_struct_", swigtype, "((", SwigType_str(ctype_ptr, 0), ")&((ptr)->", name, "));\n", NIL); - } else if ((tm = Swig_typemap_lookup("varout", n, access_mem, 0))) { - Replaceall(tm, "$result", "fields[i++]"); - Printv(convert_tab, tm, "\n", NIL); - } else - Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported member variable type %s (ignored).\n", SwigType_str(type, 0)); - - Delete(access_mem); - } - return SWIG_OK; - } - - - /* ------------------------------------------------------------ - * validIdentifier() - * ------------------------------------------------------------ */ - - virtual int validIdentifier(String *s) { - char *c = Char(s); - /* Check whether we have an R5RS identifier. */ - /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */ - /* <initial> --> <letter> | <special initial> */ - if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%') - || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') - || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') - || (*c == '^') || (*c == '_') || (*c == '~'))) { - /* <peculiar identifier> --> + | - | ... */ - if ((strcmp(c, "+") == 0) - || strcmp(c, "-") == 0 || strcmp(c, "...") == 0) - return 1; - else - return 0; - } - /* <subsequent> --> <initial> | <digit> | <special subsequent> */ - while (*c) { - if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%') - || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') - || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') - || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+') - || (*c == '-') || (*c == '.') || (*c == '@'))) - return 0; - c++; - } - return 1; - } - - String *runtimeCode() { - String *s = Swig_include_sys("mzrun.swg"); - if (!s) { - Printf(stderr, "*** Unable to open 'mzrun.swg'\n"); - s = NewString(""); - } - return s; - } - - String *defaultExternalRuntimeFilename() { - return NewString("swigmzrun.h"); - } -}; - -/* ----------------------------------------------------------------------------- - * swig_mzscheme() - Instantiate module - * ----------------------------------------------------------------------------- */ - -static Language *new_swig_mzscheme() { - return new MZSCHEME(); -} -extern "C" Language *swig_mzscheme(void) { - return new_swig_mzscheme(); -} diff --git a/contrib/tools/swig/Source/Modules/nested.cxx b/contrib/tools/swig/Source/Modules/nested.cxx deleted file mode 100644 index d027eebe5ba..00000000000 --- a/contrib/tools/swig/Source/Modules/nested.cxx +++ /dev/null @@ -1,453 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * nested.cxx - * - * Nested structs support - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" - -// Nested classes processing section -static Hash *classhash = 0; - -static String *make_name(Node *n, String *name, SwigType *decl) { - int destructor = name && (*(Char(name)) == '~'); - if (String *yyrename = Getattr(n, "class_rename")) { - String *s = NewString(yyrename); - Delattr(n, "class_rename"); - if (destructor && (*(Char(s)) != '~')) { - Insert(s, 0, "~"); - } - return s; - } - - if (!name) - return 0; - return Swig_name_make(n, 0, name, decl, 0); -} - -// C version of add_symbols() -static void add_symbols_c(Node *n) { - String *decl; - String *wrn = 0; - String *symname = 0; - int iscdecl = Cmp(nodeType(n), "cdecl") == 0; - Setattr(n, "ismember", "1"); - Setattr(n, "access", "public"); - if (Getattr(n, "sym:name")) - return; - decl = Getattr(n, "decl"); - if (!SwigType_isfunction(decl)) { - String *name = Getattr(n, "name"); - String *makename = Getattr(n, "parser:makename"); - if (iscdecl) { - String *storage = Getattr(n, "storage"); - if (Cmp(storage, "typedef") == 0) { - Setattr(n, "kind", "typedef"); - } else { - SwigType *type = Getattr(n, "type"); - String *value = Getattr(n, "value"); - Setattr(n, "kind", "variable"); - if (value && Len(value)) { - Setattr(n, "hasvalue", "1"); - } - if (type) { - SwigType *ty; - SwigType *tmp = 0; - if (decl) { - ty = tmp = Copy(type); - SwigType_push(ty, decl); - } else { - ty = type; - } - if (!SwigType_ismutable(ty)) { - SetFlag(n, "hasconsttype"); - SetFlag(n, "feature:immutable"); - } - if (tmp) - Delete(tmp); - } - if (!type) { - Printf(stderr, "notype name %s\n", name); - } - } - } - Swig_features_get(Swig_cparse_features(), 0, name, 0, n); - if (makename) { - symname = make_name(n, makename, 0); - Delattr(n, "parser:makename"); /* temporary information, don't leave it hanging around */ - } else { - makename = name; - symname = make_name(n, makename, 0); - } - - if (!symname) { - symname = Copy(Getattr(n, "unnamed")); - } - if (symname) { - wrn = Swig_name_warning(n, 0, symname, 0); - } - } else { - String *name = Getattr(n, "name"); - SwigType *fdecl = Copy(decl); - SwigType *fun = SwigType_pop_function(fdecl); - if (iscdecl) { - Setattr(n, "kind", "function"); - } - - Swig_features_get(Swig_cparse_features(), 0, name, fun, n); - - symname = make_name(n, name, fun); - wrn = Swig_name_warning(n, 0, symname, fun); - - Delete(fdecl); - Delete(fun); - - } - if (!symname) - return; - if (GetFlag(n, "feature:ignore")) { - /* Only add to C symbol table and continue */ - Swig_symbol_add(0, n); - } else if (strncmp(Char(symname), "$ignore", 7) == 0) { - char *c = Char(symname) + 7; - SetFlag(n, "feature:ignore"); - if (strlen(c)) { - SWIG_WARN_NODE_BEGIN(n); - Swig_warning(0, Getfile(n), Getline(n), "%s\n", c + 1); - SWIG_WARN_NODE_END(n); - } - Swig_symbol_add(0, n); - } else { - Node *c; - if ((wrn) && (Len(wrn))) { - String *metaname = symname; - if (!Getmeta(metaname, "already_warned")) { - SWIG_WARN_NODE_BEGIN(n); - Swig_warning(0, Getfile(n), Getline(n), "%s\n", wrn); - SWIG_WARN_NODE_END(n); - Setmeta(metaname, "already_warned", "1"); - } - } - c = Swig_symbol_add(symname, n); - - if (c != n) { - /* symbol conflict attempting to add in the new symbol */ - if (Getattr(n, "sym:weak")) { - Setattr(n, "sym:name", symname); - } else { - String *e = NewStringEmpty(); - String *en = NewStringEmpty(); - String *ec = NewStringEmpty(); - int redefined = Swig_need_redefined_warn(n, c, true); - if (redefined) { - Printf(en, "Identifier '%s' redefined (ignored)", symname); - Printf(ec, "previous definition of '%s'", symname); - } else { - Printf(en, "Redundant redeclaration of '%s'", symname); - Printf(ec, "previous declaration of '%s'", symname); - } - if (Cmp(symname, Getattr(n, "name"))) { - Printf(en, " (Renamed from '%s')", SwigType_namestr(Getattr(n, "name"))); - } - Printf(en, ","); - if (Cmp(symname, Getattr(c, "name"))) { - Printf(ec, " (Renamed from '%s')", SwigType_namestr(Getattr(c, "name"))); - } - Printf(ec, "."); - SWIG_WARN_NODE_BEGIN(n); - if (redefined) { - Swig_warning(WARN_PARSE_REDEFINED, Getfile(n), Getline(n), "%s\n", en); - Swig_warning(WARN_PARSE_REDEFINED, Getfile(c), Getline(c), "%s\n", ec); - } else { - Swig_warning(WARN_PARSE_REDUNDANT, Getfile(n), Getline(n), "%s\n", en); - Swig_warning(WARN_PARSE_REDUNDANT, Getfile(c), Getline(c), "%s\n", ec); - } - SWIG_WARN_NODE_END(n); - Printf(e, "%s:%d:%s\n%s:%d:%s\n", Getfile(n), Getline(n), en, Getfile(c), Getline(c), ec); - Setattr(n, "error", e); - Delete(e); - Delete(en); - Delete(ec); - } - } - } - Delete(symname); -} - -/* Strips C-style and C++-style comments from string in-place. */ -static void strip_comments(char *string) { - int state = 0; - /* - * 0 - not in comment - * 1 - in c-style comment - * 2 - in c++-style comment - * 3 - in string - * 4 - after reading / not in comments - * 5 - after reading * in c-style comments - * 6 - after reading \ in strings - */ - char *c = string; - while (*c) { - switch (state) { - case 0: - if (*c == '\"') - state = 3; - else if (*c == '/') - state = 4; - break; - case 1: - if (*c == '*') - state = 5; - *c = ' '; - break; - case 2: - if (*c == '\n') - state = 0; - else - *c = ' '; - break; - case 3: - if (*c == '\"') - state = 0; - else if (*c == '\\') - state = 6; - break; - case 4: - if (*c == '/') { - *(c - 1) = ' '; - *c = ' '; - state = 2; - } else if (*c == '*') { - *(c - 1) = ' '; - *c = ' '; - state = 1; - } else - state = 0; - break; - case 5: - if (*c == '/') - state = 0; - else - state = 1; - *c = ' '; - break; - case 6: - state = 3; - break; - } - ++c; - } -} - -// Create a %insert with a typedef to make a new name visible to C -static Node *create_insert(Node *n, bool noTypedef = false) { - // format a typedef - String *ccode = Getattr(n, "code"); - Push(ccode, " "); - if (noTypedef) { - Push(ccode, Getattr(n, "name")); - Push(ccode, " "); - Push(ccode, Getattr(n, "kind")); - } else { - Push(ccode, Getattr(n, "kind")); - Push(ccode, "typedef "); - Append(ccode, " "); - Append(ccode, Getattr(n, "tdname")); - } - Append(ccode, ";"); - - /* Strip comments - further code may break in presence of comments. */ - strip_comments(Char(ccode)); - - /* Make all SWIG created typedef structs/unions/classes unnamed else - redefinition errors occur - nasty hack alert. */ - if (!noTypedef) { - const char *types_array[3] = { "struct", "union", "class" }; - for (int i = 0; i < 3; i++) { - char *code_ptr = Char(ccode); - while (code_ptr) { - /* Replace struct name (as in 'struct name {...}' ) with whitespace - name will be between struct and opening brace */ - - code_ptr = strstr(code_ptr, types_array[i]); - if (code_ptr) { - char *open_bracket_pos; - code_ptr += strlen(types_array[i]); - open_bracket_pos = strchr(code_ptr, '{'); - if (open_bracket_pos) { - /* Make sure we don't have something like struct A a; */ - char *semi_colon_pos = strchr(code_ptr, ';'); - if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos))) - while (code_ptr < open_bracket_pos) - *code_ptr++ = ' '; - } - } - } - } - } - { - /* Remove SWIG directive %constant which may be left in the SWIG created typedefs */ - char *code_ptr = Char(ccode); - while (code_ptr) { - code_ptr = strstr(code_ptr, "%constant"); - if (code_ptr) { - char *directive_end_pos = strchr(code_ptr, ';'); - if (directive_end_pos) { - while (code_ptr <= directive_end_pos) - *code_ptr++ = ' '; - } - } - } - } - Node *newnode = NewHash(); - set_nodeType(newnode, "insert"); - Setfile(newnode, Getfile(n)); - Setline(newnode, Getline(n)); - String *code = NewStringEmpty(); - Wrapper_pretty_print(ccode, code); - Setattr(newnode, "code", code); - Delete(code); - Delattr(n, "code"); - return newnode; -} - -static void insertNodeAfter(Node *n, Node *c) { - Node *g = parentNode(n); - set_parentNode(c, g); - Node *ns = nextSibling(n); - if (Node *outer = Getattr(c, "nested:outer")) { - while (ns && outer == Getattr(ns, "nested:outer")) { - n = ns; - ns = nextSibling(n); - } - } - if (!ns) { - set_lastChild(g, c); - } else { - set_nextSibling(c, ns); - set_previousSibling(ns, c); - } - set_nextSibling(n, c); - set_previousSibling(c, n); -} - -void Swig_nested_name_unnamed_c_structs(Node *n) { - if (!n) - return; - if (!classhash) - classhash = Getattr(n, "classes"); - Node *c = firstChild(n); - while (c) { - Node *next = nextSibling(c); - if (String *declName = Getattr(c, "nested:unnamed")) { - if (Node *outer = Getattr(c, "nested:outer")) { - // generate a name - String *name = NewStringf("%s_%s", Getattr(outer, "name"), declName); - Delattr(c, "nested:unnamed"); - // set the name to the class and symbol table - Setattr(c, "tdname", name); - Setattr(c, "name", name); - Swig_symbol_setscope(Getattr(c, "symtab")); - Swig_symbol_setscopename(name); - // now that we have a name - gather base symbols - if (List *publicBases = Getattr(c, "baselist")) { - List *bases = Swig_make_inherit_list(name, publicBases, 0); - Swig_inherit_base_symbols(bases); - Delete(bases); - } - Setattr(classhash, name, c); - - // Merge the extension into the symbol table - if (Node *am = Getattr(Swig_extend_hash(), name)) { - Swig_extend_merge(c, am); - Swig_extend_append_previous(c, am); - Delattr(Swig_extend_hash(), name); - } - Swig_symbol_popscope(); - - // process declarations following this type (assign correct new type) - SwigType *ty = Copy(name); - Node *decl = nextSibling(c); - List *declList = NewList(); - while (decl && Getattr(decl, "nested:unnamedtype") == c) { - Setattr(decl, "type", ty); - Append(declList, decl); - Delattr(decl, "nested:unnamedtype"); - SetFlag(decl, "feature:immutable"); - add_symbols_c(decl); - decl = nextSibling(decl); - } - Delete(ty); - Swig_symbol_setscope(Swig_symbol_global_scope()); - add_symbols_c(c); - - Node *ins = create_insert(c); - insertNodeAfter(c, ins); - removeNode(c); - insertNodeAfter(n, c); - Delete(ins); - Delattr(c, "nested:outer"); - } else { - // global unnamed struct - ignore it and its instances - SetFlag(c, "feature:ignore"); - while (next && Getattr(next, "nested:unnamedtype") == c) { - SetFlag(next, "feature:ignore"); - next = nextSibling(next); - } - c = next; - continue; - } - } else if (cparse_cplusplusout) { - if (Getattr(c, "nested:outer")) { - Node *ins = create_insert(c, true); - insertNodeAfter(c, ins); - Delete(ins); - Delattr(c, "nested:outer"); - } - } - // process children - Swig_nested_name_unnamed_c_structs(c); - c = next; - } -} - -static void remove_outer_class_reference(Node *n) { - for (Node *c = firstChild(n); c; c = nextSibling(c)) { - if (GetFlag(c, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None) { - Delattr(c, "nested:outer"); - remove_outer_class_reference(c); - } - } -} - -void Swig_nested_process_classes(Node *n) { - if (!n) - return; - Node *c = firstChild(n); - while (c) { - Node *next = nextSibling(c); - if (!Getattr(c, "templatetype")) { - if (GetFlag(c, "nested") && (GetFlag(c, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None)) { - removeNode(c); - if (!checkAttribute(c, "access", "public")) - SetFlag(c, "feature:ignore"); - else if (Strcmp(nodeType(n),"extend") == 0 && Strcmp(nodeType(parentNode(n)),"class") == 0) - insertNodeAfter(parentNode(n), c); - else - insertNodeAfter(n, c); - } - Swig_nested_process_classes(c); - } - c = next; - } - remove_outer_class_reference(n); -} - diff --git a/contrib/tools/swig/Source/Modules/ocaml.cxx b/contrib/tools/swig/Source/Modules/ocaml.cxx deleted file mode 100644 index 963a0c2d102..00000000000 --- a/contrib/tools/swig/Source/Modules/ocaml.cxx +++ /dev/null @@ -1,1848 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * ocaml.cxx - * - * Ocaml language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include <ctype.h> - -static const char *usage = "\ -Ocaml Options (available with -ocaml)\n\ - -oldvarnames - Old intermediary method names for variable wrappers\n\ - -prefix <name> - Set a prefix <name> to be prepended to all names\n\ - -suffix <name> - Deprecated alias for general option -cppext\n\ - -where - Emit library location\n\ -\n"; - -static int classmode = 0; -static int in_constructor = 0, in_destructor = 0, in_copyconst = 0; -static int const_enum = 0; -static int static_member_function = 0; -static int generate_sizeof = 0; -static String *prefix = 0; -static const char *ocaml_path = "ocaml"; -static bool old_variable_names = false; -static String *classname = 0; -static String *module = 0; -static String *init_func_def = 0; -static String *f_classtemplate = 0; -static SwigType *name_qualifier_type = 0; - -static Hash *seen_enums = 0; -static Hash *seen_enumvalues = 0; -static Hash *seen_constructors = 0; - -static File *f_header = 0; -static File *f_begin = 0; -static File *f_runtime = 0; -static File *f_wrappers = 0; -static File *f_directors = 0; -static File *f_directors_h = 0; -static File *f_init = 0; -static File *f_mlout = 0; -static File *f_mliout = 0; -static File *f_mlbody = 0; -static File *f_mlibody = 0; -static File *f_mltail = 0; -static File *f_mlitail = 0; -static File *f_enumtypes_type = 0; -static File *f_enumtypes_value = 0; -static File *f_class_ctors = 0; -static File *f_class_ctors_end = 0; -static File *f_enum_to_int = 0; -static File *f_int_to_enum = 0; - -class OCAML:public Language { -public: - - OCAML() { - director_prot_ctor_code = NewString(""); - Printv(director_prot_ctor_code, - "if ( $comparison ) { /* subclassed */\n", - " $director_new \n", "} else {\n", " caml_failwith(\"accessing abstract class or protected constructor\"); \n", "}\n", NIL); - director_multiple_inheritance = 1; - director_language = 1; - } - - String *Swig_class_name(Node *n) { - String *name; - name = Copy(Getattr(n, "sym:name")); - return name; - } - - void PrintIncludeArg() { - Printv(stdout, SWIG_LIB, SWIG_FILE_DELIMITER, ocaml_path, "\n", NIL); - } - - /* ------------------------------------------------------------ - * main() - * ------------------------------------------------------------ */ - - virtual void main(int argc, char *argv[]) { - int i; - - prefix = 0; - - SWIG_library_directory(ocaml_path); - - // Look for certain command line options - for (i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-help") == 0) { - fputs(usage, stdout); - Exit(EXIT_SUCCESS); - } else if (strcmp(argv[i], "-where") == 0) { - PrintIncludeArg(); - Exit(EXIT_SUCCESS); - } else if (strcmp(argv[i], "-prefix") == 0) { - if (argv[i + 1]) { - prefix = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-suffix") == 0) { - if (argv[i + 1]) { - Printf(stderr, "swig: warning: -suffix option deprecated. SWIG 3.0.4 and later provide a -cppext option which should be used instead.\n"); - SWIG_config_cppext(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else - Swig_arg_error(); - } else if (strcmp(argv[i], "-oldvarnames") == 0) { - Swig_mark_arg(i); - old_variable_names = true; - } - } - } - - // If a prefix has been specified make sure it ends in a '_' (not actually used!) - if (prefix) { - const char *px = Char(prefix); - if (px[Len(prefix) - 1] != '_') - Printf(prefix, "_"); - } else - prefix = NewString("swig_"); - - // Add a symbol for this module - - Preprocessor_define("SWIGOCAML 1", 0); - // Set name of typemaps - - SWIG_typemap_lang("ocaml"); - - // Read in default typemaps */ - SWIG_config_file("ocaml.i"); - allow_overloading(); - - } - - /* Swig_director_declaration() - * - * Generate the full director class declaration, complete with base classes. - * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {" - * - */ - - String *Swig_director_declaration(Node *n) { - String *classname = Swig_class_name(n); - String *directorname = NewStringf("SwigDirector_%s", classname); - String *base = Getattr(n, "classtype"); - String *declaration = Swig_class_declaration(n, directorname); - Printf(declaration, " : public %s, public Swig::Director {\n", base); - Delete(classname); - Delete(directorname); - return declaration; - } - - void emitBanner(File *f) { - Printf(f, "(* ----------------------------------------------------------------------------\n"); - Swig_banner_target_lang(f, " *"); - Printf(f, " * ---------------------------------------------------------------------------- *)\n\n"); - } - - /* ------------------------------------------------------------ - * top() - * - * Recognize the %module, and capture the module name. - * Create the default enum cases. - * Set up the named outputs: - * - * init - * ml - * mli - * wrapper - * header - * runtime - * directors - * directors_h - * ------------------------------------------------------------ */ - - virtual int top(Node *n) { - /* Set comparison with none for ConstructorToFunction */ - setSubclassInstanceCheck(NewString("caml_list_nth(args,0) != Val_unit")); - - /* check if directors are enabled for this module. note: this - * is a "master" switch, without which no director code will be - * emitted. %feature("director") statements are also required - * to enable directors for individual classes or methods. - * - * use %module(directors="1") modulename at the start of the - * interface file to enable director generation. - */ - String *mod_docstring = NULL; - { - Node *module = Getattr(n, "module"); - if (module) { - Node *options = Getattr(module, "options"); - if (options) { - if (Getattr(options, "directors")) { - allow_directors(); - } - if (Getattr(options, "dirprot")) { - allow_dirprot(); - } - if (Getattr(options, "sizeof")) { - generate_sizeof = 1; - } - mod_docstring = Getattr(options, "docstring"); - } - } - } - - /* Initialize all of the output files */ - String *outfile = Getattr(n, "outfile"); - - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - f_wrappers = NewString(""); - f_directors = NewString(""); - f_directors_h = NewString(""); - f_enumtypes_type = NewString(""); - f_enumtypes_value = NewString(""); - init_func_def = NewString(""); - f_mlbody = NewString(""); - f_mlibody = NewString(""); - f_mltail = NewString(""); - f_mlitail = NewString(""); - f_class_ctors = NewString(""); - f_class_ctors_end = NewString(""); - f_enum_to_int = NewString(""); - f_int_to_enum = NewString(""); - f_classtemplate = NewString(""); - - module = Getattr(n, "name"); - - seen_constructors = NewHash(); - seen_enums = NewHash(); - seen_enumvalues = NewHash(); - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("init", init_func_def); - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("mli", f_mlibody); - Swig_register_filebyname("ml", f_mlbody); - Swig_register_filebyname("mlitail", f_mlitail); - Swig_register_filebyname("mltail", f_mltail); - Swig_register_filebyname("director", f_directors); - Swig_register_filebyname("director_h", f_directors_h); - Swig_register_filebyname("classtemplate", f_classtemplate); - Swig_register_filebyname("class_ctors", f_class_ctors); - - if (old_variable_names) { - Swig_name_register("set", "%n%v__set__"); - Swig_name_register("get", "%n%v__get__"); - } - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "OCAML"); - - Printf(f_runtime, "#define SWIG_MODULE \"%s\"\n", module); - /* Module name */ - Printf(f_mlbody, "let module_name = \"%s\"\n", module); - Printf(f_mlibody, "val module_name : string\n"); - Printf(f_enum_to_int, - "let enum_to_int x (v : c_obj) =\n" - " match v with\n" - " C_enum _y ->\n" - " (let y = _y in match (x : c_enum_type) with\n" - " `unknown -> " " (match y with\n" " `Int x -> (Swig.C_int x)\n" " | _ -> raise (LabelNotFromThisEnum v))\n"); - - Printf(f_int_to_enum, "let int_to_enum x y =\n" " match (x : c_enum_type) with\n" " `unknown -> C_enum (`Int y)\n"); - - if (directorsEnabled()) { - Printf(f_runtime, "#define SWIG_DIRECTORS\n"); - } - - Printf(f_runtime, "\n"); - - /* Produce the enum_to_int and int_to_enum functions */ - - Printf(f_enumtypes_type, "open Swig\n" "type c_enum_type = [ \n `unknown\n"); - Printf(f_enumtypes_value, "type c_enum_value = [ \n `Int of int\n"); - String *mlfile = NewString(""); - String *mlifile = NewString(""); - - Printv(mlfile, module, ".ml", NIL); - Printv(mlifile, module, ".mli", NIL); - - String *mlfilen = NewStringf("%s%s", SWIG_output_directory(), mlfile); - if ((f_mlout = NewFile(mlfilen, "w", SWIG_output_files())) == 0) { - FileErrorDisplay(mlfilen); - Exit(EXIT_FAILURE); - } - String *mlifilen = NewStringf("%s%s", SWIG_output_directory(), mlifile); - if ((f_mliout = NewFile(mlifilen, "w", SWIG_output_files())) == 0) { - FileErrorDisplay(mlifilen); - Exit(EXIT_FAILURE); - } - emitBanner(f_mlout); - emitBanner(f_mliout); - - Language::top(n); - - if (mod_docstring) { - if (Len(mod_docstring)) { - Printv(f_mliout, "(** ", mod_docstring, " *)\n", NIL); - } - Delete(mod_docstring); - mod_docstring = NULL; - } - - Printf(f_enum_to_int, ") | _ -> (C_int (get_int v))\n" "let _ = Callback.register \"%s_enum_to_int\" enum_to_int\n", module); - Printf(f_mlibody, "val enum_to_int : c_enum_type -> c_obj -> Swig.c_obj\n"); - - Printf(f_int_to_enum, "let _ = Callback.register \"%s_int_to_enum\" int_to_enum\n", module); - Printf(f_mlibody, "val int_to_enum : c_enum_type -> int -> c_obj\n"); - Printf(f_init, "#define SWIG_init f_%s_init\n" "%s" "}\n", module, init_func_def); - Printf(f_mlbody, "external f_init : unit -> unit = \"f_%s_init\" ;;\n" "let _ = f_init ()\n", module); - Printf(f_enumtypes_type, "]\n"); - Printf(f_enumtypes_value, "]\n\n" "type c_obj = c_enum_value c_obj_t\n"); - - if (directorsEnabled()) { - // Insert director runtime into the f_runtime file (make it occur before %header section) - Swig_insert_file("director_common.swg", f_runtime); - Swig_insert_file("director.swg", f_runtime); - } - - SwigType_emit_type_table(f_runtime, f_wrappers); - /* Close all of the files */ - Dump(f_runtime, f_begin); - Dump(f_directors_h, f_header); - Dump(f_header, f_begin); - Dump(f_directors, f_wrappers); - Dump(f_wrappers, f_begin); - Wrapper_pretty_print(f_init, f_begin); - Delete(f_header); - Delete(f_wrappers); - Delete(f_init); - Delete(f_runtime); - Delete(f_begin); - - Dump(f_enumtypes_type, f_mlout); - Dump(f_enumtypes_value, f_mlout); - Dump(f_mlbody, f_mlout); - Dump(f_enum_to_int, f_mlout); - Dump(f_int_to_enum, f_mlout); - Delete(f_int_to_enum); - Delete(f_enum_to_int); - Dump(f_class_ctors, f_mlout); - Dump(f_class_ctors_end, f_mlout); - Dump(f_mltail, f_mlout); - Delete(f_mlout); - - Dump(f_enumtypes_type, f_mliout); - Dump(f_enumtypes_value, f_mliout); - Dump(f_mlibody, f_mliout); - Dump(f_mlitail, f_mliout); - Delete(f_mliout); - - return SWIG_OK; - } - - /* Produce an error for the given type */ - void throw_unhandled_ocaml_type_error(SwigType *d, const char *types) { - Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s (%s).\n", SwigType_str(d, 0), types); - } - - /* Return true iff T is a pointer type */ - int - is_a_pointer(SwigType *t) { - return SwigType_ispointer(SwigType_typedef_resolve_all(t)); - } - - /* - * Delete one reference from a given type. - */ - - void oc_SwigType_del_reference(SwigType *t) { - if (SwigType_isqualifier(t)) { - SwigType_del_qualifier(t); - } - SwigType_del_reference(t); - } - - void oc_SwigType_del_array(SwigType *t) { - if (SwigType_isqualifier(t)) { - SwigType_del_qualifier(t); - } - if (SwigType_isarray(t)) { - SwigType_del_array(t); - } - } - - /* - * Return true iff T is a reference type - */ - - int - is_a_reference(SwigType *t) { - return SwigType_isreference(SwigType_typedef_resolve_all(t)); - } - - int - is_an_array(SwigType *t) { - return SwigType_isarray(SwigType_typedef_resolve_all(t)); - } - - virtual int membervariableHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - Language::membervariableHandler(n); - - String *mname = Swig_name_member(NSPACE_TODO, classname, symname); - String *getname = Swig_name_get(NSPACE_TODO, mname); - String *mangled_getname = mangleNameForCaml(getname); - Delete(getname); - - if (!GetFlag(n, "feature:immutable")) { - String *setname = Swig_name_set(NSPACE_TODO, mname); - String *mangled_setname = mangleNameForCaml(setname); - Delete(setname); - Printf(f_class_ctors, " \"[%s]\", (fun args -> " "if args = (C_list [ raw_ptr ]) then _%s args else _%s args) ;\n", symname, mangled_getname, mangled_setname); - Delete(mangled_setname); - } else { - Printf(f_class_ctors, " \"[%s]\", (fun args -> " "if args = (C_list [ raw_ptr ]) then _%s args else C_void) ;\n", symname, mangled_getname); - } - Delete(mangled_getname); - Delete(mname); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * functionWrapper() - * Create a function declaration and register it with the interpreter. - * ------------------------------------------------------------ */ - - virtual int functionWrapper(Node *n) { - char *iname = GetChar(n, "sym:name"); - SwigType *d = Getattr(n, "type"); - String *return_type_normalized = normalizeTemplatedClassName(d); - ParmList *l = Getattr(n, "parms"); - int director_method = 0; - Parm *p; - - Wrapper *f = NewWrapper(); - String *proc_name = NewString(""); - String *target = NewString(""); - String *arg = NewString(""); - String *cleanup = NewString(""); - String *outarg = NewString(""); - String *build = NewString(""); - String *tm; - int i = 0; - int numargs; - int numreq; - int newobj = GetFlag(n, "feature:new"); - String *nodeType = Getattr(n, "nodeType"); - int destructor = (!Cmp(nodeType, "destructor")); - String *overname = 0; - bool isOverloaded = Getattr(n, "sym:overloaded") ? true : false; - // For overloaded functions, only the dispatch function needs to be exposed in the ml and mli files. - bool expose_func = !isOverloaded || !Getattr(n, "sym:nextSibling"); - - // Make a wrapper name for this - String *wname = Swig_name_wrapper(iname); - if (isOverloaded) { - overname = Getattr(n, "sym:overname"); - } else { - if (!addSymbol(iname, n)) { - DelWrapper(f); - return SWIG_ERROR; - } - } - if (overname) { - Append(wname, overname); - } - /* Do this to disambiguate functions emitted from different modules */ - Append(wname, module); - - Setattr(n, "wrap:name", wname); - - // Build the name for Scheme. - Printv(proc_name, "_", iname, NIL); - String *mangled_name = mangleNameForCaml(proc_name); - - if (classmode && in_constructor && expose_func) { // Emit constructor for object - String *mangled_name_nounder = NewString((char *) (Char(mangled_name)) + 1); - Printf(f_class_ctors_end, "let %s clst = _%s clst\n", mangled_name_nounder, mangled_name_nounder); - Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name_nounder); - Delete(mangled_name_nounder); - } else if (classmode && in_destructor) { - Printf(f_class_ctors, " \"~\", %s ;\n", mangled_name); - } else if (classmode && !in_constructor && !in_destructor && !static_member_function && - !Getattr(n, "membervariableHandler:sym:name") && expose_func) { - String *opname = Copy(Getattr(n, "memberfunctionHandler:sym:name")); - - Replaceall(opname, "operator ", ""); - Printf(f_class_ctors, " \"%s\", %s ;\n", opname, mangled_name); - Delete(opname); - } - - if (classmode && in_constructor) { - Setattr(seen_constructors, mangled_name, "true"); - } - // writing the function wrapper function - Printv(f->def, "SWIGEXT CAML_VALUE ", wname, " (", NIL); - Printv(f->def, "CAML_VALUE args", NIL); - Printv(f->def, ")\n{", NIL); - - /* Define the scheme name in C. This define is used by several - macros. */ - //Printv(f->def, "#define FUNC_NAME \"", mangled_name, "\"", NIL); - - // adds local variables - Wrapper_add_local(f, "args", "CAMLparam1(args)"); - Wrapper_add_local(f, "ret", "SWIG_CAMLlocal2(swig_result,rv)"); - d = SwigType_typedef_qualified(d); - emit_parameter_variables(l, f); - - /* Attach the standard typemaps */ - emit_attach_parmmaps(l, f); - Setattr(n, "wrap:parms", l); - - numargs = emit_num_arguments(l); - numreq = emit_num_required(l); - if (!isOverloaded) { - if (numargs > 0) { - if (numreq > 0) { - Printf(f->code, "if (caml_list_length(args) < %d || caml_list_length(args) > %d) {\n", numreq, numargs); - } else { - Printf(f->code, "if (caml_list_length(args) > %d) {\n", numargs); - } - Printf(f->code, "caml_invalid_argument(\"Incorrect number of arguments passed to '%s'\");\n}\n", iname); - } else { - Printf(f->code, "if (caml_list_length(args) > 0) caml_invalid_argument(\"'%s' takes no arguments\");\n", iname); - } - } - Printf(f->code, "swig_result = Val_unit;\n"); - - // Now write code to extract the parameters (this is super ugly) - - for (i = 0, p = l; i < numargs; i++) { - /* Skip ignored arguments */ - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *ln = Getattr(p, "lname"); - pt = SwigType_typedef_qualified(pt); - - // Produce names of source and target - Clear(target); - Clear(arg); - String *source = NewStringf("caml_list_nth(args,%d)", i); - Printf(target, "%s", ln); - Printv(arg, Getattr(p, "name"), NIL); - - if (i >= numreq) { - Printf(f->code, "if (caml_list_length(args) > %d) {\n", i); - } - // Handle parameter types. - if ((tm = Getattr(p, "tmap:in"))) { - Replaceall(tm, "$input", source); - Setattr(p, "emit:input", source); - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:in:next"); - } else { - // no typemap found - // check if typedef and resolve - throw_unhandled_ocaml_type_error(pt, "in"); - p = nextSibling(p); - } - if (i >= numreq) { - Printf(f->code, "}\n"); - } - Delete(source); - } - - /* Insert constraint checking code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - - // Pass output arguments back to the caller. - - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - Replaceall(tm, "$arg", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Replaceall(tm, "$ntype", normalizeTemplatedClassName(Getattr(p, "type"))); - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - // Free up any memory allocated for the arguments. - - /* Insert cleanup code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:freearg"))) { - Printv(cleanup, tm, "\n", NIL); - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - /* if the object is a director, and the method call originated from its - * underlying ocaml object, resolve the call by going up the c++ - * inheritance chain. otherwise try to resolve the method in ocaml. - * without this check an infinite loop is set up between the director and - * shadow class method calls. - */ - - // NOTE: this code should only be inserted if this class is the - // base class of a director class. however, in general we haven't - // yet analyzed all classes derived from this one to see if they are - // directors. furthermore, this class may be used as the base of - // a director class defined in a completely different module at a - // later time, so this test must be included whether or not directorbase - // is true. we do skip this code if directors have not been enabled - // at the command line to preserve source-level compatibility with - // non-polymorphic swig. also, if this wrapper is for a smart-pointer - // method, there is no need to perform the test since the calling object - // (the smart-pointer) and the director object (the "pointee") are - // distinct. - - director_method = is_member_director(n) && !is_smart_pointer() && !destructor; - if (director_method) { - Wrapper_add_local(f, "director", "Swig::Director *director = 0"); - Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n"); - Wrapper_add_local(f, "upcall", "bool upcall = false"); - Append(f->code, "upcall = (director);\n"); - } - - // Now write code to make the function call - Swig_director_emit_dynamic_cast(n, f); - String *actioncode = emit_action(n); - - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { - Replaceall(tm, "$result", "rv"); - Replaceall(tm, "$ntype", return_type_normalized); - Printv(f->code, tm, "\n", NIL); - } else { - throw_unhandled_ocaml_type_error(d, "out"); - } - emit_return_variable(n, d, f); - - // Dump the argument output code - Printv(f->code, Char(outarg), NIL); - - // Dump the argument cleanup code - Printv(f->code, Char(cleanup), NIL); - - // Look for any remaining cleanup - - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - Printv(f->code, tm, "\n", NIL); - } - } - - /* See if there is any return cleanup code */ - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - Delete(tm); - } - - // Free any memory allocated by the function being wrapped.. - - if ((tm = Swig_typemap_lookup("swig_result", n, Swig_cresult_name(), 0))) { - Printv(f->code, tm, "\n", NIL); - } - // Wrap things up (in a manner of speaking) - - Printv(f->code, tab4, "swig_result = caml_list_append(swig_result,rv);\n", NIL); - Printv(f->code, tab4, "CAMLreturn(swig_result);\n", NIL); - Printv(f->code, "}\n", NIL); - - /* Substitute the function name */ - Replaceall(f->code, "$symname", iname); - - Wrapper_print(f, f_wrappers); - - if (isOverloaded) { - if (!Getattr(n, "sym:nextSibling")) { - int maxargs; - Wrapper *df = NewWrapper(); - String *dispatch = Swig_overload_dispatch(n, - "free(argv);\n" "CAMLreturn(%s(args));\n", - &maxargs); - - Wrapper_add_local(df, "argv", "CAML_VALUE *argv"); - - /* Undifferentiate name .. this is the dispatch function */ - wname = Swig_name_wrapper(iname); - /* Do this to disambiguate functions emitted from different - * modules */ - Append(wname, module); - - Printv(df->def, - "SWIGEXT CAML_VALUE ", wname, "(CAML_VALUE args) {\n" " CAMLparam1(args);\n" " int i;\n" " int argc = caml_list_length(args);\n", NIL); - Printv(df->code, - "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n" - "for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL); - Printv(df->code, dispatch, "\nfree(argv);\n", NIL); - Node *sibl = n; - while (Getattr(sibl, "sym:previousSibling")) - sibl = Getattr(sibl, "sym:previousSibling"); - String *protoTypes = NewString(""); - do { - String *fulldecl = Swig_name_decl(sibl); - Printf(protoTypes, "\n\" %s\\n\"", fulldecl); - Delete(fulldecl); - } while ((sibl = Getattr(sibl, "sym:nextSibling"))); - Printf(df->code, "caml_failwith(\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" - "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", iname, protoTypes); - Delete(protoTypes); - Printv(df->code, "}\n", NIL); - Wrapper_print(df, f_wrappers); - - DelWrapper(df); - Delete(dispatch); - } - } - - if (expose_func) { - Printf(f_mlbody, "external %s_f : c_obj list -> c_obj list = \"%s\" ;;\n", mangled_name, wname); - Printf(f_mlbody, "let %s arg = match %s_f (%s(fnhelper arg)) with\n", mangled_name, mangled_name, - in_constructor && Swig_directorclass(getCurrentClass()) ? "director_core_helper " : ""); - Printf(f_mlbody, " [] -> C_void\n" - "| [x] -> (if %s then Gc.finalise \n" - " (fun x -> ignore ((invoke x) \"~\" C_void)) x) ; x\n" - "| lst -> C_list lst ;;\n", newobj ? "true" : "false"); - } - - if ((!classmode || in_constructor || in_destructor || static_member_function) && expose_func) - Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name); - - Delete(proc_name); - Delete(target); - Delete(arg); - Delete(outarg); - Delete(cleanup); - Delete(build); - DelWrapper(f); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * variableWrapper() - * - * Create a link to a C variable. - * This creates a single function _wrap_varname(). - * This function takes a single optional argument. If supplied, it means - * we are setting this variable to some value. If omitted, it means we are - * simply evaluating this variable. We return the value of the variable - * in both cases. - * - * symname is the name of the variable with respect to C. This - * may need to differ from the original name in the case of enums. - * enumvname is the name of the variable with respect to ocaml. This - * will vary if the variable has been renamed. - * ------------------------------------------------------------ */ - - virtual int variableWrapper(Node *n) { - char *name = GetChar(n, "feature:symname"); - String *iname = Getattr(n, "feature:enumvname"); - String *mname = mangleNameForCaml(iname); - SwigType *t = Getattr(n, "type"); - - String *proc_name = NewString(""); - String *tm; - Wrapper *f; - - if (!name) { - name = GetChar(n, "name"); - } - - if (!iname) { - iname = Getattr(n, "sym:name"); - mname = mangleNameForCaml(NewString(iname)); - } - - if (!iname || !addSymbol(iname, n)) - return SWIG_ERROR; - - f = NewWrapper(); - - // evaluation function names - String *var_name = Swig_name_wrapper(iname); - - // Build the name for OCaml. - Printv(proc_name, iname, NIL); - Setattr(n, "wrap:name", proc_name); - - Printf(f->def, "SWIGEXT CAML_VALUE %s(CAML_VALUE args) {\n", var_name); - // Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); - - Wrapper_add_local(f, "args", "CAMLparam1(args)"); - Wrapper_add_local(f, "swig_result", "SWIG_CAMLlocal1(swig_result)"); - Printf(f->code, "swig_result = Val_unit;\n"); - - if (!GetFlag(n, "feature:immutable")) { - /* Check for a setting of the variable value */ - Printf(f->code, "if (args != Val_int(0)) {\n"); - if ((tm = Swig_typemap_lookup("varin", n, name, 0))) { - Replaceall(tm, "$input", "args"); - emit_action_code(n, f->code, tm); - } else if ((tm = Swig_typemap_lookup("in", n, name, 0))) { - Replaceall(tm, "$input", "args"); - emit_action_code(n, f->code, tm); - } else { - throw_unhandled_ocaml_type_error(t, "varin/in"); - } - Printf(f->code, "}\n"); - } - // Now return the value of the variable (regardless - // of evaluating or setting) - - if ((tm = Swig_typemap_lookup("varout", n, name, 0))) { - Replaceall(tm, "$result", "swig_result"); - emit_action_code(n, f->code, tm); - } else if ((tm = Swig_typemap_lookup("out", n, name, 0))) { - Replaceall(tm, "$result", "swig_result"); - emit_action_code(n, f->code, tm); - } else { - throw_unhandled_ocaml_type_error(t, "varout/out"); - } - - Printf(f->code, "\nCAMLreturn(swig_result);\n"); - Printf(f->code, "}\n"); - - Wrapper_print(f, f_wrappers); - - // Now add symbol to the Ocaml interpreter - - if (GetFlag(n, "feature:immutable")) { - Printf(f_mlbody, "external _%s : c_obj -> Swig.c_obj = \"%s\" \n", mname, var_name); - Printf(f_mlibody, "val _%s : c_obj -> Swig.c_obj\n", iname); - if (const_enum) { - Printf(f_enum_to_int, " | `%s -> _%s C_void\n", mname, mname); - Printf(f_int_to_enum, " if y = (get_int (_%s C_void)) then `%s else\n", mname, mname); - } - } else { - Printf(f_mlbody, "external _%s : c_obj -> c_obj = \"%s\"\n", mname, var_name); - Printf(f_mlibody, "external _%s : c_obj -> c_obj = \"%s\"\n", mname, var_name); - } - - Delete(var_name); - Delete(proc_name); - DelWrapper(f); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * staticmemberfunctionHandler -- - * Overridden to set static_member_function - * ------------------------------------------------------------ */ - - virtual int staticmemberfunctionHandler(Node *n) { - static_member_function = 1; - Language::staticmemberfunctionHandler(n); - static_member_function = 0; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constantWrapper() - * - * The one trick here is that we have to make sure we rename the - * constant to something useful that doesn't collide with the - * original if any exists. - * ------------------------------------------------------------ */ - - virtual int constantWrapper(Node *n) { - String *name = Getattr(n, "feature:symname"); - SwigType *type = Getattr(n, "type"); - String *rawval = Getattr(n, "rawval"); - String *value = rawval ? rawval : Getattr(n, "value"); - SwigType *qname = Getattr(n, "qualified:name"); - - if (qname) - value = qname; - - if (!name) { - name = mangleNameForCaml(Getattr(n, "name")); - Insert(name, 0, "_swig_wrap_"); - Setattr(n, "feature:symname", name); - } - // See if there's a typemap - - // Create variable and assign it a value - Printf(f_header, "static %s = %s;\n", SwigType_str(type, name), value); - SetFlag(n, "feature:immutable"); - variableWrapper(n); - return SWIG_OK; - } - - int constructorHandler(Node *n) { - int ret; - - in_constructor = 1; - ret = Language::constructorHandler(n); - in_constructor = 0; - - return ret; - } - - /* destructorHandler: - * Turn on destructor flag to inform decisions in functionWrapper - */ - - int destructorHandler(Node *n) { - int ret; - - in_destructor = 1; - ret = Language::destructorHandler(n); - in_destructor = 0; - - return ret; - } - - /* copyconstructorHandler: - * Turn on constructor and copyconstructor flags for functionWrapper - */ - - int copyconstructorHandler(Node *n) { - int ret; - - in_copyconst = 1; - in_constructor = 1; - ret = Language::copyconstructorHandler(n); - in_constructor = 0; - in_copyconst = 0; - - return ret; - } - - /** - * A simple, somewhat general purpose function for writing to multiple - * streams from a source template. This allows the user to define the - * class definition in ways different from the one I have here if they - * want to. It will also make the class definition system easier to - * fiddle with when I want to change methods, etc. - */ - - void Multiwrite(String *s) { - char *find_marker = strstr(Char(s), "(*Stream:"); - while (find_marker) { - char *next = strstr(find_marker, "*)"); - find_marker += strlen("(*Stream:"); - - if (next) { - int num_chars = (int)(next - find_marker); - String *stream_name = NewString(find_marker); - Delslice(stream_name, num_chars, Len(stream_name)); - File *fout = Swig_filebyname(stream_name); - if (fout) { - next += strlen("*)"); - char *following = strstr(next, "(*Stream:"); - find_marker = following; - if (!following) - following = next + strlen(next); - String *chunk = NewString(next); - Delslice(chunk, (int)(following - next), Len(chunk)); - Printv(fout, chunk, NIL); - } - } - } - } - - bool isSimpleType(String *name) { - char *ch = Char(name); - - return !(strchr(ch, '(') || strchr(ch, '<') || strchr(ch, ')') || strchr(ch, '>')); - } - - /* We accept all chars in identifiers because we use strings to index - * them. */ - int validIdentifier(String *name) { - return Len(name) > 0 ? 1 : 0; - } - - /* classHandler - * - * Create a "class" definition for ocaml. I thought quite a bit about - * how I should do this part of it, and arrived here, using a function - * invocation to select a method, and dispatch. This can obviously be - * done better, but I can't see how, given that I want to support - * overloaded methods, out parameters, and operators. - * - * I needed a system that would do this: - * - * a Be able to call these methods: - * int foo( int x ); - * float foo( int x, int &out ); - * - * b Be typeable, even in the presence of mutually dependent classes. - * - * c Support some form of operator invocation. - * - * (c) I chose strings for the method names so that "+=" would be a - * valid method name, and the somewhat natural << (invoke x) "+=" y >> - * would work. - * - * (a) (b) Since the c_obj type exists, it's easy to return C_int in one - * case and C_list [ C_float ; C_int ] in the other. This makes tricky - * problems with out parameters disappear; they're simply appended to the - * return list. - * - * (b) Since every item that comes from C++ is the same type, there is no - * problem with the following: - * - * class Foo; - * class Bar { Foo *toFoo(); } - * class Foo { Bar *toBar(); } - * - * Since the Objective caml types of Foo and Bar are the same. Now that - * I correctly incorporate SWIG's typechecking, this isn't a big deal. - * - * The class is in the form of a function returning a c_obj. The c_obj - * is a C_obj containing a function which invokes a method on the - * underlying object given its type. - * - * The name emitted here is normalized before being sent to - * Callback.register, because we need this string to look up properly - * when the typemap passes the descriptor string. I've been considering - * some, possibly more forgiving method that would do some transformations - * on the $descriptor in order to find a potential match. This is for - * later. - * - * Important things to note: - * - * We rely on exception handling (BadMethodName) in order to call an - * ancestor. This can be improved. - * - * The method used to get :classof could be improved to look at the type - * info that the base pointer contains. It's really an error to have a - * SWIG-generated object that does not contain type info, since the - * existence of the object means that SWIG knows the type. - * - * :parents could use :classof to tell what class it is and make a better - * decision. This could be nice, (i.e. provide a run-time graph of C++ - * classes represented);. - * - * I can't think of a more elegant way of converting a C_obj fun to a - * pointer than "operator &"... - * - * Added a 'sizeof' that will allow you to do the expected thing. - * This should help users to fill buffer structs and the like (as is - * typical in windows-styled code). It's only enabled if you give - * %feature(sizeof) and then, only for simple types. - * - * Overall, carrying the list of methods and base classes has worked well. - * It allows me to give the Ocaml user introspection over their objects. - */ - - int classHandler(Node *n) { - String *name = Getattr(n, "name"); - classname = Getattr(n, "sym:name"); - - if (!name) - return SWIG_OK; - - String *mangled_name = mangleNameForCaml(name); - String *this_class_def = NewString(f_classtemplate); - String *name_normalized = normalizeTemplatedClassName(name); - String *old_class_ctors = f_class_ctors; - String *base_classes = NewString(""); - f_class_ctors = NewString(""); - bool sizeof_feature = generate_sizeof && isSimpleType(name); - - - classmode = true; - int rv = Language::classHandler(n); - classmode = false; - - if (sizeof_feature) { - Printf(f_wrappers, - "SWIGEXT CAML_VALUE _wrap_%s_sizeof( CAML_VALUE args ) {\n" - " CAMLparam1(args);\n" " CAMLreturn(Val_int(sizeof(%s)));\n" "}\n", mangled_name, name_normalized); - - Printf(f_mlbody, "external __%s_sizeof : unit -> int = " "\"_wrap_%s_sizeof\"\n", mangled_name, mangled_name); - } - - - /* Insert sizeof operator for concrete classes */ - if (sizeof_feature) { - Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__", mangled_name, "_sizeof ())) ;\n", NIL); - } - /* Handle up-casts in a nice way */ - List *baselist = Getattr(n, "bases"); - if (baselist && Len(baselist)) { - Iterator b; - b = First(baselist); - while (b.item) { - String *bname = Getattr(b.item, "name"); - if (bname) { - String *base_create = NewString(""); - Printv(base_create, "(create_class \"", bname, "\")", NIL); - Printv(f_class_ctors, " \"::", bname, "\", (fun args -> ", base_create, " args) ;\n", NIL); - Printv(base_classes, base_create, " ;\n", NIL); - } - b = Next(b); - } - } - - Replaceall(this_class_def, "$classname", mangled_name); - Replaceall(this_class_def, "$normalized", name_normalized); - Replaceall(this_class_def, "$realname", name); - Replaceall(this_class_def, "$baselist", base_classes); - Replaceall(this_class_def, "$classbody", f_class_ctors); - - Delete(f_class_ctors); - f_class_ctors = old_class_ctors; - - // Actually write out the class definition - - Multiwrite(this_class_def); - - Setattr(n, "ocaml:ctor", mangled_name); - - return rv; - } - - String *normalizeTemplatedClassName(String *name) { - String *name_normalized = SwigType_typedef_resolve_all(name); - bool took_action; - - do { - took_action = false; - - if (is_a_pointer(name_normalized)) { - SwigType_del_pointer(name_normalized); - took_action = true; - } - - if (is_a_reference(name_normalized)) { - oc_SwigType_del_reference(name_normalized); - took_action = true; - } - - if (is_an_array(name_normalized)) { - oc_SwigType_del_array(name_normalized); - took_action = true; - } - } while (took_action); - - return SwigType_str(name_normalized, 0); - } - - /* - * Produce the symbol name that ocaml will use when referring to the - * target item. I wonder if there's a better way to do this: - * - * I shudder to think about doing it with a hash lookup, but that would - * make a couple of things easier: - */ - - String *mangleNameForCaml(String *s) { - String *out = Copy(s); - Replaceall(out, " ", "_xx"); - Replaceall(out, "::", "_xx"); - Replaceall(out, ",", "_x"); - Replaceall(out, "+", "_xx_plus"); - Replaceall(out, "-", "_xx_minus"); - Replaceall(out, "<", "_xx_ldbrace"); - Replaceall(out, ">", "_xx_rdbrace"); - Replaceall(out, "!", "_xx_not"); - Replaceall(out, "%", "_xx_mod"); - Replaceall(out, "^", "_xx_xor"); - Replaceall(out, "*", "_xx_star"); - Replaceall(out, "&", "_xx_amp"); - Replaceall(out, "|", "_xx_or"); - Replaceall(out, "(", "_xx_lparen"); - Replaceall(out, ")", "_xx_rparen"); - Replaceall(out, "[", "_xx_lbrace"); - Replaceall(out, "]", "_xx_rbrace"); - Replaceall(out, "~", "_xx_bnot"); - Replaceall(out, "=", "_xx_equals"); - Replaceall(out, "/", "_xx_slash"); - Replaceall(out, ".", "_xx_dot"); - return out; - } - - SwigType *fully_qualified_enum_type(Node *n) { - Node *parent = 0; - String *fully_qualified_name = NewString(""); - String *parent_type = 0; - - parent = parentNode(n); - while (parent) { - parent_type = nodeType(parent); - if (Getattr(parent, "name")) { - String *parent_copy = NewStringf("%s::", Getattr(parent, "name")); - if (Cmp(parent_type, "class") == 0 || Cmp(parent_type, "namespace") == 0) - Insert(fully_qualified_name, 0, parent_copy); - Delete(parent_copy); - } - if (!Cmp(parent_type, "class")) - break; - parent = parentNode(parent); - } - - return fully_qualified_name; - } - - /* Benedikt Grundmann inspired --> Enum wrap styles */ - - int enumvalueDeclaration(Node *n) { - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - SwigType *qtype = 0; - - if (name_qualifier_type) { - qtype = Copy(name_qualifier_type); - Printv(qtype, name, NIL); - } - - if (const_enum && qtype && symname && !Getattr(seen_enumvalues, symname)) { - Setattr(seen_enumvalues, symname, "true"); - SetFlag(n, "feature:immutable"); - Setattr(n, "feature:enumvalue", "1"); // this does not appear to be used - - Setattr(n, "qualified:name", SwigType_namestr(qtype)); - - String *evname = SwigType_manglestr(qtype); - Insert(evname, 0, "SWIG_ENUM_"); - - Setattr(n, "feature:enumvname", symname); - Setattr(n, "feature:symname", evname); - Delete(evname); - Printf(f_enumtypes_value, "| `%s\n", symname); - - return Language::enumvalueDeclaration(n); - } else - return SWIG_OK; - } - - /* ------------------------------------------------------------------- - * This function is a bit uglier than it deserves. - * - * I used to direct lookup the name of the enum. Now that certain fixes - * have been made in other places, the names of enums are now fully - * qualified, which is a good thing, overall, but requires me to do - * some legwork. - * - * The other thing that uglifies this function is the varying way that - * typedef enum and enum are handled. I need to produce consistent names, - * which means looking up and registering by typedef and enum name. */ - int enumDeclaration(Node *n) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - String *name = Getattr(n, "name"); - if (name) { - String *oname = NewString(name); - /* name is now fully qualified */ - String *fully_qualified_name = NewString(name); - bool seen_enum = false; - if (name_qualifier_type) - Delete(name_qualifier_type); - char *strip_position; - name_qualifier_type = fully_qualified_enum_type(n); - - strip_position = strstr(Char(oname), "::"); - - while (strip_position) { - strip_position += 2; - oname = NewString(strip_position); - strip_position = strstr(Char(oname), "::"); - } - - seen_enum = (Getattr(seen_enums, fully_qualified_name) ? true : false); - - if (!seen_enum) { - const_enum = true; - Printf(f_enum_to_int, "| `%s -> (match y with\n", oname); - Printf(f_int_to_enum, "| `%s -> C_enum (\n", oname); - /* * * * A note about enum name resolution * * * * - * This code should now work, but I think we can do a bit better. - * The problem I'm having is that swig isn't very precise about - * typedef name resolution. My opinion is that SwigType_typedef - * resolve_all should *always* return the enum tag if one exists, - * rather than the admittedly friendlier enclosing typedef. - * - * This would make one of the cases below unnecessary. - * * * */ - Printf(f_mlbody, "let _ = Callback.register \"%s_marker\" (`%s)\n", fully_qualified_name, oname); - if (!strncmp(Char(fully_qualified_name), "enum ", 5)) { - String *fq_noenum = NewString(Char(fully_qualified_name) + 5); - Printf(f_mlbody, - "let _ = Callback.register \"%s_marker\" (`%s)\n" "let _ = Callback.register \"%s_marker\" (`%s)\n", fq_noenum, oname, fq_noenum, name); - } - - Printf(f_enumtypes_type, "| `%s\n", oname); - Insert(fully_qualified_name, 0, "enum "); - Setattr(seen_enums, fully_qualified_name, n); - } - } - - int ret = Language::enumDeclaration(n); - - if (const_enum) { - Printf(f_int_to_enum, "`Int y)\n"); - Printf(f_enum_to_int, "| `Int x -> Swig.C_int x\n" "| _ -> raise (LabelNotFromThisEnum v))\n"); - } - - const_enum = false; - - return ret; - } - - /* ---------------------------------------------------------------------------- - * BEGIN C++ Director Class modifications - * ------------------------------------------------------------------------- */ - - /* - * Modified polymorphism code for Ocaml language module. - * - * TODO - * - * Move some boilerplate code generation to Swig_...() functions. - * - */ - - /* --------------------------------------------------------------- - * classDirectorMethod() - * - * Emit a virtual director method to pass a method call on to the - * underlying Python object. - * - * --------------------------------------------------------------- */ - - int classDirectorMethod(Node *n, Node *parent, String *super) { - int is_void = 0; - int is_pointer = 0; - String *storage = Getattr(n, "storage"); - String *value = Getattr(n, "value"); - String *decl = Getattr(n, "decl"); - String *returntype = Getattr(n, "type"); - String *name = Getattr(n, "name"); - String *classname = Getattr(parent, "sym:name"); - String *c_classname = Getattr(parent, "name"); - String *symname = Getattr(n, "sym:name"); - String *declaration = NewString(""); - ParmList *l = Getattr(n, "parms"); - Wrapper *w = NewWrapper(); - String *tm; - String *wrap_args = NewString(""); - int status = SWIG_OK; - int idx; - bool pure_virtual = false; - bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; - - if (Cmp(storage, "virtual") == 0) { - if (Cmp(value, "0") == 0) { - pure_virtual = true; - } - } - Printf(w->locals, "CAMLparam0();\n"); - - /* determine if the method returns a pointer */ - is_pointer = SwigType_ispointer_return(decl); - is_void = (!Cmp(returntype, "void") && !is_pointer); - - /* virtual method definition */ - String *target; - String *pclassname = NewStringf("SwigDirector_%s", classname); - String *qualified_name = NewStringf("%s::%s", pclassname, name); - SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type"); - target = Swig_method_decl(rtype, decl, qualified_name, l, 0); - Printf(w->def, "%s", target); - Delete(qualified_name); - Delete(target); - /* header declaration */ - target = Swig_method_decl(rtype, decl, name, l, 1); - Printf(declaration, " virtual %s", target); - Delete(target); - - // Get any exception classes in the throws typemap - if (Getattr(n, "noexcept")) { - Append(w->def, " noexcept"); - Append(declaration, " noexcept"); - } - ParmList *throw_parm_list = 0; - if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { - Parm *p; - int gencomma = 0; - - Append(w->def, " throw("); - Append(declaration, " throw("); - - if (throw_parm_list) - Swig_typemap_attach_parms("throws", throw_parm_list, 0); - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - if (gencomma++) { - Append(w->def, ", "); - Append(declaration, ", "); - } - String *str = SwigType_str(Getattr(p, "type"), 0); - Append(w->def, str); - Append(declaration, str); - Delete(str); - } - } - Append(w->def, ")"); - Append(declaration, ")"); - } - Append(w->def, " {"); - Append(declaration, ";\n"); - /* declare method return value - * if the return value is a reference or const reference, a specialized typemap must - * handle it, including declaration of c_result ($result). - */ - if (!is_void && (!ignored_method || pure_virtual)) { - if (!SwigType_isclass(returntype)) { - if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { - String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); - Delete(construct_result); - } else { - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); - } - } else { - String *cres = SwigType_lstr(returntype, "c_result"); - Printf(w->code, "%s;\n", cres); - Delete(cres); - } - } - - if (ignored_method) { - if (!pure_virtual) { - String *super_call = Swig_method_call(super, l); - if (is_void) - Printf(w->code, "%s;\n", super_call); - else - Printf(w->code, "CAMLreturn_type(%s);\n", super_call); - Delete(super_call); - } else { - Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname), - SwigType_namestr(name)); - } - } else { - Wrapper_add_local(w, "swig_result", "SWIG_CAMLlocal2(swig_result, args)"); - /* attach typemaps to arguments (C/C++ -> Ocaml) */ - String *arglist = NewString(""); - - Swig_director_parms_fixup(l); - - Swig_typemap_attach_parms("in", l, 0); - Swig_typemap_attach_parms("directorin", l, w); - Swig_typemap_attach_parms("directorargout", l, w); - - Parm *p; - int num_arguments = emit_num_arguments(l); - int i; - char source[256]; - - /* build argument list and type conversion string */ - for (i = 0, idx = 0, p = l; i < num_arguments; i++) { - - while (Getattr(p, "tmap:ignore")) { - p = Getattr(p, "tmap:ignore:next"); - } - - String *pname = Getattr(p, "name"); - String *ptype = Getattr(p, "type"); - - Putc(',', arglist); - if ((tm = Getattr(p, "tmap:directorin")) != 0) { - Setattr(p, "emit:directorinput", pname); - Replaceall(tm, "$input", pname); - Replaceall(tm, "$owner", "0"); - if (Len(tm) == 0) - Append(tm, pname); - Printv(wrap_args, tm, "\n", NIL); - p = Getattr(p, "tmap:directorin:next"); - continue; - } else if (Cmp(ptype, "void")) { - /* special handling for pointers to other C++ director classes. - * ideally this would be left to a typemap, but there is currently no - * way to selectively apply the dynamic_cast<> to classes that have - * directors. in other words, the type "SwigDirector_$1_lname" only exists - * for classes with directors. we avoid the problem here by checking - * module.wrap::directormap, but it's not clear how to get a typemap to - * do something similar. perhaps a new default typemap (in addition - * to SWIGTYPE) called DIRECTORTYPE? - */ - if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) { - Node *module = Getattr(parent, "module"); - Node *target = Swig_directormap(module, ptype); - sprintf(source, "obj%d", idx++); - String *nonconst = 0; - /* strip pointer/reference --- should move to Swig/stype.c */ - String *nptype = NewString(Char(ptype) + 2); - /* name as pointer */ - String *ppname = Copy(pname); - if (SwigType_isreference(ptype)) { - Insert(ppname, 0, "&"); - } - /* if necessary, cast away const since Python doesn't support it! */ - if (SwigType_isconst(nptype)) { - nonconst = NewStringf("nc_tmp_%s", pname); - String *nonconst_i = NewStringf("= const_cast< %s >(%s)", SwigType_lstr(ptype, 0), ppname); - Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL); - Delete(nonconst_i); - Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number, - "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(ptype, pname), - SwigType_namestr(c_classname), SwigType_namestr(name)); - } else { - nonconst = Copy(ppname); - } - Delete(nptype); - Delete(ppname); - String *mangle = SwigType_manglestr(ptype); - if (target) { - String *director = NewStringf("director_%s", mangle); - Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL); - Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL); - Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst); - Printf(wrap_args, "if (!%s) {\n", director); - Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); - Printf(wrap_args, "} else {\n"); - Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director); - Printf(wrap_args, "}\n"); - Delete(director); - Printv(arglist, source, NIL); - } else { - Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL); - Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); - //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n", - // source, nonconst, base); - Printv(arglist, source, NIL); - } - Delete(mangle); - Delete(nonconst); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, - "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), - SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_NOWRAP; - break; - } - } - p = nextSibling(p); - } - - Printv(w->code, "swig_result = Val_unit;\n", 0); - Printf(w->code, "args = Val_unit;\n"); - - /* wrap complex arguments to values */ - Printv(w->code, wrap_args, NIL); - - /* pass the method call on to the OCaml object */ - Printv(w->code, - "swig_result = caml_swig_alloc(1,C_list);\n" "SWIG_Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n", 0); - Printf(w->code, "static const CAML_VALUE *swig_ocaml_func_val = NULL;\n" "if (!swig_ocaml_func_val) {\n"); - Printf(w->code, " swig_ocaml_func_val = caml_named_value(\"swig_runmethod\");\n }\n"); - Printf(w->code, "swig_result = caml_callback3(*swig_ocaml_func_val,swig_get_self(),caml_copy_string(\"%s\"),args);\n", Getattr(n, "name")); - /* exception handling */ - tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0); - if (!tm) { - tm = Getattr(n, "feature:director:except"); - } - if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { - Printf(w->code, "if (!%s) {\n", Swig_cresult_name()); - Printf(w->code, " CAML_VALUE error = *caml_named_value(\"director_except\");\n"); - Replaceall(tm, "$error", "error"); - Printv(w->code, Str(tm), "\n", NIL); - Printf(w->code, "}\n"); - } - - /* - * Python method may return a simple object, or a tuple. - * for in/out arguments, we have to extract the appropriate values from the - * argument list, then marshal everything back to C/C++ (return value and - * output arguments). - */ - - /* marshal return value and other outputs (if any) from value to C/C++ - * type */ - - String *cleanup = NewString(""); - String *outarg = NewString(""); - - tm = Swig_typemap_lookup("directorout", n, "c_result", w); - if (tm != 0) { - Replaceall(tm, "$input", "swig_result"); - /* TODO check this */ - if (Getattr(n, "wrap:disown")) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - Replaceall(tm, "$result", "c_result"); - Printv(w->code, tm, "\n", NIL); - } - - /* marshal outputs */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:directorargout")) != 0) { - Replaceall(tm, "$result", "swig_result"); - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NIL); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } - } - - Delete(arglist); - Delete(cleanup); - Delete(outarg); - } - - /* any existing helper functions to handle this? */ - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { - String *rettype = SwigType_str(returntype, 0); - if (!SwigType_isreference(returntype)) { - Printf(w->code, "CAMLreturn_type((%s)c_result);\n", rettype); - } else { - Printf(w->code, "CAMLreturn_type((%s)*c_result);\n", rettype); - } - Delete(rettype); - } - } else { - Printf(w->code, "CAMLreturn0;\n"); - } - - Printf(w->code, "}\n"); - - // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method - String *inline_extra_method = NewString(""); - if (dirprot_mode() && !is_public(n) && !pure_virtual) { - Printv(inline_extra_method, declaration, NIL); - String *extra_method_name = NewStringf("%sSwigPublic", name); - Replaceall(inline_extra_method, name, extra_method_name); - Replaceall(inline_extra_method, ";\n", " {\n "); - if (!is_void) - Printf(inline_extra_method, "return "); - String *methodcall = Swig_method_call(super, l); - Printv(inline_extra_method, methodcall, ";\n }\n", NIL); - Delete(methodcall); - Delete(extra_method_name); - } - - /* emit the director method */ - if (status == SWIG_OK) { - if (!Getattr(n, "defaultargs")) { - Replaceall(w->code, "$symname", symname); - Wrapper_print(w, f_directors); - Printv(f_directors_h, declaration, NIL); - Printv(f_directors_h, inline_extra_method, NIL); - } - } - - /* clean up */ - Delete(wrap_args); - Delete(pclassname); - DelWrapper(w); - return status; - } - - /* ------------------------------------------------------------ - * classDirectorConstructor() - * ------------------------------------------------------------ */ - - int classDirectorConstructor(Node *n) { - Node *parent = Getattr(n, "parentNode"); - String *sub = NewString(""); - String *decl = Getattr(n, "decl"); - String *supername = Swig_class_name(parent); - String *classname = NewString(""); - Printf(classname, "SwigDirector_%s", supername); - - /* insert self parameter */ - Parm *p, *q; - ParmList *superparms = Getattr(n, "parms"); - ParmList *parms = CopyParmList(superparms); - String *type = NewString("CAML_VALUE"); - p = NewParm(type, NewString("self"), n); - q = Copy(p); - set_nextSibling(q, superparms); - set_nextSibling(p, parms); - parms = p; - - if (!Getattr(n, "defaultargs")) { - /* constructor */ - { - Wrapper *w = NewWrapper(); - String *call; - String *basetype = Getattr(parent, "classtype"); - String *target = Swig_method_decl(0, decl, classname, parms, 0); - call = Swig_csuperclass_call(0, basetype, superparms); - Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call); - Delete(target); - Wrapper_print(w, f_directors); - Delete(call); - DelWrapper(w); - } - - /* constructor header */ - { - String *target = Swig_method_decl(0, decl, classname, parms, 1); - Printf(f_directors_h, " %s;\n", target); - Delete(target); - } - } - - Setattr(n, "parms", q); - Language::classDirectorConstructor(n); - - Delete(sub); - Delete(classname); - Delete(supername); - //Delete(parms); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * classDirectorDefaultConstructor() - * ------------------------------------------------------------ */ - - int classDirectorDefaultConstructor(Node *n) { - String *classname; - classname = Swig_class_name(n); - - /* insert self parameter */ - Parm *p, *q; - ParmList *superparms = Getattr(n, "parms"); - ParmList *parms = CopyParmList(superparms); - String *type = NewString("CAML_VALUE"); - p = NewParm(type, NewString("self"), n); - q = Copy(p); - set_nextSibling(p, parms); - - { - Wrapper *w = NewWrapper(); - Printf(w->def, "SwigDirector_%s::SwigDirector_%s(CAML_VALUE self) : Swig::Director(self) { }", classname, classname); - Wrapper_print(w, f_directors); - DelWrapper(w); - } - Printf(f_directors_h, " SwigDirector_%s(CAML_VALUE self);\n", classname); - Delete(classname); - Setattr(n, "parms", q); - return Language::classDirectorDefaultConstructor(n); - } - - int classDirectorInit(Node *n) { - String *declaration = Swig_director_declaration(n); - Printf(f_directors_h, "\n" "%s\n" "public:\n", declaration); - Delete(declaration); - return Language::classDirectorInit(n); - } - - int classDirectorEnd(Node *n) { - Printf(f_directors_h, "};\n\n"); - return Language::classDirectorEnd(n); - } - - /* --------------------------------------------------------------------- - * typedefHandler - * - * This is here in order to maintain the correct association between - * typedef names and enum names. - * - * Since I implement enums as polymorphic variant tags, I need to call - * back into ocaml to evaluate them. This requires a string that can - * be generated in the typemaps, and also at SWIG time to be the same - * string. The problem that arises is that SWIG variously generates - * enum e_name_tag - * e_name_tag - * e_typedef_name - * for - * typedef enum e_name_tag { ... } e_typedef_name; - * - * Since I need these strings to be consistent, I must maintain a correct - * association list between typedef and enum names. - * --------------------------------------------------------------------- */ - int typedefHandler(Node *n) { - String *type = Getattr(n, "type"); - Node *enum_node = type ? Getattr(seen_enums, type) : 0; - if (enum_node) { - String *name = Getattr(enum_node, "name"); - - Printf(f_mlbody, "let _ = Callback.register \"%s_marker\" (`%s)\n", Getattr(n, "name"), name); - - } - return SWIG_OK; - } - - String *runtimeCode() { - String *s = Swig_include_sys("ocamlrun.swg"); - if (!s) { - Printf(stderr, "*** Unable to open 'ocamlrun.swg'\n"); - s = NewString(""); - } - return s; - } - - String *defaultExternalRuntimeFilename() { - return NewString("swigocamlrun.h"); - } -}; - -/* ------------------------------------------------------------------------- - * swig_ocaml() - Instantiate module - * ------------------------------------------------------------------------- */ - -static Language *new_swig_ocaml() { - return new OCAML(); -} -extern "C" Language *swig_ocaml(void) { - return new_swig_ocaml(); -} diff --git a/contrib/tools/swig/Source/Modules/octave.cxx b/contrib/tools/swig/Source/Modules/octave.cxx deleted file mode 100644 index 352105b9bda..00000000000 --- a/contrib/tools/swig/Source/Modules/octave.cxx +++ /dev/null @@ -1,1572 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * octave.cxx - * - * Octave language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" - -static String *global_name = 0; -static String *op_prefix = 0; - -static const char *usage = "\ -Octave Options (available with -octave)\n\ - -globals <name> - Set <name> used to access C global variables [default: 'cvar']\n\ - Use '.' to load C global variables into module namespace\n\ - -opprefix <str> - Prefix <str> for global operator functions [default: 'op_']\n\ -\n"; - - -class OCTAVE:public Language { -private: - File *f_begin; - File *f_runtime; - File *f_header; - File *f_doc; - File *f_wrappers; - File *f_init; - File *f_initbeforefunc; - File *f_directors; - File *f_directors_h; - String *s_global_tab; - String *s_members_tab; - String *class_name; - - int have_constructor; - int have_destructor; - String *constructor_name; - - Hash *docs; - - void Octave_begin_function(Node *n, File *f, const_String_or_char_ptr cname, const_String_or_char_ptr wname, bool dld) { - if (dld) { - String *tname = texinfo_name(n, "std::string()"); - Printf(f, "SWIG_DEFUN( %s, %s, %s ) {", cname, wname, tname); - } - else { - Printf(f, "static octave_value_list %s (const octave_value_list& args, int nargout) {", wname); - } - } - -public: - OCTAVE(): - f_begin(0), - f_runtime(0), - f_header(0), - f_doc(0), - f_wrappers(0), - f_init(0), - f_initbeforefunc(0), - f_directors(0), - f_directors_h(0), - s_global_tab(0), - s_members_tab(0), - class_name(0), - have_constructor(0), - have_destructor(0), - constructor_name(0), - docs(0) - { - /* Add code to manage protected constructors and directors */ - director_prot_ctor_code = NewString(""); - Printv(director_prot_ctor_code, - "if ( $comparison ) { /* subclassed */\n", - " $director_new \n", - "} else {\n", " error(\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL); - - enable_cplus_runtime_mode(); - allow_overloading(); - director_multiple_inheritance = 1; - director_language = 1; - docs = NewHash(); - } - - virtual void main(int argc, char *argv[]) { - - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-help") == 0) { - fputs(usage, stdout); - } else if (strcmp(argv[i], "-globals") == 0) { - if (argv[i + 1]) { - global_name = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-opprefix") == 0) { - if (argv[i + 1]) { - op_prefix = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-cppcast") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nocppcast") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); - Swig_mark_arg(i); - Exit(EXIT_FAILURE); - } - } - } - - if (!global_name) - global_name = NewString("cvar"); - if (!op_prefix) - op_prefix = NewString("op_"); - - SWIG_library_directory("octave"); - Preprocessor_define("SWIGOCTAVE 1", 0); - SWIG_config_file("octave.swg"); - SWIG_typemap_lang("octave"); - allow_overloading(); - - // Octave API is C++, so output must be C++ compatible even when wrapping C code - if (!cparse_cplusplus) - Swig_cparse_cplusplusout(1); - } - - virtual int top(Node *n) { - { - Node *mod = Getattr(n, "module"); - if (mod) { - Node *options = Getattr(mod, "options"); - if (options) { - int dirprot = 0; - if (Getattr(options, "dirprot")) { - dirprot = 1; - } - if (Getattr(options, "nodirprot")) { - dirprot = 0; - } - if (Getattr(options, "directors")) { - allow_directors(); - if (dirprot) - allow_dirprot(); - } - } - } - } - - String *module = Getattr(n, "name"); - String *outfile = Getattr(n, "outfile"); - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - f_runtime = NewString(""); - f_header = NewString(""); - f_doc = NewString(""); - f_wrappers = NewString(""); - f_init = NewString(""); - f_initbeforefunc = NewString(""); - f_directors_h = NewString(""); - f_directors = NewString(""); - s_global_tab = NewString(""); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("doc", f_doc); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("init", f_init); - Swig_register_filebyname("initbeforefunc", f_initbeforefunc); - Swig_register_filebyname("director", f_directors); - Swig_register_filebyname("director_h", f_directors_h); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "OCTAVE"); - - Printf(f_runtime, "#define SWIG_name_d \"%s\"\n", module); - Printf(f_runtime, "#define SWIG_name %s\n", module); - - Printf(f_runtime, "\n"); - Printf(f_runtime, "#define SWIG_global_name \"%s\"\n", global_name); - Printf(f_runtime, "#define SWIG_op_prefix \"%s\"\n", op_prefix); - - if (directorsEnabled()) { - Printf(f_runtime, "#define SWIG_DIRECTORS\n"); - Swig_banner(f_directors_h); - if (dirprot_mode()) { - // Printf(f_directors_h, "#include <map>\n"); - // Printf(f_directors_h, "#include <string>\n\n"); - } - } - - Printf(f_runtime, "\n"); - - Printf(s_global_tab, "\nstatic const struct swig_octave_member swig_globals[] = {\n"); - Printf(f_init, "static bool SWIG_init_user(octave_swig_type* module_ns)\n{\n"); - - if (!CPlusPlus) - Printf(f_header,"extern \"C\" {\n"); - - Language::top(n); - - if (!CPlusPlus) - Printf(f_header,"}\n"); - - if (Len(docs)) - emit_doc_texinfo(); - - if (directorsEnabled()) { - Swig_insert_file("director_common.swg", f_runtime); - Swig_insert_file("director.swg", f_runtime); - } - - Printf(f_init, "return true;\n}\n"); - Printf(s_global_tab, "{0,0,0,0,0,0}\n};\n"); - - Printv(f_wrappers, s_global_tab, NIL); - SwigType_emit_type_table(f_runtime, f_wrappers); - Dump(f_runtime, f_begin); - Dump(f_header, f_begin); - Dump(f_doc, f_begin); - if (directorsEnabled()) { - Dump(f_directors_h, f_begin); - Dump(f_directors, f_begin); - } - Dump(f_wrappers, f_begin); - Dump(f_initbeforefunc, f_begin); - Wrapper_pretty_print(f_init, f_begin); - - Delete(s_global_tab); - Delete(f_initbeforefunc); - Delete(f_init); - Delete(f_wrappers); - Delete(f_doc); - Delete(f_header); - Delete(f_directors); - Delete(f_directors_h); - Delete(f_runtime); - Delete(f_begin); - - return SWIG_OK; - } - - String *texinfo_escape(String *_s) { - const char* s=(const char*)Data(_s); - while (*s&&(*s=='\t'||*s=='\r'||*s=='\n'||*s==' ')) - ++s; - String *r = NewString(""); - for (int j=0;s[j];++j) { - if (s[j] == '\n') { - Append(r, "\\n\\\n"); - } else if (s[j] == '\r') { - Append(r, "\\r"); - } else if (s[j] == '\t') { - Append(r, "\\t"); - } else if (s[j] == '\\') { - Append(r, "\\\\"); - } else if (s[j] == '\'') { - Append(r, "\\\'"); - } else if (s[j] == '\"') { - Append(r, "\\\""); - } else - Putc(s[j], r); - } - return r; - } - void emit_doc_texinfo() { - for (Iterator it = First(docs); it.key; it = Next(it)) { - String *wrap_name = it.key; - - String *synopsis = Getattr(it.item, "synopsis"); - String *decl_info = Getattr(it.item, "decl_info"); - String *cdecl_info = Getattr(it.item, "cdecl_info"); - String *args_info = Getattr(it.item, "args_info"); - - String *doc_str = NewString(""); - Printv(doc_str, synopsis, decl_info, cdecl_info, args_info, NIL); - String *escaped_doc_str = texinfo_escape(doc_str); - - if (Len(doc_str)>0) { - Printf(f_doc,"static const char* %s_texinfo = ",wrap_name); - Printf(f_doc,"\"-*- texinfo -*-\\n\\\n%s", escaped_doc_str); - if (Len(decl_info)) - Printf(f_doc,"\\n\\\n@end deftypefn"); - Printf(f_doc,"\";\n"); - } - - Delete(escaped_doc_str); - Delete(doc_str); - Delete(wrap_name); - } - Printf(f_doc,"\n"); - } - bool is_empty_doc_node(Node* n) { - if (!n) - return true; - String *synopsis = Getattr(n, "synopsis"); - String *decl_info = Getattr(n, "decl_info"); - String *cdecl_info = Getattr(n, "cdecl_info"); - String *args_info = Getattr(n, "args_info"); - return !Len(synopsis) && !Len(decl_info) && - !Len(cdecl_info) && !Len(args_info); - } - String *texinfo_name(Node* n, const char* defval = "0") { - String *tname = NewString(""); - String *iname = Getattr(n, "sym:name"); - String *wname = Swig_name_wrapper(iname); - Node* d = Getattr(docs, wname); - - if (is_empty_doc_node(d)) - Printf(tname, defval); - else - Printf(tname, "%s_texinfo", wname); - - return tname; - } - void process_autodoc(Node *n) { - String *iname = Getattr(n, "sym:name"); - String *name = Getattr(n, "name"); - String *wname = Swig_name_wrapper(iname); - String *str = Getattr(n, "feature:docstring"); - bool autodoc_enabled = !Cmp(Getattr(n, "feature:autodoc"), "1"); - Node* d = Getattr(docs, wname); - if (!d) { - d = NewHash(); - Setattr(d, "synopsis", NewString("")); - Setattr(d, "decl_info", NewString("")); - Setattr(d, "cdecl_info", NewString("")); - Setattr(d, "args_info", NewString("")); - Setattr(docs, wname, d); - } - - String *synopsis = Getattr(d, "synopsis"); - String *decl_info = Getattr(d, "decl_info"); - // String *cdecl_info = Getattr(d, "cdecl_info"); - String *args_info = Getattr(d, "args_info"); - - // * couldn't we just emit the docs here? - - if (autodoc_enabled) { - String *decl_str = NewString(""); - String *args_str = NewString(""); - make_autodocParmList(n, decl_str, args_str); - Append(decl_info, "@deftypefn {Loadable Function} "); - - SwigType *type = Getattr(n, "type"); - if (type && Strcmp(type, "void")) { - Node *nn = classLookup(Getattr(n, "type")); - String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0); - Append(decl_info, "@var{retval} = "); - Printf(args_str, "%s@var{retval} is of type %s. ", args_str, type_str); - Delete(type_str); - } - - Append(decl_info, name); - Append(decl_info, " ("); - Append(decl_info, decl_str); - Append(decl_info, ")\n"); - Append(args_info, args_str); - Delete(decl_str); - Delete(args_str); - } - - if (str && Len(str) > 0) { - // strip off {} if necessary - char *t = Char(str); - if (*t == '{') { - Delitem(str, 0); - Delitem(str, DOH_END); - } - - // emit into synopsis section - Append(synopsis, str); - } - } - - virtual int importDirective(Node *n) { - String *modname = Getattr(n, "module"); - if (modname) - Printf(f_init, "if (!SWIG_Octave_LoadModule(\"%s\")) return false;\n", modname); - return Language::importDirective(n); - } - - const char *get_implicitconv_flag(Node *n) { - int conv = 0; - if (n && GetFlag(n, "feature:implicitconv")) { - conv = 1; - } - return conv ? "SWIG_POINTER_IMPLICIT_CONV" : "0"; - } - - /* ----------------------------------------------------------------------------- - * addMissingParameterNames() - * For functions that have not had nameless parameters set in the Language class. - * - * Inputs: - * plist - entire parameter list - * arg_offset - argument number for first parameter - * Side effects: - * The "lname" attribute in each parameter in plist will be contain a parameter name - * ----------------------------------------------------------------------------- */ - - void addMissingParameterNames(Node* n, ParmList *plist, int arg_offset) { - Parm *p = plist; - int i = arg_offset; - while (p) { - if (!Getattr(p, "lname")) { - String *name = makeParameterName(n, p, i); - Setattr(p, "lname", name); - Delete(name); - } - i++; - p = nextSibling(p); - } - } - - void make_autodocParmList(Node *n, String *decl_str, String *args_str) { - String *pdocs = 0; - ParmList *plist = CopyParmList(Getattr(n, "parms")); - Parm *p; - Parm *pnext; - int arg_num = is_wrapping_class() ? 1 : 0; - - addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms - - Swig_typemap_attach_parms("in", plist, 0); - Swig_typemap_attach_parms("doc", plist, 0); - - for (p = plist; p; p = pnext, arg_num++) { - - String *tm = Getattr(p, "tmap:in"); - if (tm) { - pnext = Getattr(p, "tmap:in:next"); - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - continue; - } - } else { - pnext = nextSibling(p); - } - - String *name = 0; - String *type = 0; - String *value = 0; - String *pdoc = Getattr(p, "tmap:doc"); - if (pdoc) { - name = Getattr(p, "tmap:doc:name"); - type = Getattr(p, "tmap:doc:type"); - value = Getattr(p, "tmap:doc:value"); - } - - String *made_name = 0; - if (!name) { - name = made_name = makeParameterName(n, p, arg_num); - } - - type = type ? type : Getattr(p, "type"); - value = value ? value : Getattr(p, "value"); - - if (SwigType_isvarargs(type)) - break; - - String *tex_name = NewString(""); - if (name) - Printf(tex_name, "@var{%s}", name); - else - Printf(tex_name, "@var{?}"); - - if (Len(decl_str)) - Append(decl_str, ", "); - Append(decl_str, tex_name); - - if (value) { - String *new_value = convertValue(value, Getattr(p, "type")); - if (new_value) { - value = new_value; - } else { - Node *lookup = Swig_symbol_clookup(value, 0); - if (lookup) - value = Getattr(lookup, "sym:name"); - } - Printf(decl_str, " = %s", value); - } - - Node *nn = classLookup(Getattr(p, "type")); - String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0); - Printf(args_str, "%s is of type %s. ", tex_name, type_str); - - Delete(type_str); - Delete(tex_name); - Delete(made_name); - } - if (pdocs) - Setattr(n, "feature:pdocs", pdocs); - Delete(plist); - } - - /* ------------------------------------------------------------ - * convertValue() - * Check if string v can be an Octave value literal, - * (eg. number or string), or translate it to an Octave literal. - * ------------------------------------------------------------ */ - String *convertValue(String *v, SwigType *t) { - if (v && Len(v) > 0) { - char fc = (Char(v))[0]; - if (('0' <= fc && fc <= '9') || '\'' == fc || '"' == fc) { - /* number or string (or maybe NULL pointer) */ - if (SwigType_ispointer(t) && Strcmp(v, "0") == 0) - return NewString("None"); - else - return v; - } - if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) - return SwigType_ispointer(t) ? NewString("nil") : NewString("0"); - if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0) - return NewString("true"); - if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0) - return NewString("false"); - } - return 0; - } - - virtual int functionWrapper(Node *n) { - Parm *p; - String *tm; - int j; - - String *nodeType = Getattr(n, "nodeType"); - int constructor = (!Cmp(nodeType, "constructor")); - int destructor = (!Cmp(nodeType, "destructor")); - String *storage = Getattr(n, "storage"); - - bool overloaded = !!Getattr(n, "sym:overloaded"); - bool last_overload = overloaded && !Getattr(n, "sym:nextSibling"); - String *iname = Getattr(n, "sym:name"); - String *wname = Swig_name_wrapper(iname); - String *overname = Copy(wname); - SwigType *d = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - - if (!overloaded && !addSymbol(iname, n)) - return SWIG_ERROR; - - if (overloaded) - Append(overname, Getattr(n, "sym:overname")); - - if (!overloaded || last_overload) - process_autodoc(n); - - Wrapper *f = NewWrapper(); - Octave_begin_function(n, f->def, iname, overname, !overloaded); - - // Start default try block to execute - // cleanup code if exception is thrown - Printf(f->code, "try {\n"); - - emit_parameter_variables(l, f); - emit_attach_parmmaps(l, f); - Setattr(n, "wrap:parms", l); - - int num_arguments = emit_num_arguments(l); - int num_required = emit_num_required(l); - int varargs = emit_isvarargs(l); - char source[64]; - - Printf(f->code, "if (!SWIG_check_num_args(\"%s\",args.length(),%i,%i,%i)) " - "{\n SWIG_fail;\n }\n", iname, num_arguments, num_required, varargs); - - if (constructor && num_arguments == 1 && num_required == 1) { - if (Cmp(storage, "explicit") == 0) { - Node *parent = Swig_methodclass(n); - if (GetFlag(parent, "feature:implicitconv")) { - String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type"))); - Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc); - Delete(desc); - } - } - } - - for (j = 0, p = l; j < num_arguments; ++j) { - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - - String *tm = Getattr(p, "tmap:in"); - if (tm) { - if (!tm || checkAttribute(p, "tmap:in:numinputs", "0")) { - p = nextSibling(p); - continue; - } - - sprintf(source, "args(%d)", j); - Setattr(p, "emit:input", source); - - Replaceall(tm, "$input", Getattr(p, "emit:input")); - - if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - - if (Getattr(p, "tmap:in:implicitconv")) { - const char *convflag = "0"; - if (!Getattr(p, "hidden")) { - SwigType *ptype = Getattr(p, "type"); - convflag = get_implicitconv_flag(classLookup(ptype)); - } - Replaceall(tm, "$implicitconv", convflag); - Setattr(p, "implicitconv", convflag); - } - - String *getargs = NewString(""); - if (j >= num_required) - Printf(getargs, "if (%d<args.length()) {\n%s\n}", j, tm); - else - Printv(getargs, tm, NIL); - Printv(f->code, getargs, "\n", NIL); - Delete(getargs); - - p = Getattr(p, "tmap:in:next"); - continue; - } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); - break; - } - } - - // Check for trailing varargs - if (varargs) { - if (p && (tm = Getattr(p, "tmap:in"))) { - Replaceall(tm, "$input", "varargs"); - Printv(f->code, tm, "\n", NIL); - } - } - - // Insert constraint checking code - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - - // Insert cleanup code - String *cleanup = NewString(""); - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:freearg"))) { - if (Getattr(p, "tmap:freearg:implicitconv")) { - const char *convflag = "0"; - if (!Getattr(p, "hidden")) { - SwigType *ptype = Getattr(p, "type"); - convflag = get_implicitconv_flag(classLookup(ptype)); - } - if (strcmp(convflag, "0") == 0) { - tm = 0; - } - } - if (tm && (Len(tm) != 0)) { - Printv(cleanup, tm, "\n", NIL); - } - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - // Insert argument output code - String *outarg = NewString(""); - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - Replaceall(tm, "$result", "_outp"); - Replaceall(tm, "$arg", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - int director_method = is_member_director(n) && !is_smart_pointer() && !destructor; - if (director_method) { - Wrapper_add_local(f, "upcall", "bool upcall = false"); - Append(f->code, "upcall = !!dynamic_cast<Swig::Director*>(arg1);\n"); - } - - Setattr(n, "wrap:name", overname); - - Swig_director_emit_dynamic_cast(n, f); - String *actioncode = emit_action(n); - - Wrapper_add_local(f, "_out", "octave_value_list _out"); - Wrapper_add_local(f, "_outp", "octave_value_list *_outp=&_out"); - Wrapper_add_local(f, "_outv", "octave_value _outv"); - - // Return the function value - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { - Replaceall(tm, "$result", "_outv"); - - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "1"); - else - Replaceall(tm, "$owner", "0"); - - Printf(f->code, "%s\n", tm); - Printf(f->code, "if (_outv.is_defined()) _outp = " "SWIG_Octave_AppendOutput(_outp, _outv);\n"); - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), iname); - } - emit_return_variable(n, d, f); - - Printv(f->code, outarg, NIL); - Printv(f->code, cleanup, NIL); - - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - } - } - - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Replaceall(tm, "$result", "_outv"); - Printf(f->code, "%s\n", tm); - Delete(tm); - } - - Printf(f->code, "return _out;\n"); - - // Execute cleanup code if branched to fail: label - Printf(f->code, "fail:\n"); - Printv(f->code, cleanup, NIL); - Printf(f->code, "return octave_value_list();\n"); - - // Execute cleanup code if exception was thrown - Printf(f->code, "}\n"); - Printf(f->code, "catch(...) {\n"); - Printv(f->code, cleanup, NIL); - Printf(f->code, "throw;\n"); - Printf(f->code, "}\n"); - - // End wrapper function - Printf(f->code, "}\n"); - - /* Substitute the cleanup code */ - Replaceall(f->code, "$cleanup", cleanup); - - Replaceall(f->code, "$symname", iname); - Wrapper_print(f, f_wrappers); - DelWrapper(f); - - if (last_overload) - dispatchFunction(n); - - if (!overloaded || last_overload) { - String *tname = texinfo_name(n); - Printf(s_global_tab, "{\"%s\",%s,0,0,2,%s},\n", iname, wname, tname); - Delete(tname); - } - - Delete(overname); - Delete(wname); - Delete(cleanup); - Delete(outarg); - - return SWIG_OK; - } - - void dispatchFunction(Node *n) { - Wrapper *f = NewWrapper(); - - String *iname = Getattr(n, "sym:name"); - String *wname = Swig_name_wrapper(iname); - int maxargs; - String *dispatch = Swig_overload_dispatch(n, "return %s(args, nargout);", &maxargs); - String *tmp = NewString(""); - - Octave_begin_function(n, f->def, iname, wname, true); - Wrapper_add_local(f, "argc", "int argc = args.length()"); - Printf(tmp, "octave_value_ref argv[%d]={", maxargs); - for (int j = 0; j < maxargs; ++j) - Printf(tmp, "%soctave_value_ref(args,%d)", j ? "," : " ", j); - Printf(tmp, "}"); - Wrapper_add_local(f, "argv", tmp); - Printv(f->code, dispatch, "\n", NIL); - Printf(f->code, "error(\"No matching function for overload\");\n"); - Printf(f->code, "return octave_value_list();\n"); - Printv(f->code, "}\n", NIL); - - Wrapper_print(f, f_wrappers); - Delete(tmp); - DelWrapper(f); - Delete(dispatch); - Delete(wname); - } - - virtual int variableWrapper(Node *n) { - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - - if (!addSymbol(iname, n)) - return SWIG_ERROR; - - String *tm; - Wrapper *getf = NewWrapper(); - Wrapper *setf = NewWrapper(); - - String *getname = Swig_name_get(NSPACE_TODO, iname); - String *setname = Swig_name_set(NSPACE_TODO, iname); - - String *getwname = Swig_name_wrapper(getname); - String *setwname = Swig_name_wrapper(setname); - - Octave_begin_function(n, setf->def, setname, setwname, true); - Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();\n", iname); - if (is_assignable(n)) { - Setattr(n, "wrap:name", setname); - if ((tm = Swig_typemap_lookup("varin", n, name, 0))) { - Replaceall(tm, "$input", "args(0)"); - if (Getattr(n, "tmap:varin:implicitconv")) { - Replaceall(tm, "$implicitconv", get_implicitconv_flag(n)); - } - emit_action_code(n, setf->code, tm); - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0)); - } - Append(setf->code, "return octave_value_list();\n"); - Append(setf->code, "fail:\n"); - Append(setf->code, "return octave_value_list();\n"); - } else { - Printf(setf->code, "return octave_set_immutable(args,nargout);"); - } - Append(setf->code, "}\n"); - Wrapper_print(setf, f_wrappers); - - Setattr(n, "wrap:name", getname); - int addfail = 0; - Octave_begin_function(n, getf->def, getname, getwname, true); - Wrapper_add_local(getf, "obj", "octave_value obj"); - if ((tm = Swig_typemap_lookup("varout", n, name, 0))) { - Replaceall(tm, "$result", "obj"); - addfail = emit_action_code(n, getf->code, tm); - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0)); - } - Append(getf->code, "return obj;\n"); - if (addfail) { - Append(getf->code, "fail:\n"); - Append(getf->code, "return octave_value_list();\n"); - } - Append(getf->code, "}\n"); - Wrapper_print(getf, f_wrappers); - - Printf(s_global_tab, "{\"%s\",0,%s,%s,2,0},\n", iname, getwname, setwname); - - Delete(getwname); - Delete(setwname); - DelWrapper(setf); - DelWrapper(getf); - - return SWIG_OK; - } - - virtual int constantWrapper(Node *n) { - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - String *rawval = Getattr(n, "rawval"); - String *value = rawval ? rawval : Getattr(n, "value"); - String *cppvalue = Getattr(n, "cppvalue"); - String *tm; - - if (!addSymbol(iname, n)) - return SWIG_ERROR; - - if (SwigType_type(type) == T_MPOINTER) { - String *wname = Swig_name_wrapper(iname); - String *str = SwigType_str(type, wname); - Printf(f_header, "static %s = %s;\n", str, value); - Delete(str); - value = wname; - } - if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) { - Replaceall(tm, "$value", cppvalue ? cppvalue : value); - Replaceall(tm, "$nsname", iname); - Printf(f_init, "%s\n", tm); - } else { - Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); - return SWIG_NOWRAP; - } - - return SWIG_OK; - } - - virtual int nativeWrapper(Node *n) { - return Language::nativeWrapper(n); - } - - virtual int enumDeclaration(Node *n) { - return Language::enumDeclaration(n); - } - - virtual int enumvalueDeclaration(Node *n) { - return Language::enumvalueDeclaration(n); - } - - virtual int classDeclaration(Node *n) { - return Language::classDeclaration(n); - } - - virtual int classHandler(Node *n) { - have_constructor = 0; - have_destructor = 0; - constructor_name = 0; - - class_name = Getattr(n, "sym:name"); - - if (!addSymbol(class_name, n)) - return SWIG_ERROR; - - // This is a bug, due to the fact that swig_type -> octave_class mapping - // is 1-to-n. - static Hash *emitted = NewHash(); - String *mangled_classname = Swig_name_mangle(Getattr(n, "name")); - if (Getattr(emitted, mangled_classname)) { - Delete(mangled_classname); - return SWIG_NOWRAP; - } - Setattr(emitted, mangled_classname, "1"); - Delete(mangled_classname); - - assert(!s_members_tab); - s_members_tab = NewString(""); - Printv(s_members_tab, "static swig_octave_member swig_", class_name, "_members[] = {\n", NIL); - - Language::classHandler(n); - - SwigType *t = Copy(Getattr(n, "name")); - SwigType_add_pointer(t); - - // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers) - SwigType *smart = Swig_cparse_smartptr(n); - String *wrap_class = NewStringf("&_wrap_class_%s", class_name); - if (smart) { - SwigType_add_pointer(smart); - SwigType_remember_clientdata(smart, wrap_class); - } - //String *wrap_class = NewStringf("&_wrap_class_%s", class_name); - SwigType_remember_clientdata(t, wrap_class); - - int use_director = Swig_directorclass(n); - if (use_director) { - String *nspace = Getattr(n, "sym:nspace"); - String *cname = Swig_name_disown(nspace, class_name); - String *wcname = Swig_name_wrapper(cname); - String *cnameshdw = NewStringf("%s_shadow", cname); - String *wcnameshdw = Swig_name_wrapper(cnameshdw); - Octave_begin_function(n, f_wrappers, cnameshdw, wcnameshdw, true); - Printf(f_wrappers, " if (args.length()!=1) {\n"); - Printf(f_wrappers, " error(\"disown takes no arguments\");\n"); - Printf(f_wrappers, " return octave_value_list();\n"); - Printf(f_wrappers, " }\n"); - Printf(f_wrappers, " %s (args, nargout);\n", wcname); - Printf(f_wrappers, " return args;\n"); - Printf(f_wrappers, "}\n"); - Printf(s_members_tab, "{\"__disown\",%s,0,0,0,0},\n", wcnameshdw); - Delete(wcname); - Delete(cname); - Delete(wcnameshdw); - Delete(cnameshdw); - } - - Printf(s_members_tab, "{0,0,0,0,0,0}\n};\n"); - Printv(f_wrappers, s_members_tab, NIL); - - String *base_class_names = NewString(""); - String *base_class = NewString(""); - List *baselist = Getattr(n, "bases"); - if (baselist && Len(baselist)) { - Iterator b; - b = First(baselist); - while (b.item) { - String *bname = Getattr(b.item, "name"); - if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) { - b = Next(b); - continue; - } - - String *bname_mangled = SwigType_manglestr(SwigType_add_pointer(Copy(bname))); - Printf(base_class_names, "\"%s\",", bname_mangled); - Printf(base_class, "0,"); - b = Next(b); - Delete(bname_mangled); - } - } - - Printv(f_wrappers, "static const char *swig_", class_name, "_base_names[] = {", base_class_names, "0};\n", NIL); - Printv(f_wrappers, "static const swig_type_info *swig_", class_name, "_base[] = {", base_class, "0};\n", NIL); - Printv(f_wrappers, "static swig_octave_class _wrap_class_", class_name, " = {\"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL); - Printv(f_wrappers, Swig_directorclass(n) ? "1," : "0,", NIL); - if (have_constructor) { - String *nspace = Getattr(n, "sym:nspace"); - String *cname = Swig_name_construct(nspace, constructor_name); - String *wcname = Swig_name_wrapper(cname); - String *tname = texinfo_name(n); - Printf(f_wrappers, "%s,%s,", wcname, tname); - Delete(tname); - Delete(wcname); - Delete(cname); - } else - Printv(f_wrappers, "0,0,", NIL); - if (have_destructor) { - String *nspace = Getattr(n, "sym:nspace"); - String *cname = Swig_name_destroy(nspace, class_name); - String *wcname = Swig_name_wrapper(cname); - Printf(f_wrappers, "%s,", wcname); - Delete(wcname); - Delete(cname); - } else - Printv(f_wrappers, "0", ",", NIL); - Printf(f_wrappers, "swig_%s_members,swig_%s_base_names,swig_%s_base };\n\n", class_name, class_name, class_name); - - Delete(base_class); - Delete(base_class_names); - Delete(smart); - Delete(t); - Delete(s_members_tab); - s_members_tab = 0; - class_name = 0; - - return SWIG_OK; - } - - virtual int memberfunctionHandler(Node *n) { - Language::memberfunctionHandler(n); - - assert(s_members_tab); - assert(class_name); - String *name = Getattr(n, "name"); - String *iname = GetChar(n, "sym:name"); - String *realname = iname ? iname : name; - String *wname = Getattr(n, "wrap:name"); - assert(wname); - - if (!Getattr(n, "sym:nextSibling")) { - String *tname = texinfo_name(n); - String *rname = Copy(wname); - bool overloaded = !!Getattr(n, "sym:overloaded"); - if (overloaded) - Delslice(rname, Len(rname) - Len(Getattr(n, "sym:overname")), DOH_END); - Printf(s_members_tab, "{\"%s\",%s,0,0,0,%s},\n", - realname, rname, tname); - Delete(rname); - Delete(tname); - } - - return SWIG_OK; - } - - virtual int membervariableHandler(Node *n) { - Setattr(n, "feature:autodoc", "0"); - - Language::membervariableHandler(n); - - assert(s_members_tab); - assert(class_name); - String *symname = Getattr(n, "sym:name"); - String *getname = Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)); - String *setname = Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)); - String *getwname = Swig_name_wrapper(getname); - String *setwname = GetFlag(n, "feature:immutable") ? NewString("octave_set_immutable") : Swig_name_wrapper(setname); - assert(s_members_tab); - - Printf(s_members_tab, "{\"%s\",0,%s,%s,0,0},\n", symname, getwname, setwname); - - Delete(getname); - Delete(setname); - Delete(getwname); - Delete(setwname); - return SWIG_OK; - } - - virtual int constructorHandler(Node *n) { - have_constructor = 1; - if (!constructor_name) - constructor_name = NewString(Getattr(n, "sym:name")); - - int use_director = Swig_directorclass(n); - if (use_director) { - Parm *parms = Getattr(n, "parms"); - Parm *self; - String *name = NewString("self"); - String *type = NewString("void"); - SwigType_add_pointer(type); - self = NewParm(type, name, n); - Delete(type); - Delete(name); - Setattr(self, "lname", "self_obj"); - if (parms) - set_nextSibling(self, parms); - Setattr(n, "parms", self); - Setattr(n, "wrap:self", "1"); - Setattr(n, "hidden", "1"); - Delete(self); - } - - return Language::constructorHandler(n); - } - - virtual int destructorHandler(Node *n) { - have_destructor = 1; - return Language::destructorHandler(n); - } - - virtual int staticmemberfunctionHandler(Node *n) { - Language::staticmemberfunctionHandler(n); - - assert(s_members_tab); - assert(class_name); - String *name = Getattr(n, "name"); - String *iname = GetChar(n, "sym:name"); - String *realname = iname ? iname : name; - String *wname = Getattr(n, "wrap:name"); - assert(wname); - - if (!Getattr(n, "sym:nextSibling")) { - String *tname = texinfo_name(n); - String *rname = Copy(wname); - bool overloaded = !!Getattr(n, "sym:overloaded"); - if (overloaded) - Delslice(rname, Len(rname) - Len(Getattr(n, "sym:overname")), DOH_END); - Printf(s_members_tab, "{\"%s\",%s,0,0,1,%s},\n", - realname, rname, tname); - Delete(rname); - Delete(tname); - } - - return SWIG_OK; - } - - virtual int memberconstantHandler(Node *n) { - return Language::memberconstantHandler(n); - } - - virtual int staticmembervariableHandler(Node *n) { - Setattr(n, "feature:autodoc", "0"); - - Language::staticmembervariableHandler(n); - - if (!GetFlag(n, "wrappedasconstant")) { - assert(s_members_tab); - assert(class_name); - String *symname = Getattr(n, "sym:name"); - String *getname = Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)); - String *setname = Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)); - String *getwname = Swig_name_wrapper(getname); - String *setwname = GetFlag(n, "feature:immutable") ? NewString("octave_set_immutable") : Swig_name_wrapper(setname); - assert(s_members_tab); - - Printf(s_members_tab, "{\"%s\",0,%s,%s,1,0},\n", symname, getwname, setwname); - - Delete(getname); - Delete(setname); - Delete(getwname); - Delete(setwname); - } - return SWIG_OK; - } - - int classDirectorInit(Node *n) { - String *declaration = Swig_director_declaration(n); - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "%s\n", declaration); - Printf(f_directors_h, "public:\n"); - Delete(declaration); - return Language::classDirectorInit(n); - } - - int classDirectorEnd(Node *n) { - Printf(f_directors_h, "};\n\n"); - return Language::classDirectorEnd(n); - } - - int classDirectorConstructor(Node *n) { - Node *parent = Getattr(n, "parentNode"); - String *sub = NewString(""); - String *decl = Getattr(n, "decl"); - String *supername = Swig_class_name(parent); - String *classname = NewString(""); - Printf(classname, "SwigDirector_%s", supername); - - // insert self parameter - Parm *p; - ParmList *superparms = Getattr(n, "parms"); - ParmList *parms = CopyParmList(superparms); - String *type = NewString("void"); - SwigType_add_pointer(type); - p = NewParm(type, NewString("self"), n); - set_nextSibling(p, parms); - parms = p; - - if (!Getattr(n, "defaultargs")) { - // constructor - { - Wrapper *w = NewWrapper(); - String *call; - String *basetype = Getattr(parent, "classtype"); - String *target = Swig_method_decl(0, decl, classname, parms, 0); - call = Swig_csuperclass_call(0, basetype, superparms); - Printf(w->def, "%s::%s: %s," "\nSwig::Director(static_cast<%s*>(this)) { \n", classname, target, call, basetype); - Append(w->def, "}\n"); - Delete(target); - Wrapper_print(w, f_directors); - Delete(call); - DelWrapper(w); - } - - // constructor header - { - String *target = Swig_method_decl(0, decl, classname, parms, 1); - Printf(f_directors_h, " %s;\n", target); - Delete(target); - } - } - - Delete(sub); - Delete(classname); - Delete(supername); - Delete(parms); - return Language::classDirectorConstructor(n); - } - - int classDirectorDefaultConstructor(Node *n) { - String *classname = Swig_class_name(n); - { - Wrapper *w = NewWrapper(); - Printf(w->def, "SwigDirector_%s::SwigDirector_%s(void* self) :" - "\nSwig::Director((octave_swig_type*)self,static_cast<%s*>(this)) { \n", classname, classname, classname); - Append(w->def, "}\n"); - Wrapper_print(w, f_directors); - DelWrapper(w); - } - Printf(f_directors_h, " SwigDirector_%s(octave_swig_type* self);\n", classname); - Delete(classname); - return Language::classDirectorDefaultConstructor(n); - } - - int classDirectorMethod(Node *n, Node *parent, String *super) { - int is_void = 0; - int is_pointer = 0; - String *decl = Getattr(n, "decl"); - String *returntype = Getattr(n, "type"); - String *name = Getattr(n, "name"); - String *classname = Getattr(parent, "sym:name"); - String *c_classname = Getattr(parent, "name"); - String *symname = Getattr(n, "sym:name"); - String *declaration = NewString(""); - ParmList *l = Getattr(n, "parms"); - Wrapper *w = NewWrapper(); - String *tm; - String *wrap_args = NewString(""); - String *value = Getattr(n, "value"); - String *storage = Getattr(n, "storage"); - bool pure_virtual = false; - int status = SWIG_OK; - int idx; - bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; - - if (Cmp(storage, "virtual") == 0) { - if (Cmp(value, "0") == 0) { - pure_virtual = true; - } - } - - // determine if the method returns a pointer - is_pointer = SwigType_ispointer_return(decl); - is_void = (!Cmp(returntype, "void") && !is_pointer); - - // virtual method definition - String *target; - String *pclassname = NewStringf("SwigDirector_%s", classname); - String *qualified_name = NewStringf("%s::%s", pclassname, name); - SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type"); - target = Swig_method_decl(rtype, decl, qualified_name, l, 0); - Printf(w->def, "%s", target); - Delete(qualified_name); - Delete(target); - - // header declaration - target = Swig_method_decl(rtype, decl, name, l, 1); - Printf(declaration, " virtual %s", target); - Delete(target); - - // Get any exception classes in the throws typemap - if (Getattr(n, "noexcept")) { - Append(w->def, " noexcept"); - Append(declaration, " noexcept"); - } - ParmList *throw_parm_list = 0; - - if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { - Parm *p; - int gencomma = 0; - - Append(w->def, " throw("); - Append(declaration, " throw("); - - if (throw_parm_list) - Swig_typemap_attach_parms("throws", throw_parm_list, 0); - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - if (gencomma++) { - Append(w->def, ", "); - Append(declaration, ", "); - } - String *str = SwigType_str(Getattr(p, "type"), 0); - Append(w->def, str); - Append(declaration, str); - Delete(str); - } - } - - Append(w->def, ")"); - Append(declaration, ")"); - } - - Append(w->def, " {"); - Append(declaration, ";\n"); - - // declare method return value - // if the return value is a reference or const reference, a specialized typemap must - // handle it, including declaration of c_result ($result). - if (!is_void && (!ignored_method || pure_virtual)) { - if (!SwigType_isclass(returntype)) { - if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { - String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); - Delete(construct_result); - } else { - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); - } - } else { - String *cres = SwigType_lstr(returntype, "c_result"); - Printf(w->code, "%s;\n", cres); - Delete(cres); - } - } - - if (ignored_method) { - if (!pure_virtual) { - if (!is_void) - Printf(w->code, "return "); - String *super_call = Swig_method_call(super, l); - Printf(w->code, "%s;\n", super_call); - Delete(super_call); - } else { - Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname), - SwigType_namestr(name)); - } - } else { - // attach typemaps to arguments (C/C++ -> Octave) - String *parse_args = NewString(""); - - Swig_director_parms_fixup(l); - - Swig_typemap_attach_parms("in", l, 0); - Swig_typemap_attach_parms("directorin", l, w); - Swig_typemap_attach_parms("directorargout", l, w); - - Parm *p; - - int outputs = 0; - if (!is_void) - outputs++; - - // build argument list and type conversion string - p = l; - while (p) { - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - continue; - } - - if (Getattr(p, "tmap:directorargout") != 0) - outputs++; - - String *pname = Getattr(p, "name"); - String *ptype = Getattr(p, "type"); - Wrapper_add_local(w, "tmpv", "octave_value tmpv"); - - if ((tm = Getattr(p, "tmap:directorin")) != 0) { - String *parse = Getattr(p, "tmap:directorin:parse"); - if (!parse) { - Setattr(p, "emit:directorinput", "tmpv"); - Replaceall(tm, "$input", "tmpv"); - Replaceall(tm, "$owner", "0"); - Printv(wrap_args, tm, "\n", NIL); - Printf(wrap_args, "args.append(tmpv);\n"); - Putc('O', parse_args); - } else { - Append(parse_args, parse); - Setattr(p, "emit:directorinput", pname); - Replaceall(tm, "$input", pname); - Replaceall(tm, "$owner", "0"); - if (Len(tm) == 0) - Append(tm, pname); - } - p = Getattr(p, "tmap:directorin:next"); - continue; - } else if (Cmp(ptype, "void")) { - Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, - "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), - SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_NOWRAP; - break; - } - p = nextSibling(p); - } - - String *method_name = Getattr(n, "sym:name"); - - Printv(w->code, wrap_args, NIL); - - // emit method invocation - Wrapper_add_local(w, "args", "octave_value_list args"); - Wrapper_add_local(w, "out", "octave_value_list out"); - Wrapper_add_local(w, "idx", "std::list<octave_value_list> idx"); - Printf(w->code, "idx.push_back(octave_value_list(\"%s\"));\n", method_name); - Printf(w->code, "idx.push_back(args);\n"); - Printf(w->code, "out=swig_get_self()->subsref(\".(\",idx,%d);\n", outputs); - - String *cleanup = NewString(""); - String *outarg = NewString(""); - idx = 0; - - // marshal return value - if (!is_void) { - Printf(w->code, "if (out.length()<%d) {\n", outputs); - Printf(w->code, "Swig::DirectorTypeMismatchException::raise(\"Octave " - "method %s.%s failed to return the required number " "of arguments.\");\n", classname, method_name); - Printf(w->code, "}\n"); - - tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w); - if (tm != 0) { - char temp[24]; - sprintf(temp, "out(%d)", idx); - Replaceall(tm, "$input", temp); - // Replaceall(tm, "$argnum", temp); - Replaceall(tm, "$disown", Getattr(n, "wrap:disown") ? "SWIG_POINTER_DISOWN" : "0"); - if (Getattr(n, "tmap:directorout:implicitconv")) { - Replaceall(tm, "$implicitconv", get_implicitconv_flag(n)); - } - Replaceall(tm, "$result", "c_result"); - Printv(w->code, tm, "\n", NIL); - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, - "Unable to use return type %s in director method %s::%s (skipping method).\n", - SwigType_str(returntype, 0), SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_ERROR; - } - } - idx++; - - // marshal outputs - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:directorargout")) != 0) { - char temp[24]; - sprintf(temp, "out(%d)", idx); - Replaceall(tm, "$result", temp); - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NIL); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } - } - - Delete(parse_args); - Delete(cleanup); - Delete(outarg); - } - - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { - String *rettype = SwigType_str(returntype, 0); - if (!SwigType_isreference(returntype)) { - Printf(w->code, "return (%s) c_result;\n", rettype); - } else { - Printf(w->code, "return (%s) *c_result;\n", rettype); - } - Delete(rettype); - } - } - - Append(w->code, "}\n"); - - // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method - String *inline_extra_method = NewString(""); - if (dirprot_mode() && !is_public(n) && !pure_virtual) { - Printv(inline_extra_method, declaration, NIL); - String *extra_method_name = NewStringf("%sSwigPublic", name); - Replaceall(inline_extra_method, name, extra_method_name); - Replaceall(inline_extra_method, ";\n", " {\n "); - if (!is_void) - Printf(inline_extra_method, "return "); - String *methodcall = Swig_method_call(super, l); - Printv(inline_extra_method, methodcall, ";\n }\n", NIL); - Delete(methodcall); - Delete(extra_method_name); - } - // emit the director method - if (status == SWIG_OK) { - if (!Getattr(n, "defaultargs")) { - Replaceall(w->code, "$symname", symname); - Wrapper_print(w, f_directors); - Printv(f_directors_h, declaration, NIL); - Printv(f_directors_h, inline_extra_method, NIL); - } - } - // clean up - Delete(wrap_args); - Delete(pclassname); - DelWrapper(w); - return status; - } - - String *runtimeCode() { - String *s = NewString(""); - String *srun = Swig_include_sys("octrun.swg"); - if (!srun) { - Printf(stderr, "*** Unable to open 'octrun.swg'\n"); - } else { - Append(s, srun); - Delete(srun); - } - return s; - } - - String *defaultExternalRuntimeFilename() { - return NewString("swigoctaverun.h"); - } -}; - -extern "C" Language *swig_octave(void) { - return new OCTAVE(); -} diff --git a/contrib/tools/swig/Source/Modules/overload.cxx b/contrib/tools/swig/Source/Modules/overload.cxx deleted file mode 100644 index b94e87ebb71..00000000000 --- a/contrib/tools/swig/Source/Modules/overload.cxx +++ /dev/null @@ -1,866 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * overload.cxx - * - * This file is used to analyze overloaded functions and methods. - * It looks at signatures and tries to gather information for - * building a dispatch function. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" - -#define MAX_OVERLOAD 4096 - -/* Overload "argc" and "argv" */ -String *argv_template_string; -String *argc_template_string; - -namespace { -struct Overloaded { - Node *n; /* Node */ - int argc; /* Argument count */ - ParmList *parms; /* Parameters used for overload check */ - int error; /* Ambiguity error */ - bool implicitconv_function; /* For ordering implicitconv functions*/ -}; -} - -static int fast_dispatch_mode = 0; -static int cast_dispatch_mode = 0; - -/* Set fast_dispatch_mode */ -void Wrapper_fast_dispatch_mode_set(int flag) { - fast_dispatch_mode = flag; -} - -void Wrapper_cast_dispatch_mode_set(int flag) { - cast_dispatch_mode = flag; -} - -/* ----------------------------------------------------------------------------- - * mark_implicitconv_function() - * - * Mark function if it contains an implicitconv type in the parameter list - * ----------------------------------------------------------------------------- */ -static void mark_implicitconv_function(Overloaded& onode) { - Parm *parms = onode.parms; - if (parms) { - bool is_implicitconv_function = false; - Parm *p = parms; - while (p) { - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - continue; - } - if (GetFlag(p, "implicitconv")) { - is_implicitconv_function = true; - break; - } - p = nextSibling(p); - } - if (is_implicitconv_function) - onode.implicitconv_function = true; - } -} - -/* ----------------------------------------------------------------------------- - * Swig_overload_rank() - * - * This function takes an overloaded declaration and creates a list that ranks - * all overloaded methods in an order that can be used to generate a dispatch - * function. - * Slight difference in the way this function is used by scripting languages and - * statically typed languages. The script languages call this method via - * Swig_overload_dispatch() - where wrappers for all overloaded methods are generated, - * however sometimes the code can never be executed. The non-scripting languages - * call this method via Swig_overload_check() for each overloaded method in order - * to determine whether or not the method should be wrapped. Note the slight - * difference when overloading methods that differ by const only. The - * scripting languages will ignore the const method, whereas the non-scripting - * languages ignore the first method parsed. - * ----------------------------------------------------------------------------- */ - -List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { - Overloaded nodes[MAX_OVERLOAD]; - int nnodes = 0; - Node *o = Getattr(n, "sym:overloaded"); - Node *c; - - if (!o) - return 0; - - c = o; - while (c) { - if (Getattr(c, "error")) { - c = Getattr(c, "sym:nextSibling"); - continue; - } - /* if (SmartPointer && Getattr(c,"cplus:staticbase")) { - c = Getattr(c,"sym:nextSibling"); - continue; - } */ - - /* Make a list of all the declarations (methods) that are overloaded with - * this one particular method name */ - if (Getattr(c, "wrap:name")) { - assert(nnodes < MAX_OVERLOAD); - nodes[nnodes].n = c; - nodes[nnodes].parms = Getattr(c, "wrap:parms"); - nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms); - nodes[nnodes].error = 0; - nodes[nnodes].implicitconv_function = false; - - mark_implicitconv_function(nodes[nnodes]); - nnodes++; - } - c = Getattr(c, "sym:nextSibling"); - } - - /* Sort the declarations by required argument count */ - { - int i, j; - for (i = 0; i < nnodes; i++) { - for (j = i + 1; j < nnodes; j++) { - if (nodes[i].argc > nodes[j].argc) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - } - } - } - - /* Sort the declarations by argument types */ - { - int i, j; - for (i = 0; i < nnodes - 1; i++) { - if (nodes[i].argc == nodes[i + 1].argc) { - for (j = i + 1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) { - Parm *p1 = nodes[i].parms; - Parm *p2 = nodes[j].parms; - int differ = 0; - int num_checked = 0; - while (p1 && p2 && (num_checked < nodes[i].argc)) { - // Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type")); - if (checkAttribute(p1, "tmap:in:numinputs", "0")) { - p1 = Getattr(p1, "tmap:in:next"); - continue; - } - if (checkAttribute(p2, "tmap:in:numinputs", "0")) { - p2 = Getattr(p2, "tmap:in:next"); - continue; - } - String *t1 = Getattr(p1, "tmap:typecheck:precedence"); - String *t2 = Getattr(p2, "tmap:typecheck:precedence"); - if ((!t1) && (!nodes[i].error)) { - Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n), - "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n", - Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0)); - nodes[i].error = 1; - } else if ((!t2) && (!nodes[j].error)) { - Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n", - Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0)); - nodes[j].error = 1; - } - if (t1 && t2) { - int t1v, t2v; - t1v = atoi(Char(t1)); - t2v = atoi(Char(t2)); - differ = t1v - t2v; - } else if (!t1 && t2) - differ = 1; - else if (t1 && !t2) - differ = -1; - else if (!t1 && !t2) - differ = -1; - num_checked++; - if (differ > 0) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - break; - } else if ((differ == 0) && (Strcmp(t1, "0") == 0)) { - t1 = Getattr(p1, "equivtype"); - t1 = t1 ? t1 : Getattr(p1, "ltype"); - if (!t1) { - t1 = SwigType_ltype(Getattr(p1, "type")); - if (Getattr(p1, "tmap:typecheck:SWIGTYPE")) { - SwigType_add_pointer(t1); - } - Setattr(p1, "ltype", t1); - } - t2 = Getattr(p2, "equivtype"); - t2 = t2 ? t2 : Getattr(p2, "ltype"); - if (!t2) { - t2 = SwigType_ltype(Getattr(p2, "type")); - if (Getattr(p2, "tmap:typecheck:SWIGTYPE")) { - SwigType_add_pointer(t2); - } - Setattr(p2, "ltype", t2); - } - - /* Need subtype check here. If t2 is a subtype of t1, then we need to change the - order */ - - if (SwigType_issubtype(t2, t1)) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - - if (Strcmp(t1, t2) != 0) { - differ = 1; - break; - } - } else if (differ) { - break; - } - if (Getattr(p1, "tmap:in:next")) { - p1 = Getattr(p1, "tmap:in:next"); - } else { - p1 = nextSibling(p1); - } - if (Getattr(p2, "tmap:in:next")) { - p2 = Getattr(p2, "tmap:in:next"); - } else { - p2 = nextSibling(p2); - } - } - if (!differ) { - /* See if declarations differ by const only */ - String *decl1 = Getattr(nodes[i].n, "decl"); - String *decl2 = Getattr(nodes[j].n, "decl"); - if (decl1 && decl2) { - /* Remove ref-qualifiers. Note that rvalue ref-qualifiers are already ignored and - * it is illegal to overload a function with and without ref-qualifiers. So with - * all the combinations of ref-qualifiers and cv-qualifiers, we just detect - * the cv-qualifier (const) overloading. */ - String *d1 = Copy(decl1); - String *d2 = Copy(decl2); - if (SwigType_isreference(d1) || SwigType_isrvalue_reference(d1)) { - Delete(SwigType_pop(d1)); - } - if (SwigType_isreference(d2) || SwigType_isrvalue_reference(d2)) { - Delete(SwigType_pop(d2)); - } - String *dq1 = Copy(d1); - String *dq2 = Copy(d2); - if (SwigType_isconst(d1)) { - Delete(SwigType_pop(dq1)); - } - if (SwigType_isconst(d2)) { - Delete(SwigType_pop(dq2)); - } - if (Strcmp(dq1, dq2) == 0) { - - if (SwigType_isconst(d1) && !SwigType_isconst(d2)) { - if (script_lang_wrapping) { - // Swap nodes so that the const method gets ignored (shadowed by the non-const method) - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - differ = 1; - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), - "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - } - nodes[j].error = 1; - } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) { - differ = 1; - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), - "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - } - nodes[j].error = 1; - } - } - Delete(dq1); - Delete(dq2); - } - } - if (!differ) { - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n), - "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - nodes[j].error = 1; - } - } - } - } - } - } - List *result = NewList(); - { - int i; - int argc_changed_index = -1; - for (i = 0; i < nnodes; i++) { - if (nodes[i].error) - Setattr(nodes[i].n, "overload:ignore", "1"); - Append(result, nodes[i].n); - // Printf(stdout,"[ %d ] %d %s\n", i, nodes[i].implicitconv_function, ParmList_errorstr(nodes[i].parms)); - if (i == nnodes-1 || nodes[i].argc != nodes[i+1].argc) { - if (argc_changed_index+2 < nnodes && (nodes[argc_changed_index+1].argc == nodes[argc_changed_index+2].argc)) { - // Add additional implicitconv functions in same order as already ranked. - // Consider overloaded functions by argument count... only add additional implicitconv functions if - // the number of functions with the same arg count > 1, ie, only if overloaded by same argument count. - int j; - for (j = argc_changed_index + 1; j <= i; j++) { - if (nodes[j].implicitconv_function) { - SetFlag(nodes[j].n, "implicitconvtypecheckoff"); - Append(result, nodes[j].n); - // Printf(stdout,"[ %d ] %d + %s\n", j, nodes[j].implicitconv_function, ParmList_errorstr(nodes[j].parms)); - } - } - } - argc_changed_index = i; - } - } - } - return result; -} - -// /* ----------------------------------------------------------------------------- -// * print_typecheck() -// * ----------------------------------------------------------------------------- */ - -static bool print_typecheck(String *f, int j, Parm *pj, bool implicitconvtypecheckoff) { - char tmp[256]; - sprintf(tmp, Char(argv_template_string), j); - String *tm = Getattr(pj, "tmap:typecheck"); - if (tm) { - tm = Copy(tm); - Replaceid(tm, Getattr(pj, "lname"), "_v"); - String *conv = Getattr(pj, "implicitconv"); - if (conv && !implicitconvtypecheckoff) { - Replaceall(tm, "$implicitconv", conv); - } else { - Replaceall(tm, "$implicitconv", "0"); - } - Replaceall(tm, "$input", tmp); - Printv(f, tm, "\n", NIL); - Delete(tm); - return true; - } else - return false; -} - -/* ----------------------------------------------------------------------------- - * ReplaceFormat() - * ----------------------------------------------------------------------------- */ - -static String *ReplaceFormat(const_String_or_char_ptr fmt, int j) { - String *lfmt = NewString(fmt); - char buf[50]; - sprintf(buf, "%d", j); - Replaceall(lfmt, "$numargs", buf); - int i; - String *commaargs = NewString(""); - for (i = 0; i < j; i++) { - Printv(commaargs, ", ", NIL); - Printf(commaargs, Char(argv_template_string), i); - } - Replaceall(lfmt, "$commaargs", commaargs); - return lfmt; -} - -/* ----------------------------------------------------------------------------- - * Swig_overload_dispatch() - * - * Generate a dispatch function. argc is assumed to hold the argument count. - * argv is the argument vector. - * - * Note that for C++ class member functions, Swig_overload_dispatch() assumes - * that argc includes the "self" argument and that the first element of argv[] - * is the "self" argument. So for a member function: - * - * Foo::bar(int x, int y, int z); - * - * the argc should be 4 (not 3!) and the first element of argv[] would be - * the appropriate scripting language reference to "self". For regular - * functions (and static class functions) the argc and argv only include - * the regular function arguments. - * ----------------------------------------------------------------------------- */ - -/* - Cast dispatch mechanism. -*/ -String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *maxargs) { - int i, j; - - *maxargs = 1; - - String *f = NewString(""); - String *sw = NewString(""); - Printf(f, "{\n"); - Printf(f, "unsigned long _index = 0;\n"); - Printf(f, "SWIG_TypeRank _rank = 0; \n"); - - /* Get a list of methods ranked by precedence values and argument count */ - List *dispatch = Swig_overload_rank(n, true); - int nfunc = Len(dispatch); - - /* Loop over the functions */ - - bool emitcheck = true; - for (i = 0; i < nfunc; i++) { - int fn = 0; - Node *ni = Getitem(dispatch, i); - Parm *pi = Getattr(ni, "wrap:parms"); - bool implicitconvtypecheckoff = GetFlag(ni, "implicitconvtypecheckoff") != 0; - int num_required = emit_num_required(pi); - int num_arguments = emit_num_arguments(pi); - if (num_arguments > *maxargs) - *maxargs = num_arguments; - - if (num_required == num_arguments) { - Printf(f, "if (%s == %d) {\n", argc_template_string, num_required); - } else { - Printf(f, "if ((%s >= %d) && (%s <= %d)) {\n", argc_template_string, num_required, argc_template_string, num_arguments); - } - Printf(f, "SWIG_TypeRank _ranki = 0;\n"); - Printf(f, "SWIG_TypeRank _rankm = 0;\n"); - if (num_arguments) - Printf(f, "SWIG_TypeRank _pi = 1;\n"); - - /* create a list with the wrappers that collide with the - current one based on argument number */ - List *coll = NewList(); - for (int k = i + 1; k < nfunc; k++) { - Node *nk = Getitem(dispatch, k); - Parm *pk = Getattr(nk, "wrap:parms"); - int nrk = emit_num_required(pk); - int nak = emit_num_arguments(pk); - if ((nrk >= num_required && nrk <= num_arguments) || (nak >= num_required && nak <= num_arguments) || (nrk <= num_required && nak >= num_arguments)) - Append(coll, nk); - } - - // printf("overload: %s coll=%d\n", Char(Getattr(n, "sym:name")), Len(coll)); - - int num_braces = 0; - bool test = (num_arguments > 0); - if (test) { - int need_v = 1; - j = 0; - Parm *pj = pi; - while (pj) { - if (checkAttribute(pj, "tmap:in:numinputs", "0")) { - pj = Getattr(pj, "tmap:in:next"); - continue; - } - - String *tm = Getattr(pj, "tmap:typecheck"); - if (tm) { - tm = Copy(tm); - /* normalise for comparison later */ - Replaceid(tm, Getattr(pj, "lname"), "_v"); - - /* if all the wrappers have the same type check on this - argument we can optimize it out */ - for (int k = 0; k < Len(coll) && !emitcheck; k++) { - Node *nk = Getitem(coll, k); - Parm *pk = Getattr(nk, "wrap:parms"); - int nak = emit_num_arguments(pk); - if (nak <= j) - continue; - int l = 0; - Parm *pl = pk; - /* finds arg j on the collider wrapper */ - while (pl && l <= j) { - if (checkAttribute(pl, "tmap:in:numinputs", "0")) { - pl = Getattr(pl, "tmap:in:next"); - continue; - } - if (l == j) { - /* we are at arg j, so we compare the tmaps now */ - String *tml = Getattr(pl, "tmap:typecheck"); - /* normalise it before comparing */ - if (tml) - Replaceid(tml, Getattr(pl, "lname"), "_v"); - if (!tml || Cmp(tm, tml)) - emitcheck = true; - //printf("tmap: %s[%d] (%d) => %s\n\n", - // Char(Getattr(nk, "sym:name")), - // l, emitcheck, tml?Char(tml):0); - } - Parm *pl1 = Getattr(pl, "tmap:in:next"); - if (pl1) - pl = pl1; - else - pl = nextSibling(pl); - l++; - } - } - - if (emitcheck) { - if (need_v) { - Printf(f, "int _v = 0;\n"); - need_v = 0; - } - if (j >= num_required) { - Printf(f, "if (%s > %d) {\n", argc_template_string, j); - num_braces++; - } - String *tmp = NewStringf(argv_template_string, j); - - String *conv = Getattr(pj, "implicitconv"); - if (conv && !implicitconvtypecheckoff) { - Replaceall(tm, "$implicitconv", conv); - } else { - Replaceall(tm, "$implicitconv", "0"); - } - Replaceall(tm, "$input", tmp); - Printv(f, "{\n", tm, "}\n", NIL); - Delete(tm); - fn = i + 1; - Printf(f, "if (!_v) goto check_%d;\n", fn); - Printf(f, "_ranki += _v*_pi;\n"); - Printf(f, "_rankm += _pi;\n"); - Printf(f, "_pi *= SWIG_MAXCASTRANK;\n"); - } - } - if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) { - /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */ - Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni), - "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n", - Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0)); - } - Parm *pj1 = Getattr(pj, "tmap:in:next"); - if (pj1) - pj = pj1; - else - pj = nextSibling(pj); - j++; - } - } - - /* close braces */ - for ( /* empty */ ; num_braces > 0; num_braces--) - Printf(f, "}\n"); - - Printf(f, "if (!_index || (_ranki < _rank)) {\n"); - Printf(f, " _rank = _ranki; _index = %d;\n", i + 1); - Printf(f, " if (_rank == _rankm) goto dispatch;\n"); - Printf(f, "}\n"); - String *lfmt = ReplaceFormat(fmt, num_arguments); - Printf(sw, "case %d:\n", i + 1); - Printf(sw, Char(lfmt), Getattr(ni, "wrap:name")); - Printf(sw, "\n"); - - Printf(f, "}\n"); /* braces closes "if" for this method */ - if (fn) - Printf(f, "check_%d:\n\n", fn); - - if (implicitconvtypecheckoff) - Delattr(ni, "implicitconvtypecheckoff"); - - Delete(lfmt); - Delete(coll); - } - Delete(dispatch); - Printf(f, "dispatch:\n"); - Printf(f, "switch(_index) {\n"); - Printf(f, "%s", sw); - Printf(f, "}\n"); - - Printf(f, "}\n"); - return f; -} - -/* - Fast dispatch mechanism, provided by Salvador Fandi~no Garc'ia (#930586). -*/ -static String *overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *maxargs, const_String_or_char_ptr fmt_fastdispatch) { - int i, j; - - *maxargs = 1; - - String *f = NewString(""); - - /* Get a list of methods ranked by precedence values and argument count */ - List *dispatch = Swig_overload_rank(n, true); - int nfunc = Len(dispatch); - - /* Loop over the functions */ - - for (i = 0; i < nfunc; i++) { - int fn = 0; - Node *ni = Getitem(dispatch, i); - Parm *pi = Getattr(ni, "wrap:parms"); - bool implicitconvtypecheckoff = GetFlag(ni, "implicitconvtypecheckoff") != 0; - int num_required = emit_num_required(pi); - int num_arguments = emit_num_arguments(pi); - if (num_arguments > *maxargs) - *maxargs = num_arguments; - - if (num_required == num_arguments) { - Printf(f, "if (%s == %d) {\n", argc_template_string, num_required); - } else { - Printf(f, "if ((%s >= %d) && (%s <= %d)) {\n", argc_template_string, num_required, argc_template_string, num_arguments); - } - - /* create a list with the wrappers that collide with the - current one based on argument number */ - List *coll = NewList(); - for (int k = i + 1; k < nfunc; k++) { - Node *nk = Getitem(dispatch, k); - Parm *pk = Getattr(nk, "wrap:parms"); - int nrk = emit_num_required(pk); - int nak = emit_num_arguments(pk); - if ((nrk >= num_required && nrk <= num_arguments) || (nak >= num_required && nak <= num_arguments) || (nrk <= num_required && nak >= num_arguments)) - Append(coll, nk); - } - - // printf("overload: %s coll=%d\n", Char(Getattr(n, "sym:name")), Len(coll)); - - bool emitcheck = false; - int num_braces = 0; - bool test = (Len(coll) > 0 && num_arguments); - if (test) { - int need_v = 1; - j = 0; - Parm *pj = pi; - while (pj) { - if (checkAttribute(pj, "tmap:in:numinputs", "0")) { - pj = Getattr(pj, "tmap:in:next"); - continue; - } - - String *tm = Getattr(pj, "tmap:typecheck"); - if (tm) { - tm = Copy(tm); - /* normalise for comparison later */ - Replaceid(tm, Getattr(pj, "lname"), "_v"); - - /* if all the wrappers have the same type check on this - argument we can optimize it out */ - emitcheck = false; - for (int k = 0; k < Len(coll) && !emitcheck; k++) { - Node *nk = Getitem(coll, k); - Parm *pk = Getattr(nk, "wrap:parms"); - int nak = emit_num_arguments(pk); - if (nak <= j) - continue; - int l = 0; - Parm *pl = pk; - /* finds arg j on the collider wrapper */ - while (pl && l <= j) { - if (checkAttribute(pl, "tmap:in:numinputs", "0")) { - pl = Getattr(pl, "tmap:in:next"); - continue; - } - if (l == j) { - /* we are at arg j, so we compare the tmaps now */ - String *tml = Getattr(pl, "tmap:typecheck"); - /* normalise it before comparing */ - if (tml) - Replaceid(tml, Getattr(pl, "lname"), "_v"); - if (!tml || Cmp(tm, tml)) - emitcheck = true; - //printf("tmap: %s[%d] (%d) => %s\n\n", - // Char(Getattr(nk, "sym:name")), - // l, emitcheck, tml?Char(tml):0); - } - Parm *pl1 = Getattr(pl, "tmap:in:next"); - if (pl1) - pl = pl1; - else - pl = nextSibling(pl); - l++; - } - } - - if (emitcheck) { - if (need_v) { - Printf(f, "int _v = 0;\n"); - need_v = 0; - } - if (j >= num_required) { - Printf(f, "if (%s > %d) {\n", argc_template_string, j); - num_braces++; - } - String *tmp = NewStringf(argv_template_string, j); - - String *conv = Getattr(pj, "implicitconv"); - if (conv && !implicitconvtypecheckoff) { - Replaceall(tm, "$implicitconv", conv); - } else { - Replaceall(tm, "$implicitconv", "0"); - } - Replaceall(tm, "$input", tmp); - Printv(f, "{\n", tm, "}\n", NIL); - Delete(tm); - fn = i + 1; - Printf(f, "if (!_v) goto check_%d;\n", fn); - } - } - if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) { - /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */ - Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni), - "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n", - Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0)); - } - Parm *pj1 = Getattr(pj, "tmap:in:next"); - if (pj1) - pj = pj1; - else - pj = nextSibling(pj); - j++; - } - } - - /* close braces */ - for ( /* empty */ ; num_braces > 0; num_braces--) - Printf(f, "}\n"); - - // The language module may want to generate different code for last overloaded function called (with same number of arguments) - String *lfmt = ReplaceFormat(!emitcheck && fmt_fastdispatch ? fmt_fastdispatch : fmt, num_arguments); - Printf(f, Char(lfmt), Getattr(ni, "wrap:name")); - - Printf(f, "}\n"); /* braces closes "if" for this method */ - if (fn) - Printf(f, "check_%d:\n\n", fn); - - if (implicitconvtypecheckoff) - Delattr(ni, "implicitconvtypecheckoff"); - - Delete(lfmt); - Delete(coll); - } - Delete(dispatch); - return f; -} - -String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *maxargs, const_String_or_char_ptr fmt_fastdispatch) { - - if (fast_dispatch_mode || GetFlag(n, "feature:fastdispatch")) { - return overload_dispatch_fast(n, fmt, maxargs, fmt_fastdispatch); - } - - int i, j; - - *maxargs = 1; - - String *f = NewString(""); - - /* Get a list of methods ranked by precedence values and argument count */ - List *dispatch = Swig_overload_rank(n, true); - int nfunc = Len(dispatch); - - /* Loop over the functions */ - - for (i = 0; i < nfunc; i++) { - Node *ni = Getitem(dispatch, i); - Parm *pi = Getattr(ni, "wrap:parms"); - bool implicitconvtypecheckoff = GetFlag(ni, "implicitconvtypecheckoff") != 0; - int num_required = emit_num_required(pi); - int num_arguments = emit_num_arguments(pi); - if (GetFlag(n, "wrap:this")) { - num_required++; - num_arguments++; - } - if (num_arguments > *maxargs) - *maxargs = num_arguments; - - if (num_required == num_arguments) { - Printf(f, "if (%s == %d) {\n", argc_template_string, num_required); - } else { - Printf(f, "if ((%s >= %d) && (%s <= %d)) {\n", argc_template_string, num_required, argc_template_string, num_arguments); - } - - if (num_arguments) { - Printf(f, "int _v = 0;\n"); - } - - int num_braces = 0; - j = 0; - Parm *pj = pi; - while (pj) { - if (checkAttribute(pj, "tmap:in:numinputs", "0")) { - pj = Getattr(pj, "tmap:in:next"); - continue; - } - if (j >= num_required) { - String *lfmt = ReplaceFormat(fmt, num_arguments); - Printf(f, "if (%s <= %d) {\n", argc_template_string, j); - Printf(f, Char(lfmt), Getattr(ni, "wrap:name")); - Printf(f, "}\n"); - Delete(lfmt); - } - if (print_typecheck(f, (GetFlag(n, "wrap:this") ? j + 1 : j), pj, implicitconvtypecheckoff)) { - Printf(f, "if (_v) {\n"); - num_braces++; - } - if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) { - /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */ - Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni), - "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n", - Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0)); - } - Parm *pk = Getattr(pj, "tmap:in:next"); - if (pk) - pj = pk; - else - pj = nextSibling(pj); - j++; - } - String *lfmt = ReplaceFormat(fmt, num_arguments); - Printf(f, Char(lfmt), Getattr(ni, "wrap:name")); - Delete(lfmt); - /* close braces */ - for ( /* empty */ ; num_braces > 0; num_braces--) - Printf(f, "}\n"); - Printf(f, "}\n"); /* braces closes "if" for this method */ - if (implicitconvtypecheckoff) - Delattr(ni, "implicitconvtypecheckoff"); - } - Delete(dispatch); - return f; -} - -/* ----------------------------------------------------------------------------- - * Swig_overload_check() - * ----------------------------------------------------------------------------- */ -void Swig_overload_check(Node *n) { - Swig_overload_rank(n, false); -} diff --git a/contrib/tools/swig/Source/Modules/perl5.cxx b/contrib/tools/swig/Source/Modules/perl5.cxx deleted file mode 100644 index 0cbf6b17a74..00000000000 --- a/contrib/tools/swig/Source/Modules/perl5.cxx +++ /dev/null @@ -1,2502 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * perl5.cxx - * - * Perl5 language module for SWIG. - * ------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" -#include <ctype.h> - -static const char *usage = "\ -Perl 5 Options (available with -perl5)\n\ - -compat - Compatibility mode\n\ - -const - Wrap constants as constants and not variables (implies -proxy)\n\ - -nopm - Do not generate the .pm file\n\ - -noproxy - Don't create proxy classes\n\ - -proxy - Create proxy classes (enabled by default)\n\ - -static - Omit code related to dynamic loading\n\ -\n"; - -static int compat = 0; - -static int no_pmfile = 0; - -static int export_all = 0; - -/* - * pmfile - * set by the -pm flag, overrides the name of the .pm file - */ -static String *pmfile = 0; - -/* - * module - * set by the %module directive, e.g. "Xerces". It will determine - * the name of the .pm file, and the dynamic library, and the name - * used by any module wanting to %import the module. - */ -static String *module = 0; - -/* - * namespace_module - * the fully namespace qualified name of the module. It will be used - * to set the package namespace in the .pm file, as well as the name - * of the initialization methods in the glue library. This will be - * the same as module, above, unless the %module directive is given - * the 'package' option, e.g. %module(package="Foo::Bar") "baz" - */ -static String *namespace_module = 0; - -/* - * cmodule - * the namespace of the internal glue code, set to the value of - * module with a 'c' appended - */ -static String *cmodule = 0; - -/* - * dest_package - * an optional namespace to put all classes into. Specified by using - * the %module(package="Foo::Bar") "baz" syntax - */ -static String *dest_package = 0; - -static String *command_tab = 0; -static String *constant_tab = 0; -static String *variable_tab = 0; - -static File *f_begin = 0; -static File *f_runtime = 0; -static File *f_runtime_h = 0; -static File *f_header = 0; -static File *f_wrappers = 0; -static File *f_directors = 0; -static File *f_directors_h = 0; -static File *f_init = 0; -static File *f_pm = 0; -static String *pm; /* Package initialization code */ -static String *magic; /* Magic variable wrappers */ - -static int staticoption = 0; - -// controlling verbose output -static int verbose = 0; - -/* The following variables are used to manage Perl5 classes */ - -static int blessed = 1; /* Enable object oriented features */ -static int do_constants = 0; /* Constant wrapping */ -static List *classlist = 0; /* List of classes */ -static int have_constructor = 0; -static int have_destructor = 0; -static int have_data_members = 0; -static String *class_name = 0; /* Name of the class (what Perl thinks it is) */ -static String *real_classname = 0; /* Real name of C/C++ class */ -static String *fullclassname = 0; - -static String *pcode = 0; /* Perl code associated with each class */ - /* static String *blessedmembers = 0; *//* Member data associated with each class */ -static int member_func = 0; /* Set to 1 when wrapping a member function */ -static String *func_stubs = 0; /* Function stubs */ -static String *const_stubs = 0; /* Constant stubs */ -static int num_consts = 0; /* Number of constants */ -static String *var_stubs = 0; /* Variable stubs */ -static String *exported = 0; /* Exported symbols */ -static String *pragma_include = 0; -static String *additional_perl_code = 0; /* Additional Perl code from %perlcode %{ ... %} */ -static Hash *operators = 0; -static int have_operators = 0; - -class PERL5:public Language { -public: - - PERL5():Language () { - Clear(argc_template_string); - Printv(argc_template_string, "items", NIL); - Clear(argv_template_string); - Printv(argv_template_string, "ST(%d)", NIL); - director_language = 1; - } - - /* Test to see if a type corresponds to something wrapped with a shadow class */ - Node *is_shadow(SwigType *t) { - Node *n; - n = classLookup(t); - /* Printf(stdout,"'%s' --> '%p'\n", t, n); */ - if (n) { - if (!Getattr(n, "perl5:proxy")) { - setclassname(n); - } - return Getattr(n, "perl5:proxy"); - } - return 0; - } - - /* ------------------------------------------------------------ - * main() - * ------------------------------------------------------------ */ - - virtual void main(int argc, char *argv[]) { - int i = 1; - - SWIG_library_directory("perl5"); - - for (i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-package") == 0) { - Printv(stderr, - "*** -package is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n", NIL); - Exit(EXIT_FAILURE); - } else if (strcmp(argv[i], "-interface") == 0) { - Printv(stderr, - "*** -interface is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n", NIL); - Exit(EXIT_FAILURE); - } else if (strcmp(argv[i], "-exportall") == 0) { - export_all = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-static") == 0) { - staticoption = 1; - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) { - blessed = 1; - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-noproxy") == 0)) { - blessed = 0; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-const") == 0) { - do_constants = 1; - blessed = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nopm") == 0) { - no_pmfile = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-pm") == 0) { - Swig_mark_arg(i); - i++; - pmfile = NewString(argv[i]); - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-v") == 0) { - Swig_mark_arg(i); - verbose++; - } else if (strcmp(argv[i], "-compat") == 0) { - compat = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-help") == 0) { - fputs(usage, stdout); - } else if (strcmp(argv[i], "-cppcast") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nocppcast") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); - Swig_mark_arg(i); - Exit(EXIT_FAILURE); - } - } - } - - Preprocessor_define("SWIGPERL 1", 0); - // SWIGPERL5 is deprecated, and no longer documented. - Preprocessor_define("SWIGPERL5 1", 0); - SWIG_typemap_lang("perl5"); - SWIG_config_file("perl5.swg"); - allow_overloading(); - } - - /* ------------------------------------------------------------ - * top() - * ------------------------------------------------------------ */ - - virtual int top(Node *n) { - /* check if directors are enabled for this module. note: this - * is a "master" switch, without which no director code will be - * emitted. %feature("director") statements are also required - * to enable directors for individual classes or methods. - * - * use %module(directors="1") modulename at the start of the - * interface file to enable director generation. - * - * TODO: directors are disallowed in conjunction with many command - * line options. Some of them are probably safe, but it will take - * some effort to validate each one. - */ - { - Node *mod = Getattr(n, "module"); - if (mod) { - Node *options = Getattr(mod, "options"); - if (options) { - int dirprot = 0; - if (Getattr(options, "dirprot")) - dirprot = 1; - if (Getattr(options, "nodirprot")) - dirprot = 0; - if (Getattr(options, "directors")) { - int allow = 1; - if (export_all) { - Printv(stderr, "*** directors are not supported with -exportall\n", NIL); - allow = 0; - } - if (staticoption) { - Printv(stderr, "*** directors are not supported with -static\n", NIL); - allow = 0; - } - if (!blessed) { - Printv(stderr, "*** directors are not supported with -noproxy\n", NIL); - allow = 0; - } - if (no_pmfile) { - Printv(stderr, "*** directors are not supported with -nopm\n", NIL); - allow = 0; - } - if (compat) { - Printv(stderr, "*** directors are not supported with -compat\n", NIL); - allow = 0; - } - if (allow) { - allow_directors(); - if (dirprot) - allow_dirprot(); - } - } - } - } - } - - /* Initialize all of the output files */ - String *outfile = Getattr(n, "outfile"); - String *outfile_h = Getattr(n, "outfile_h"); - - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - f_wrappers = NewString(""); - f_directors_h = NewString(""); - f_directors = NewString(""); - - if (directorsEnabled()) { - f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); - if (!f_runtime_h) { - FileErrorDisplay(outfile_h); - Exit(EXIT_FAILURE); - } - } - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", f_init); - Swig_register_filebyname("director", f_directors); - Swig_register_filebyname("director_h", f_directors_h); - - classlist = NewList(); - - pm = NewString(""); - func_stubs = NewString(""); - var_stubs = NewString(""); - const_stubs = NewString(""); - exported = NewString(""); - magic = NewString(""); - pragma_include = NewString(""); - additional_perl_code = NewString(""); - - command_tab = NewString("static swig_command_info swig_commands[] = {\n"); - constant_tab = NewString("static swig_constant_info swig_constants[] = {\n"); - variable_tab = NewString("static swig_variable_info swig_variables[] = {\n"); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "PERL"); - - if (directorsEnabled()) { - Printf(f_runtime, "#define SWIG_DIRECTORS\n"); - } - Printf(f_runtime, "#define SWIG_CASTRANK_MODE\n"); - Printf(f_runtime, "\n"); - - // Is the imported module in another package? (IOW, does it use the - // %module(package="name") option and it's different than the package - // of this module.) - Node *mod = Getattr(n, "module"); - Node *options = Getattr(mod, "options"); - module = Copy(Getattr(n,"name")); - - String *underscore_module = Copy(module); - Replaceall(underscore_module,":","_"); - - if (verbose > 0) { - fprintf(stdout, "top: using namespace_module: %s\n", Char(namespace_module)); - } - - if (directorsEnabled()) { - Swig_banner(f_directors_h); - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", underscore_module); - Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", underscore_module); - if (dirprot_mode()) { - Printf(f_directors_h, "#include <map>\n"); - Printf(f_directors_h, "#include <string>\n\n"); - } - - Printf(f_directors, "\n\n"); - Printf(f_directors, "/* ---------------------------------------------------\n"); - Printf(f_directors, " * C++ director class methods\n"); - Printf(f_directors, " * --------------------------------------------------- */\n\n"); - if (outfile_h) { - String *filename = Swig_file_filename(outfile_h); - Printf(magic, "#include \"%s\"\n\n", filename); - Delete(filename); - } - } - - if (verbose > 0) { - fprintf(stdout, "top: using module: %s\n", Char(module)); - } - - dest_package = options ? Getattr(options, "package") : 0; - if (dest_package) { - namespace_module = Copy(dest_package); - if (verbose > 0) { - fprintf(stdout, "top: Found package: %s\n",Char(dest_package)); - } - } else { - namespace_module = Copy(module); - if (verbose > 0) { - fprintf(stdout, "top: No package found\n"); - } - } - /* If we're in blessed mode, change the package name to "packagec" */ - - if (blessed) { - cmodule = NewStringf("%sc",namespace_module); - } else { - cmodule = NewString(namespace_module); - } - - /* Create a .pm file - * Need to strip off any prefixes that might be found in - * the module name */ - - if (no_pmfile) { - f_pm = NewString(0); - } else { - if (!pmfile) { - char *m = Char(module) + Len(module); - while (m != Char(module)) { - if (*m == ':') { - m++; - break; - } - m--; - } - pmfile = NewStringf("%s.pm", m); - } - String *filen = NewStringf("%s%s", SWIG_output_directory(), pmfile); - if ((f_pm = NewFile(filen, "w", SWIG_output_files())) == 0) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Delete(filen); - filen = NULL; - Swig_register_filebyname("pm", f_pm); - Swig_register_filebyname("perl", f_pm); - } - { - String *boot_name = NewStringf("boot_%s", underscore_module); - Printf(f_header,"#define SWIG_init %s\n\n", boot_name); - Printf(f_header,"#define SWIG_name \"%s::%s\"\n", cmodule, boot_name); - Printf(f_header,"#define SWIG_prefix \"%s::\"\n", cmodule); - Delete(boot_name); - } - - Swig_banner_target_lang(f_pm, "#"); - Printf(f_pm, "\n"); - - Printf(f_pm, "package %s;\n", module); - - /* - * If the package option has been given we are placing our - * symbols into some other packages namespace, so we do not - * mess with @ISA or require for that package - */ - if (dest_package) { - Printf(f_pm,"use base qw(DynaLoader);\n"); - } else { - Printf(f_pm,"use base qw(Exporter);\n"); - if (!staticoption) { - Printf(f_pm,"use base qw(DynaLoader);\n"); - } - } - - /* Start creating magic code */ - - Printv(magic, - "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n", - "#define MAGIC_CLASS\n", - "SWIGCLASS_STATIC int swig_magic_readonly(pTHX_ SV *SWIGUNUSEDPARM(sv), MAGIC *SWIGUNUSEDPARM(mg)) {\n", - tab4, "MAGIC_PPERL\n", tab4, "croak(\"Value is read-only.\");\n", tab4, "return 0;\n", "}\n", NIL); - - Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); - - /* emit wrappers */ - Language::top(n); - - if (directorsEnabled()) { - // Insert director runtime into the f_runtime file (make it occur before %header section) - Swig_insert_file("director_common.swg", f_runtime); - Swig_insert_file("director.swg", f_runtime); - } - - String *base = NewString(""); - - /* Dump out variable wrappers */ - - Printv(magic, "\n#ifdef __cplusplus\n}\n#endif\n", NIL); - - Printf(f_header, "%s\n", magic); - - String *type_table = NewString(""); - - /* Patch the type table to reflect the names used by shadow classes */ - if (blessed) { - Iterator cls; - for (cls = First(classlist); cls.item; cls = Next(cls)) { - String *pname = Getattr(cls.item, "perl5:proxy"); - if (pname) { - SwigType *type = Getattr(cls.item, "classtypeobj"); - if (!type) - continue; /* If unnamed class, no type will be found */ - type = Copy(type); - - SwigType_add_pointer(type); - String *mangled = SwigType_manglestr(type); - SwigType_remember_mangleddata(mangled, NewStringf("\"%s\"", pname)); - Delete(type); - Delete(mangled); - } - } - } - SwigType_emit_type_table(f_runtime, type_table); - - Printf(f_wrappers, "%s", type_table); - Delete(type_table); - - Printf(constant_tab, "{0,0,0,0,0,0}\n};\n"); - Printv(f_wrappers, constant_tab, NIL); - - Printf(f_wrappers, "#ifdef __cplusplus\n}\n#endif\n"); - - Printf(f_init, "\t ST(0) = &PL_sv_yes;\n"); - Printf(f_init, "\t XSRETURN(1);\n"); - Printf(f_init, "}\n"); - - /* Finish off tables */ - Printf(variable_tab, "{0,0,0,0}\n};\n"); - Printv(f_wrappers, variable_tab, NIL); - - Printf(command_tab, "{0,0}\n};\n"); - Printv(f_wrappers, command_tab, NIL); - - - Printf(f_pm, "package %s;\n", cmodule); - - if (!staticoption) { - Printf(f_pm,"bootstrap %s;\n", module); - } else { - Printf(f_pm,"package %s;\n", cmodule); - Printf(f_pm,"boot_%s();\n", underscore_module); - } - - Printf(f_pm, "package %s;\n", module); - /* - * If the package option has been given we are placing our - * symbols into some other packages namespace, so we do not - * mess with @EXPORT - */ - if (!dest_package) { - Printf(f_pm,"@EXPORT = qw(%s);\n", exported); - } - - Printf(f_pm, "%s", pragma_include); - - if (blessed) { - - /* - * These methods will be duplicated if package - * has been specified, so we do not output them - */ - if (!dest_package) { - Printv(base, "\n# ---------- BASE METHODS -------------\n\n", "package ", namespace_module, ";\n\n", NIL); - - /* Write out the TIE method */ - - Printv(base, "sub TIEHASH {\n", tab4, "my ($classname,$obj) = @_;\n", tab4, "return bless $obj, $classname;\n", "}\n\n", NIL); - - /* Output a CLEAR method. This is just a place-holder, but by providing it we - * can make declarations such as - * %$u = ( x => 2, y=>3, z =>4 ); - * - * Where x,y,z are the members of some C/C++ object. */ - - Printf(base, "sub CLEAR { }\n\n"); - - /* Output default firstkey/nextkey methods */ - - Printf(base, "sub FIRSTKEY { }\n\n"); - Printf(base, "sub NEXTKEY { }\n\n"); - - /* Output a FETCH method. This is actually common to all classes */ - Printv(base, - "sub FETCH {\n", - tab4, "my ($self,$field) = @_;\n", tab4, "my $member_func = \"swig_${field}_get\";\n", tab4, "$self->$member_func();\n", "}\n\n", NIL); - - /* Output a STORE method. This is also common to all classes (might move to base class) */ - - Printv(base, - "sub STORE {\n", - tab4, "my ($self,$field,$newval) = @_;\n", - tab4, "my $member_func = \"swig_${field}_set\";\n", tab4, "$self->$member_func($newval);\n", "}\n\n", NIL); - - /* Output a 'this' method */ - - Printv(base, "sub this {\n", tab4, "my $ptr = shift;\n", tab4, "return tied(%$ptr);\n", "}\n\n", NIL); - - Printf(f_pm, "%s", base); - } - - /* Emit function stubs for stand-alone functions */ - Printf(f_pm, "\n# ------- FUNCTION WRAPPERS --------\n\n"); - Printf(f_pm, "package %s;\n\n", namespace_module); - Printf(f_pm, "%s", func_stubs); - - /* Emit package code for different classes */ - Printf(f_pm, "%s", pm); - - if (num_consts > 0) { - /* Emit constant stubs */ - Printf(f_pm, "\n# ------- CONSTANT STUBS -------\n\n"); - Printf(f_pm, "package %s;\n\n", namespace_module); - Printf(f_pm, "%s", const_stubs); - } - - /* Emit variable stubs */ - - Printf(f_pm, "\n# ------- VARIABLE STUBS --------\n\n"); - Printf(f_pm, "package %s;\n\n", namespace_module); - Printf(f_pm, "%s", var_stubs); - } - - /* Add additional Perl code at the end */ - Printf(f_pm, "%s", additional_perl_code); - - Printf(f_pm, "1;\n"); - Delete(f_pm); - Delete(base); - Delete(dest_package); - Delete(underscore_module); - - /* Close all of the files */ - Dump(f_runtime, f_begin); - Dump(f_header, f_begin); - - if (directorsEnabled()) { - Dump(f_directors_h, f_runtime_h); - Printf(f_runtime_h, "\n"); - Printf(f_runtime_h, "#endif\n"); - Dump(f_directors, f_begin); - } - - Dump(f_wrappers, f_begin); - Wrapper_pretty_print(f_init, f_begin); - Delete(f_header); - Delete(f_wrappers); - Delete(f_init); - Delete(f_directors); - Delete(f_directors_h); - Delete(f_runtime); - Delete(f_begin); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * importDirective(Node *n) - * ------------------------------------------------------------ */ - - virtual int importDirective(Node *n) { - if (blessed) { - String *modname = Getattr(n, "module"); - if (modname) { - Printf(f_pm, "require %s;\n", modname); - } - } - return Language::importDirective(n); - } - - /* ------------------------------------------------------------ - * functionWrapper() - * ------------------------------------------------------------ */ - - virtual int functionWrapper(Node *n) { - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - SwigType *d = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - String *overname = 0; - int director_method = 0; - - Parm *p; - int i; - Wrapper *f; - char source[256], temp[256]; - String *tm; - String *cleanup, *outarg; - int num_saved = 0; - int num_arguments, num_required; - int varargs = 0; - - if (Getattr(n, "sym:overloaded")) { - overname = Getattr(n, "sym:overname"); - } else { - if (!addSymbol(iname, n)) - return SWIG_ERROR; - } - - f = NewWrapper(); - cleanup = NewString(""); - outarg = NewString(""); - - String *wname = Swig_name_wrapper(iname); - if (overname) { - Append(wname, overname); - } - Setattr(n, "wrap:name", wname); - Printv(f->def, "XS(", wname, ") {\n", "{\n", /* scope to destroy C++ objects before croaking */ - NIL); - - emit_parameter_variables(l, f); - emit_attach_parmmaps(l, f); - Setattr(n, "wrap:parms", l); - - num_arguments = emit_num_arguments(l); - num_required = emit_num_required(l); - varargs = emit_isvarargs(l); - - Wrapper_add_local(f, "argvi", "int argvi = 0"); - - /* Check the number of arguments */ - if (!varargs) { - Printf(f->code, " if ((items < %d) || (items > %d)) {\n", num_required, num_arguments); - } else { - Printf(f->code, " if (items < %d) {\n", num_required); - } - Printf(f->code, " SWIG_croak(\"Usage: %s\");\n", usage_func(Char(iname), d, l)); - Printf(f->code, "}\n"); - - /* Write code to extract parameters. */ - for (i = 0, p = l; i < num_arguments; i++) { - - /* Skip ignored arguments */ - - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - - /* Produce string representation of source and target arguments */ - sprintf(source, "ST(%d)", i); - - if (i >= num_required) { - Printf(f->code, " if (items > %d) {\n", i); - } - if ((tm = Getattr(p, "tmap:in"))) { - Replaceall(tm, "$input", source); - Setattr(p, "emit:input", source); /* Save input location */ - - if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - - Printf(f->code, "%s\n", tm); - p = Getattr(p, "tmap:in:next"); - } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); - p = nextSibling(p); - } - if (i >= num_required) { - Printf(f->code, " }\n"); - } - } - - if (varargs) { - if (p && (tm = Getattr(p, "tmap:in"))) { - sprintf(source, "ST(%d)", i); - Replaceall(tm, "$input", source); - Setattr(p, "emit:input", source); - Printf(f->code, "if (items >= %d) {\n", i); - Printv(f->code, tm, "\n", NIL); - Printf(f->code, "}\n"); - } - } - - /* Insert constraint checking code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert cleanup code */ - for (i = 0, p = l; p; i++) { - if ((tm = Getattr(p, "tmap:freearg"))) { - Replaceall(tm, "$arg", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(cleanup, tm, "\n", NIL); - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert argument output code */ - num_saved = 0; - for (i = 0, p = l; p; i++) { - if ((tm = Getattr(p, "tmap:argout"))) { - SwigType *t = Getattr(p, "type"); - Replaceall(tm, "$result", "ST(argvi)"); - if (is_shadow(t)) { - Replaceall(tm, "$shadow", "SWIG_SHADOW"); - } else { - Replaceall(tm, "$shadow", "0"); - } - - String *in = Getattr(p, "emit:input"); - if (in) { - sprintf(temp, "_saved[%d]", num_saved); - Replaceall(tm, "$arg", temp); - Replaceall(tm, "$input", temp); - Printf(f->code, "_saved[%d] = %s;\n", num_saved, in); - num_saved++; - } - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - /* If there were any saved arguments, emit a local variable for them */ - if (num_saved) { - sprintf(temp, "_saved[%d]", num_saved); - Wrapper_add_localv(f, "_saved", "SV *", temp, NIL); - } - - director_method = is_member_director(n) && !is_smart_pointer() && 0 != Cmp(nodeType(n), "destructor"); - if (director_method) { - Wrapper_add_local(f, "director", "Swig::Director *director = 0"); - Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n"); - if (dirprot_mode() && !is_public(n)) { - Printf(f->code, "if (!director || !(director->swig_get_inner(\"%s\"))) {\n", name); - Printf(f->code, "SWIG_exception_fail(SWIG_RuntimeError, \"accessing protected member %s\");\n", name); - Append(f->code, "}\n"); - } - Wrapper_add_local(f, "upcall", "bool upcall = false"); - Printf(f->code, "upcall = director && SvSTASH(SvRV(ST(0))) == gv_stashpv(director->swig_get_class(), 0);\n"); - } - - /* Emit the function call */ - if (director_method) { - Append(f->code, "try {\n"); - } - - /* Now write code to make the function call */ - - Swig_director_emit_dynamic_cast(n, f); - String *actioncode = emit_action(n); - - if (director_method) { - Append(actioncode, "} catch (Swig::DirectorException& swig_err) {\n"); - Append(actioncode, " sv_setsv(ERRSV, swig_err.getNative());\n"); - Append(actioncode, " SWIG_fail;\n"); - Append(actioncode, "}\n"); - } - - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { - SwigType *t = Getattr(n, "type"); - Replaceall(tm, "$result", "ST(argvi)"); - if (is_shadow(t)) { - Replaceall(tm, "$shadow", "SWIG_SHADOW"); - } else { - Replaceall(tm, "$shadow", "0"); - } - if (GetFlag(n, "feature:new")) { - Replaceall(tm, "$owner", "SWIG_OWNER"); - } else { - Replaceall(tm, "$owner", "0"); - } - Printf(f->code, "%s\n", tm); - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name); - } - emit_return_variable(n, d, f); - - /* If there were any output args, take care of them. */ - - Printv(f->code, outarg, NIL); - - /* If there was any cleanup, do that. */ - - Printv(f->code, cleanup, NIL); - - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - } - } - - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - } - - if (director_method) { - if ((tm = Swig_typemap_lookup("directorfree", n, Swig_cresult_name(), 0))) { - Replaceall(tm, "$input", Swig_cresult_name()); - Replaceall(tm, "$result", "ST(argvi)"); - Printf(f->code, "%s\n", tm); - Delete(tm); - } - } - - Printv(f->code, "XSRETURN(argvi);\n", "fail:\n", cleanup, "SWIG_croak_null();\n" "}\n" "}\n", NIL); - - /* Add the dXSARGS last */ - - Wrapper_add_local(f, "dXSARGS", "dXSARGS"); - - /* Substitute the cleanup code */ - Replaceall(f->code, "$cleanup", cleanup); - Replaceall(f->code, "$symname", iname); - - /* Dump the wrapper function */ - - Wrapper_print(f, f_wrappers); - - /* Now register the function */ - - if (!Getattr(n, "sym:overloaded")) { - Printf(command_tab, "{\"%s::%s\", %s},\n", cmodule, iname, wname); - } else if (!Getattr(n, "sym:nextSibling")) { - /* Generate overloaded dispatch function */ - int maxargs; - String *dispatch = Swig_overload_dispatch_cast(n, "PUSHMARK(MARK); SWIG_CALLXS(%s); return;", &maxargs); - - /* Generate a dispatch wrapper for all overloaded functions */ - - Wrapper *df = NewWrapper(); - String *dname = Swig_name_wrapper(iname); - - Printv(df->def, "XS(", dname, ") {\n", NIL); - - Wrapper_add_local(df, "dXSARGS", "dXSARGS"); - Printv(df->code, dispatch, "\n", NIL); - Printf(df->code, "croak(\"No matching function for overloaded '%s'\");\n", iname); - Printf(df->code, "XSRETURN(0);\n"); - Printv(df->code, "}\n", NIL); - Wrapper_print(df, f_wrappers); - Printf(command_tab, "{\"%s::%s\", %s},\n", cmodule, iname, dname); - DelWrapper(df); - Delete(dispatch); - Delete(dname); - } - if (!Getattr(n, "sym:nextSibling")) { - if (export_all) { - Printf(exported, "%s ", iname); - } - - /* -------------------------------------------------------------------- - * Create a stub for this function, provided it's not a member function - * -------------------------------------------------------------------- */ - - if ((blessed) && (!member_func)) { - Printv(func_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL); - } - - } - Delete(cleanup); - Delete(outarg); - DelWrapper(f); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * variableWrapper() - * ------------------------------------------------------------ */ - virtual int variableWrapper(Node *n) { - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - Wrapper *getf, *setf; - String *tm; - String *getname = Swig_name_get(NSPACE_TODO, iname); - String *setname = Swig_name_set(NSPACE_TODO, iname); - - String *get_name = Swig_name_wrapper(getname); - String *set_name = Swig_name_wrapper(setname); - - if (!addSymbol(iname, n)) - return SWIG_ERROR; - - getf = NewWrapper(); - setf = NewWrapper(); - - /* Create a Perl function for setting the variable value */ - - if (!GetFlag(n, "feature:immutable")) { - Setattr(n, "wrap:name", set_name); - Printf(setf->def, "SWIGCLASS_STATIC int %s(pTHX_ SV* sv, MAGIC * SWIGUNUSEDPARM(mg)) {\n", set_name); - Printv(setf->code, tab4, "MAGIC_PPERL\n", NIL); - - /* Check for a few typemaps */ - tm = Swig_typemap_lookup("varin", n, name, 0); - if (tm) { - Replaceall(tm, "$input", "sv"); - /* Printf(setf->code,"%s\n", tm); */ - emit_action_code(n, setf->code, tm); - } else { - Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0)); - DelWrapper(setf); - DelWrapper(getf); - return SWIG_NOWRAP; - } - Printf(setf->code, "fail:\n"); - Printf(setf->code, " return 1;\n}\n"); - Replaceall(setf->code, "$symname", iname); - Wrapper_print(setf, magic); - } - - /* Now write a function to evaluate the variable */ - Setattr(n, "wrap:name", get_name); - int addfail = 0; - Printf(getf->def, "SWIGCLASS_STATIC int %s(pTHX_ SV *sv, MAGIC *SWIGUNUSEDPARM(mg)) {\n", get_name); - Printv(getf->code, tab4, "MAGIC_PPERL\n", NIL); - - if ((tm = Swig_typemap_lookup("varout", n, name, 0))) { - Replaceall(tm, "$result", "sv"); - if (is_shadow(t)) { - Replaceall(tm, "$shadow", "SWIG_SHADOW"); - } else { - Replaceall(tm, "$shadow", "0"); - } - /* Printf(getf->code,"%s\n", tm); */ - addfail = emit_action_code(n, getf->code, tm); - } else { - Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0)); - DelWrapper(setf); - DelWrapper(getf); - return SWIG_NOWRAP; - } - Printf(getf->code, " return 1;\n"); - if (addfail) { - Append(getf->code, "fail:\n"); - Append(getf->code, " return 0;\n"); - } - Append(getf->code, "}\n"); - - - Replaceall(getf->code, "$symname", iname); - Wrapper_print(getf, magic); - - String *tt = Getattr(n, "tmap:varout:type"); - if (tt) { - tt = NewStringf("&%s", tt); - } else { - tt = NewString("0"); - } - /* Now add symbol to the PERL interpreter */ - if (GetFlag(n, "feature:immutable")) { - Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS swig_magic_readonly, MAGIC_CLASS ", get_name, ",", tt, " },\n", NIL); - - } else { - Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS ", set_name, ", MAGIC_CLASS ", get_name, ",", tt, " },\n", NIL); - } - - /* If we're blessed, try to figure out what to do with the variable - 1. If it's a Perl object of some sort, create a tied-hash - around it. - 2. Otherwise, just hack Perl's symbol table */ - - if (blessed) { - if (is_shadow(t)) { - Printv(var_stubs, - "\nmy %__", iname, "_hash;\n", - "tie %__", iname, "_hash,\"", is_shadow(t), "\", $", - cmodule, "::", iname, ";\n", "$", iname, "= \\%__", iname, "_hash;\n", "bless $", iname, ", ", is_shadow(t), ";\n", NIL); - } else { - Printv(var_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL); - } - } - if (export_all) - Printf(exported, "$%s ", iname); - - Delete(tt); - DelWrapper(setf); - DelWrapper(getf); - Delete(getname); - Delete(setname); - Delete(set_name); - Delete(get_name); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constantWrapper() - * ------------------------------------------------------------ */ - - virtual int constantWrapper(Node *n) { - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - String *rawval = Getattr(n, "rawval"); - String *value = rawval ? rawval : Getattr(n, "value"); - String *tm; - - if (!addSymbol(iname, n)) - return SWIG_ERROR; - - /* Special hook for member pointer */ - if (SwigType_type(type) == T_MPOINTER) { - String *wname = Swig_name_wrapper(iname); - Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type, wname), value); - value = Char(wname); - } - - if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) { - Replaceall(tm, "$value", value); - if (is_shadow(type)) { - Replaceall(tm, "$shadow", "SWIG_SHADOW"); - } else { - Replaceall(tm, "$shadow", "0"); - } - Printf(constant_tab, "%s,\n", tm); - } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) { - Replaceall(tm, "$value", value); - if (is_shadow(type)) { - Replaceall(tm, "$shadow", "SWIG_SHADOW"); - } else { - Replaceall(tm, "$shadow", "0"); - } - Printf(f_init, "%s\n", tm); - } else { - Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); - return SWIG_NOWRAP; - } - - if (blessed) { - if (is_shadow(type)) { - Printv(var_stubs, - "\nmy %__", iname, "_hash;\n", - "tie %__", iname, "_hash,\"", is_shadow(type), "\", $", - cmodule, "::", iname, ";\n", "$", iname, "= \\%__", iname, "_hash;\n", "bless $", iname, ", ", is_shadow(type), ";\n", NIL); - } else if (do_constants) { - Printv(const_stubs, "sub ", name, " () { $", cmodule, "::", name, " }\n", NIL); - num_consts++; - } else { - Printv(var_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL); - } - } - if (export_all) { - if (do_constants && !is_shadow(type)) { - Printf(exported, "%s ", name); - } else { - Printf(exported, "$%s ", iname); - } - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * usage_func() - * ------------------------------------------------------------ */ - char *usage_func(char *iname, SwigType *, ParmList *l) { - static String *temp = 0; - Parm *p; - int i; - - if (!temp) - temp = NewString(""); - Clear(temp); - Printf(temp, "%s(", iname); - - /* Now go through and print parameters */ - p = l; - i = 0; - while (p != 0) { - SwigType *pt = Getattr(p, "type"); - String *pn = Getattr(p, "name"); - if (!checkAttribute(p,"tmap:in:numinputs","0")) { - /* If parameter has been named, use that. Otherwise, just print a type */ - if (SwigType_type(pt) != T_VOID) { - if (Len(pn) > 0) { - Printf(temp, "%s", pn); - } else { - Printf(temp, "%s", SwigType_str(pt, 0)); - } - } - i++; - p = nextSibling(p); - if (p) - if (!checkAttribute(p,"tmap:in:numinputs","0")) - Putc(',', temp); - } else { - p = nextSibling(p); - if (p) - if ((i > 0) && (!checkAttribute(p,"tmap:in:numinputs","0"))) - Putc(',', temp); - } - } - Printf(temp, ");"); - return Char(temp); - } - - /* ------------------------------------------------------------ - * nativeWrapper() - * ------------------------------------------------------------ */ - - virtual int nativeWrapper(Node *n) { - String *name = Getattr(n, "sym:name"); - String *funcname = Getattr(n, "wrap:name"); - - if (!addSymbol(funcname, n)) - return SWIG_ERROR; - - Printf(command_tab, "{\"%s::%s\", %s},\n", cmodule, name, funcname); - if (export_all) - Printf(exported, "%s ", name); - if (blessed) { - Printv(func_stubs, "*", name, " = *", cmodule, "::", name, ";\n", NIL); - } - return SWIG_OK; - } - -/* ---------------------------------------------------------------------------- - * OBJECT-ORIENTED FEATURES - * - * These extensions provide a more object-oriented interface to C++ - * classes and structures. The code here is based on extensions - * provided by David Fletcher and Gary Holt. - * - * I have generalized these extensions to make them more general purpose - * and to resolve object-ownership problems. - * - * The approach here is very similar to the Python module : - * 1. All of the original methods are placed into a single - * package like before except that a 'c' is appended to the - * package name. - * - * 2. All methods and function calls are wrapped with a new - * perl function. While possibly inefficient this allows - * us to catch complex function arguments (which are hard to - * track otherwise). - * - * 3. Classes are represented as tied-hashes in a manner similar - * to Gary Holt's extension. This allows us to access - * member data. - * - * 4. Stand-alone (global) C functions are modified to take - * tied hashes as arguments for complex datatypes (if - * appropriate). - * - * 5. Global variables involving a class/struct is encapsulated - * in a tied hash. - * - * ------------------------------------------------------------------------- */ - - - void setclassname(Node *n) { - String *symname = Getattr(n, "sym:name"); - String *fullname; - String *actualpackage; - Node *clsmodule = Getattr(n, "module"); - - if (!clsmodule) { - /* imported module does not define a module name. Oh well */ - return; - } - - /* Do some work on the class name */ - if (verbose > 0) { - String *modulename = Getattr(clsmodule, "name"); - fprintf(stdout, "setclassname: Found sym:name: %s\n", Char(symname)); - fprintf(stdout, "setclassname: Found module: %s\n", Char(modulename)); - fprintf(stdout, "setclassname: No package found\n"); - } - - if (dest_package) { - fullname = NewStringf("%s::%s", namespace_module, symname); - } else { - actualpackage = Getattr(clsmodule,"name"); - - if (verbose > 0) { - fprintf(stdout, "setclassname: Found actualpackage: %s\n", Char(actualpackage)); - } - if ((!compat) && (!Strchr(symname,':'))) { - fullname = NewStringf("%s::%s",actualpackage,symname); - } else { - fullname = NewString(symname); - } - } - if (verbose > 0) { - fprintf(stdout, "setclassname: setting proxy: %s\n", Char(fullname)); - } - Setattr(n, "perl5:proxy", fullname); - } - - /* ------------------------------------------------------------ - * classDeclaration() - * ------------------------------------------------------------ */ - virtual int classDeclaration(Node *n) { - /* Do some work on the class name */ - if (!Getattr(n, "feature:onlychildren")) { - if (blessed) { - setclassname(n); - Append(classlist, n); - } - } - - return Language::classDeclaration(n); - } - - /* ------------------------------------------------------------ - * classHandler() - * ------------------------------------------------------------ */ - - virtual int classHandler(Node *n) { - - if (blessed) { - have_constructor = 0; - have_operators = 0; - have_destructor = 0; - have_data_members = 0; - operators = NewHash(); - - class_name = Getattr(n, "sym:name"); - - if (!addSymbol(class_name, n)) - return SWIG_ERROR; - - /* Use the fully qualified name of the Perl class */ - if (!compat) { - fullclassname = NewStringf("%s::%s", namespace_module, class_name); - } else { - fullclassname = NewString(class_name); - } - real_classname = Getattr(n, "name"); - pcode = NewString(""); - // blessedmembers = NewString(""); - } - - /* Emit all of the members */ - Language::classHandler(n); - - - /* Finish the rest of the class */ - if (blessed) { - /* Generate a client-data entry */ - SwigType *ct = NewStringf("p.%s", real_classname); - Printv(f_init, "SWIG_TypeClientData(SWIGTYPE", SwigType_manglestr(ct), ", (void*) \"", fullclassname, "\");\n", NIL); - SwigType_remember(ct); - Delete(ct); - - Printv(pm, "\n############# Class : ", fullclassname, " ##############\n", "\npackage ", fullclassname, ";\n", NIL); - - if (have_operators) { - Printf(pm, "use overload\n"); - Iterator ki; - for (ki = First(operators); ki.key; ki = Next(ki)) { - char *name = Char(ki.key); - // fprintf(stderr,"found name: <%s>\n", name); - if (strstr(name, "__eq__")) { - Printv(pm, tab4, "\"==\" => sub { $_[0]->__eq__($_[1])},\n",NIL); - } else if (strstr(name, "__ne__")) { - Printv(pm, tab4, "\"!=\" => sub { $_[0]->__ne__($_[1])},\n",NIL); - // there are no tests for this in operator_overload_runme.pl - // it is likely to be broken - // } else if (strstr(name, "__assign__")) { - // Printv(pm, tab4, "\"=\" => sub { $_[0]->__assign__($_[1])},\n",NIL); - } else if (strstr(name, "__str__")) { - Printv(pm, tab4, "'\"\"' => sub { $_[0]->__str__()},\n",NIL); - } else if (strstr(name, "__plusplus__")) { - Printv(pm, tab4, "\"++\" => sub { $_[0]->__plusplus__()},\n",NIL); - } else if (strstr(name, "__minmin__")) { - Printv(pm, tab4, "\"--\" => sub { $_[0]->__minmin__()},\n",NIL); - } else if (strstr(name, "__add__")) { - Printv(pm, tab4, "\"+\" => sub { $_[0]->__add__($_[1])},\n",NIL); - } else if (strstr(name, "__sub__")) { - Printv(pm, tab4, "\"-\" => sub { if( not $_[2] ) { $_[0]->__sub__($_[1]) }\n",NIL); - Printv(pm, tab8, "elsif( $_[0]->can('__rsub__') ) { $_[0]->__rsub__($_[1]) }\n",NIL); - Printv(pm, tab8, "else { die(\"reverse subtraction not supported\") }\n",NIL); - Printv(pm, tab8, "},\n",NIL); - } else if (strstr(name, "__mul__")) { - Printv(pm, tab4, "\"*\" => sub { $_[0]->__mul__($_[1])},\n",NIL); - } else if (strstr(name, "__div__")) { - Printv(pm, tab4, "\"/\" => sub { $_[0]->__div__($_[1])},\n",NIL); - } else if (strstr(name, "__mod__")) { - Printv(pm, tab4, "\"%\" => sub { $_[0]->__mod__($_[1])},\n",NIL); - // there are no tests for this in operator_overload_runme.pl - // it is likely to be broken - // } else if (strstr(name, "__and__")) { - // Printv(pm, tab4, "\"&\" => sub { $_[0]->__and__($_[1])},\n",NIL); - - // there are no tests for this in operator_overload_runme.pl - // it is likely to be broken - // } else if (strstr(name, "__or__")) { - // Printv(pm, tab4, "\"|\" => sub { $_[0]->__or__($_[1])},\n",NIL); - } else if (strstr(name, "__gt__")) { - Printv(pm, tab4, "\">\" => sub { $_[0]->__gt__($_[1])},\n",NIL); - } else if (strstr(name, "__ge__")) { - Printv(pm, tab4, "\">=\" => sub { $_[0]->__ge__($_[1])},\n",NIL); - } else if (strstr(name, "__not__")) { - Printv(pm, tab4, "\"!\" => sub { $_[0]->__not__()},\n",NIL); - } else if (strstr(name, "__lt__")) { - Printv(pm, tab4, "\"<\" => sub { $_[0]->__lt__($_[1])},\n",NIL); - } else if (strstr(name, "__le__")) { - Printv(pm, tab4, "\"<=\" => sub { $_[0]->__le__($_[1])},\n",NIL); - } else if (strstr(name, "__pluseq__")) { - Printv(pm, tab4, "\"+=\" => sub { $_[0]->__pluseq__($_[1])},\n",NIL); - } else if (strstr(name, "__mineq__")) { - Printv(pm, tab4, "\"-=\" => sub { $_[0]->__mineq__($_[1])},\n",NIL); - } else if (strstr(name, "__neg__")) { - Printv(pm, tab4, "\"neg\" => sub { $_[0]->__neg__()},\n",NIL); - } else { - fprintf(stderr,"Unknown operator: %s\n", name); - } - } - Printv(pm, tab4, - "\"=\" => sub { my $class = ref($_[0]); $class->new($_[0]) },\n", NIL); - Printv(pm, tab4, "\"fallback\" => 1;\n", NIL); - } - // make use strict happy - Printv(pm, "use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);\n", NIL); - - /* If we are inheriting from a base class, set that up */ - - Printv(pm, "@ISA = qw(", NIL); - - /* Handle inheritance */ - List *baselist = Getattr(n, "bases"); - if (baselist && Len(baselist)) { - Iterator b; - b = First(baselist); - while (b.item) { - String *bname = Getattr(b.item, "perl5:proxy"); - if (!bname) { - b = Next(b); - continue; - } - Printv(pm, " ", bname, NIL); - b = Next(b); - } - } - - /* Module comes last */ - if (!compat || Cmp(namespace_module, fullclassname)) { - Printv(pm, " ", namespace_module, NIL); - } - - Printf(pm, " );\n"); - - /* Dump out a hash table containing the pointers that we own */ - Printf(pm, "%%OWNER = ();\n"); - if (have_data_members || have_destructor) - Printf(pm, "%%ITERATORS = ();\n"); - - /* Dump out the package methods */ - - Printv(pm, pcode, NIL); - Delete(pcode); - - /* Output methods for managing ownership */ - - String *director_disown; - if (Getattr(n, "perl5:directordisown")) { - director_disown = NewStringf("%s%s($self);\n", tab4, Getattr(n, "perl5:directordisown")); - } else { - director_disown = NewString(""); - } - Printv(pm, - "sub DISOWN {\n", - tab4, "my $self = shift;\n", - director_disown, - tab4, "my $ptr = tied(%$self);\n", - tab4, "delete $OWNER{$ptr};\n", - "}\n\n", "sub ACQUIRE {\n", tab4, "my $self = shift;\n", tab4, "my $ptr = tied(%$self);\n", tab4, "$OWNER{$ptr} = 1;\n", "}\n\n", NIL); - Delete(director_disown); - - /* Only output the following methods if a class has member data */ - - Delete(operators); - operators = 0; - if (Swig_directorclass(n)) { - /* director classes need a way to recover subclass instance attributes */ - Node *get_attr = NewHash(); - String *mrename; - String *symname = Getattr(n, "sym:name"); - mrename = Swig_name_disown(NSPACE_TODO, symname); - Replaceall(mrename, "disown", "swig_get_attr"); - String *type = NewString(getClassType()); - String *name = NewString("self"); - SwigType_add_pointer(type); - Parm *p = NewParm(type, name, n); - Delete(name); - Delete(type); - type = NewString("SV"); - SwigType_add_pointer(type); - String *action = NewString(""); - Printv(action, "{\n", " Swig::Director *director = SWIG_DIRECTOR_CAST(arg1);\n", - " result = sv_newmortal();\n" " if (director) sv_setsv(result, director->swig_get_self());\n", "}\n", NIL); - Setfile(get_attr, Getfile(n)); - Setline(get_attr, Getline(n)); - Setattr(get_attr, "wrap:action", action); - Setattr(get_attr, "name", mrename); - Setattr(get_attr, "sym:name", mrename); - Setattr(get_attr, "type", type); - Setattr(get_attr, "parms", p); - Delete(action); - Delete(type); - Delete(p); - - member_func = 1; - functionWrapper(get_attr); - member_func = 0; - Delete(get_attr); - - Printv(pm, "sub FETCH {\n", tab4, "my ($self,$field) = @_;\n", tab4, "my $member_func = \"swig_${field}_get\";\n", tab4, - "if (not $self->can($member_func)) {\n", tab8, "my $h = ", cmodule, "::", mrename, "($self);\n", tab8, "return $h->{$field} if $h;\n", - tab4, "}\n", tab4, "return $self->$member_func;\n", "}\n", "\n", "sub STORE {\n", tab4, "my ($self,$field,$newval) = @_;\n", tab4, - "my $member_func = \"swig_${field}_set\";\n", tab4, "if (not $self->can($member_func)) {\n", tab8, "my $h = ", cmodule, "::", mrename, - "($self);\n", tab8, "return $h->{$field} = $newval if $h;\n", tab4, "}\n", tab4, "return $self->$member_func($newval);\n", "}\n", NIL); - - Delete(mrename); - } - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * memberfunctionHandler() - * ------------------------------------------------------------ */ - - virtual int memberfunctionHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - - member_func = 1; - Language::memberfunctionHandler(n); - member_func = 0; - - if ((blessed) && (!Getattr(n, "sym:nextSibling"))) { - - if (Strstr(symname, "__eq__")) { - DohSetInt(operators, "__eq__", 1); - have_operators = 1; - } else if (Strstr(symname, "__ne__")) { - DohSetInt(operators, "__ne__", 1); - have_operators = 1; - } else if (Strstr(symname, "__assign__")) { - DohSetInt(operators, "__assign__", 1); - have_operators = 1; - } else if (Strstr(symname, "__str__")) { - DohSetInt(operators, "__str__", 1); - have_operators = 1; - } else if (Strstr(symname, "__add__")) { - DohSetInt(operators, "__add__", 1); - have_operators = 1; - } else if (Strstr(symname, "__sub__")) { - DohSetInt(operators, "__sub__", 1); - have_operators = 1; - } else if (Strstr(symname, "__mul__")) { - DohSetInt(operators, "__mul__", 1); - have_operators = 1; - } else if (Strstr(symname, "__div__")) { - DohSetInt(operators, "__div__", 1); - have_operators = 1; - } else if (Strstr(symname, "__mod__")) { - DohSetInt(operators, "__mod__", 1); - have_operators = 1; - } else if (Strstr(symname, "__and__")) { - DohSetInt(operators, "__and__", 1); - have_operators = 1; - } else if (Strstr(symname, "__or__")) { - DohSetInt(operators, "__or__", 1); - have_operators = 1; - } else if (Strstr(symname, "__not__")) { - DohSetInt(operators, "__not__", 1); - have_operators = 1; - } else if (Strstr(symname, "__gt__")) { - DohSetInt(operators, "__gt__", 1); - have_operators = 1; - } else if (Strstr(symname, "__ge__")) { - DohSetInt(operators, "__ge__", 1); - have_operators = 1; - } else if (Strstr(symname, "__lt__")) { - DohSetInt(operators, "__lt__", 1); - have_operators = 1; - } else if (Strstr(symname, "__le__")) { - DohSetInt(operators, "__le__", 1); - have_operators = 1; - } else if (Strstr(symname, "__neg__")) { - DohSetInt(operators, "__neg__", 1); - have_operators = 1; - } else if (Strstr(symname, "__plusplus__")) { - DohSetInt(operators, "__plusplus__", 1); - have_operators = 1; - } else if (Strstr(symname, "__minmin__")) { - DohSetInt(operators, "__minmin__", 1); - have_operators = 1; - } else if (Strstr(symname, "__mineq__")) { - DohSetInt(operators, "__mineq__", 1); - have_operators = 1; - } else if (Strstr(symname, "__pluseq__")) { - DohSetInt(operators, "__pluseq__", 1); - have_operators = 1; - } - - if (Getattr(n, "feature:shadow")) { - String *plcode = perlcode(Getattr(n, "feature:shadow"), 0); - String *plaction = NewStringf("%s::%s", cmodule, Swig_name_member(NSPACE_TODO, class_name, symname)); - Replaceall(plcode, "$action", plaction); - Delete(plaction); - Printv(pcode, plcode, NIL); - } else { - Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL); - } - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * membervariableHandler() - * - * Adds an instance member. - * ----------------------------------------------------------------------------- */ - - virtual int membervariableHandler(Node *n) { - - String *symname = Getattr(n, "sym:name"); - /* SwigType *t = Getattr(n,"type"); */ - - /* Emit a pair of get/set functions for the variable */ - - member_func = 1; - Language::membervariableHandler(n); - member_func = 0; - - if (blessed) { - - Printv(pcode, "*swig_", symname, "_get = *", cmodule, "::", Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)), ";\n", NIL); - Printv(pcode, "*swig_", symname, "_set = *", cmodule, "::", Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname)), ";\n", NIL); - - /* Now we need to generate a little Perl code for this */ - - /* if (is_shadow(t)) { - - *//* This is a Perl object that we have already seen. Add an - entry to the members list *//* - Printv(blessedmembers, - tab4, symname, " => '", is_shadow(t), "',\n", - NIL); - - } - */ - } - have_data_members++; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constructorDeclaration() - * - * Emits a blessed constructor for our class. In addition to our construct - * we manage a Perl hash table containing all of the pointers created by - * the constructor. This prevents us from accidentally trying to free - * something that wasn't necessarily allocated by malloc or new - * ------------------------------------------------------------ */ - - virtual int constructorHandler(Node *n) { - - String *symname = Getattr(n, "sym:name"); - - member_func = 1; - - Swig_save("perl5:constructorHandler", n, "parms", NIL); - if (Swig_directorclass(n)) { - Parm *parms = Getattr(n, "parms"); - Parm *self; - String *name = NewString("self"); - String *type = NewString("SV"); - SwigType_add_pointer(type); - self = NewParm(type, name, n); - Delete(type); - Delete(name); - Setattr(self, "lname", "O"); - if (parms) - set_nextSibling(self, parms); - Setattr(n, "parms", self); - Setattr(n, "wrap:self", "1"); - Setattr(n, "hidden", "1"); - Delete(self); - } - - String *saved_nc = none_comparison; - none_comparison = NewStringf("strcmp(SvPV_nolen(ST(0)), \"%s::%s\") != 0", module, class_name); - String *saved_director_prot_ctor_code = director_prot_ctor_code; - director_prot_ctor_code = NewStringf("if ($comparison) { /* subclassed */\n" " $director_new\n" "} else {\n" - "SWIG_exception_fail(SWIG_RuntimeError, \"accessing abstract class or protected constructor\");\n" "}\n"); - Language::constructorHandler(n); - Delete(none_comparison); - none_comparison = saved_nc; - Delete(director_prot_ctor_code); - director_prot_ctor_code = saved_director_prot_ctor_code; - Swig_restore(n); - - if ((blessed) && (!Getattr(n, "sym:nextSibling"))) { - if (Getattr(n, "feature:shadow")) { - String *plcode = perlcode(Getattr(n, "feature:shadow"), 0); - String *plaction = NewStringf("%s::%s", module, Swig_name_member(NSPACE_TODO, class_name, symname)); - Replaceall(plcode, "$action", plaction); - Delete(plaction); - Printv(pcode, plcode, NIL); - } else { - if ((Cmp(symname, class_name) == 0)) { - /* Emit a blessed constructor */ - Printf(pcode, "sub new {\n"); - } else { - /* Constructor doesn't match classname so we'll just use the normal name */ - Printv(pcode, "sub ", Swig_name_construct(NSPACE_TODO, symname), " {\n", NIL); - } - - const char *pkg = getCurrentClass() && Swig_directorclass(getCurrentClass())? "$_[0]" : "shift"; - Printv(pcode, - tab4, "my $pkg = ", pkg, ";\n", - tab4, "my $self = ", cmodule, "::", Swig_name_construct(NSPACE_TODO, symname), "(@_);\n", tab4, "bless $self, $pkg if defined($self);\n", "}\n\n", NIL); - - have_constructor = 1; - } - } - member_func = 0; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * destructorHandler() - * ------------------------------------------------------------ */ - - virtual int destructorHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - member_func = 1; - Language::destructorHandler(n); - if (blessed) { - if (Getattr(n, "feature:shadow")) { - String *plcode = perlcode(Getattr(n, "feature:shadow"), 0); - String *plaction = NewStringf("%s::%s", module, Swig_name_member(NSPACE_TODO, class_name, symname)); - Replaceall(plcode, "$action", plaction); - Delete(plaction); - Printv(pcode, plcode, NIL); - } else { - Printv(pcode, - "sub DESTROY {\n", - tab4, "return unless $_[0]->isa('HASH');\n", - tab4, "my $self = tied(%{$_[0]});\n", - tab4, "return unless defined $self;\n", - tab4, "delete $ITERATORS{$self};\n", - tab4, "if (exists $OWNER{$self}) {\n", - tab8, cmodule, "::", Swig_name_destroy(NSPACE_TODO, symname), "($self);\n", tab8, "delete $OWNER{$self};\n", tab4, "}\n}\n\n", NIL); - have_destructor = 1; - } - } - member_func = 0; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * staticmemberfunctionHandler() - * ------------------------------------------------------------ */ - - virtual int staticmemberfunctionHandler(Node *n) { - member_func = 1; - Language::staticmemberfunctionHandler(n); - member_func = 0; - if ((blessed) && (!Getattr(n, "sym:nextSibling"))) { - String *symname = Getattr(n, "sym:name"); - Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL); - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * staticmembervariableHandler() - * ------------------------------------------------------------ */ - - virtual int staticmembervariableHandler(Node *n) { - Language::staticmembervariableHandler(n); - if (blessed) { - String *symname = Getattr(n, "sym:name"); - Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL); - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * memberconstantHandler() - * ------------------------------------------------------------ */ - - virtual int memberconstantHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - int oldblessed = blessed; - - /* Create a normal constant */ - blessed = 0; - Language::memberconstantHandler(n); - blessed = oldblessed; - - if (blessed) { - Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL); - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * pragma() - * - * Pragma directive. - * - * %pragma(perl5) code="String" # Includes a string in the .pm file - * %pragma(perl5) include="file.pl" # Includes a file in the .pm file - * ------------------------------------------------------------ */ - - virtual int pragmaDirective(Node *n) { - String *lang; - String *code; - String *value; - if (!ImportMode) { - lang = Getattr(n, "lang"); - code = Getattr(n, "name"); - value = Getattr(n, "value"); - if (Strcmp(lang, "perl5") == 0) { - if (Strcmp(code, "code") == 0) { - /* Dump the value string into the .pm file */ - if (value) { - Printf(pragma_include, "%s\n", value); - } - } else if (Strcmp(code, "include") == 0) { - /* Include a file into the .pm file */ - if (value) { - FILE *f = Swig_include_open(value); - if (!f) { - Swig_error(input_file, line_number, "Unable to locate file %s\n", value); - } else { - char buffer[4096]; - while (fgets(buffer, 4095, f)) { - Printf(pragma_include, "%s", buffer); - } - fclose(f); - } - } - } else { - Swig_error(input_file, line_number, "Unrecognized pragma.\n"); - } - } - } - return Language::pragmaDirective(n); - } - - /* ------------------------------------------------------------ - * perlcode() - Output perlcode code into the shadow file - * ------------------------------------------------------------ */ - - String *perlcode(String *code, const String *indent) { - String *out = NewString(""); - String *temp; - char *t; - if (!indent) - indent = ""; - - temp = NewString(code); - - t = Char(temp); - if (*t == '{') { - Delitem(temp, 0); - Delitem(temp, DOH_END); - } - - /* Split the input text into lines */ - List *clist = SplitLines(temp); - Delete(temp); - int initial = 0; - String *s = 0; - Iterator si; - /* Get the initial indentation */ - - for (si = First(clist); si.item; si = Next(si)) { - s = si.item; - if (Len(s)) { - char *c = Char(s); - while (*c) { - if (!isspace(*c)) - break; - initial++; - c++; - } - if (*c && !isspace(*c)) - break; - else { - initial = 0; - } - } - } - while (si.item) { - s = si.item; - if (Len(s) > initial) { - char *c = Char(s); - c += initial; - Printv(out, indent, c, "\n", NIL); - } else { - Printv(out, "\n", NIL); - } - si = Next(si); - } - Delete(clist); - return out; - } - - /* ------------------------------------------------------------ - * insertDirective() - * - * Hook for %insert directive. - * ------------------------------------------------------------ */ - - virtual int insertDirective(Node *n) { - String *code = Getattr(n, "code"); - String *section = Getattr(n, "section"); - - if ((!ImportMode) && (Cmp(section, "perl") == 0)) { - Printv(additional_perl_code, code, NIL); - } else { - Language::insertDirective(n); - } - return SWIG_OK; - } - - String *runtimeCode() { - String *s = NewString(""); - String *shead = Swig_include_sys("perlhead.swg"); - if (!shead) { - Printf(stderr, "*** Unable to open 'perlhead.swg'\n"); - } else { - Append(s, shead); - Delete(shead); - } - String *serrors = Swig_include_sys("perlerrors.swg"); - if (!serrors) { - Printf(stderr, "*** Unable to open 'perlerrors.swg'\n"); - } else { - Append(s, serrors); - Delete(serrors); - } - String *srun = Swig_include_sys("perlrun.swg"); - if (!srun) { - Printf(stderr, "*** Unable to open 'perlrun.swg'\n"); - } else { - Append(s, srun); - Delete(srun); - } - return s; - } - - String *defaultExternalRuntimeFilename() { - return NewString("swigperlrun.h"); - } - - virtual int classDirectorInit(Node *n) { - String *declaration = Swig_director_declaration(n); - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "%s\n", declaration); - Printf(f_directors_h, "public:\n"); - Delete(declaration); - return Language::classDirectorInit(n); - } - - virtual int classDirectorEnd(Node *n) { - if (dirprot_mode()) { - /* - This implementation uses a std::map<std::string,int>. - - It should be possible to rewrite it using a more elegant way, - like copying the Java approach for the 'override' array. - - But for now, this seems to be the least intrusive way. - */ - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "/* Internal director utilities */\n"); - Printf(f_directors_h, "public:\n"); - Printf(f_directors_h, " bool swig_get_inner(const char *swig_protected_method_name) const {\n"); - Printf(f_directors_h, " std::map<std::string, bool>::const_iterator iv = swig_inner.find(swig_protected_method_name);\n"); - Printf(f_directors_h, " return (iv != swig_inner.end() ? iv->second : false);\n"); - Printf(f_directors_h, " }\n"); - - Printf(f_directors_h, " void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const {\n"); - Printf(f_directors_h, " swig_inner[swig_protected_method_name] = swig_val;\n"); - Printf(f_directors_h, " }\n"); - Printf(f_directors_h, "private:\n"); - Printf(f_directors_h, " mutable std::map<std::string, bool> swig_inner;\n"); - } - Printf(f_directors_h, "};\n"); - return Language::classDirectorEnd(n); - } - - virtual int classDirectorConstructor(Node *n) { - Node *parent = Getattr(n, "parentNode"); - String *sub = NewString(""); - String *decl = Getattr(n, "decl"); - String *supername = Swig_class_name(parent); - String *classname = NewString(""); - Printf(classname, "SwigDirector_%s", supername); - - /* insert self parameter */ - Parm *p; - ParmList *superparms = Getattr(n, "parms"); - ParmList *parms = CopyParmList(superparms); - String *type = NewString("SV"); - SwigType_add_pointer(type); - p = NewParm(type, NewString("self"), n); - set_nextSibling(p, parms); - parms = p; - - if (!Getattr(n, "defaultargs")) { - /* constructor */ - { - Wrapper *w = NewWrapper(); - String *call; - String *basetype = Getattr(parent, "classtype"); - String *target = Swig_method_decl(0, decl, classname, parms, 0); - call = Swig_csuperclass_call(0, basetype, superparms); - Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call); - Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype); - Append(w->def, "}\n"); - Delete(target); - Wrapper_print(w, f_directors); - Delete(call); - DelWrapper(w); - } - - /* constructor header */ - { - String *target = Swig_method_decl(0, decl, classname, parms, 1); - Printf(f_directors_h, " %s;\n", target); - Delete(target); - } - } - - Delete(sub); - Delete(classname); - Delete(supername); - Delete(parms); - return Language::classDirectorConstructor(n); - } - - virtual int classDirectorMethod(Node *n, Node *parent, String *super) { - int is_void = 0; - int is_pointer = 0; - String *decl = Getattr(n, "decl"); - String *name = Getattr(n, "name"); - String *classname = Getattr(parent, "sym:name"); - String *c_classname = Getattr(parent, "name"); - String *symname = Getattr(n, "sym:name"); - String *declaration = NewString(""); - ParmList *l = Getattr(n, "parms"); - Wrapper *w = NewWrapper(); - String *tm; - String *wrap_args = NewString(""); - String *returntype = Getattr(n, "type"); - String *value = Getattr(n, "value"); - String *storage = Getattr(n, "storage"); - bool pure_virtual = false; - int status = SWIG_OK; - int idx; - bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; - - if (Cmp(storage, "virtual") == 0) { - if (Cmp(value, "0") == 0) { - pure_virtual = true; - } - } - - /* determine if the method returns a pointer */ - is_pointer = SwigType_ispointer_return(decl); - is_void = (!Cmp(returntype, "void") && !is_pointer); - - /* virtual method definition */ - String *target; - String *pclassname = NewStringf("SwigDirector_%s", classname); - String *qualified_name = NewStringf("%s::%s", pclassname, name); - SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type"); - target = Swig_method_decl(rtype, decl, qualified_name, l, 0); - Printf(w->def, "%s", target); - Delete(qualified_name); - Delete(target); - /* header declaration */ - target = Swig_method_decl(rtype, decl, name, l, 1); - Printf(declaration, " virtual %s", target); - Delete(target); - - // Get any exception classes in the throws typemap - if (Getattr(n, "noexcept")) { - Append(w->def, " noexcept"); - Append(declaration, " noexcept"); - } - ParmList *throw_parm_list = 0; - - if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { - Parm *p; - int gencomma = 0; - - Append(w->def, " throw("); - Append(declaration, " throw("); - - if (throw_parm_list) - Swig_typemap_attach_parms("throws", throw_parm_list, 0); - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - if (gencomma++) { - Append(w->def, ", "); - Append(declaration, ", "); - } - String *str = SwigType_str(Getattr(p, "type"), 0); - Append(w->def, str); - Append(declaration, str); - Delete(str); - } - } - - Append(w->def, ")"); - Append(declaration, ")"); - } - - Append(w->def, " {"); - Append(declaration, ";\n"); - - /* declare method return value - * if the return value is a reference or const reference, a specialized typemap must - * handle it, including declaration of c_result ($result). - */ - if (!is_void && (!ignored_method || pure_virtual)) { - if (!SwigType_isclass(returntype)) { - if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { - String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); - Delete(construct_result); - } else { - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); - } - } else { - String *cres = SwigType_lstr(returntype, "c_result"); - Printf(w->code, "%s;\n", cres); - Delete(cres); - } - } - - if (!is_void && !ignored_method) { - String *pres = NewStringf("SV *%s", Swig_cresult_name()); - Wrapper_add_local(w, Swig_cresult_name(), pres); - Delete(pres); - } - - if (ignored_method) { - if (!pure_virtual) { - if (!is_void) - Printf(w->code, "return "); - String *super_call = Swig_method_call(super, l); - Printf(w->code, "%s;\n", super_call); - Delete(super_call); - } else { - Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname), - SwigType_namestr(name)); - } - } else { - /* attach typemaps to arguments (C/C++ -> Perl) */ - String *parse_args = NewString(""); - String *pstack = NewString(""); - - Swig_director_parms_fixup(l); - - /* remove the wrapper 'w' since it was producing spurious temps */ - Swig_typemap_attach_parms("in", l, 0); - Swig_typemap_attach_parms("directorin", l, w); - Swig_typemap_attach_parms("directorargout", l, w); - - Wrapper_add_local(w, "SP", "dSP"); - - { - String *ptype = Copy(getClassType()); - SwigType_add_pointer(ptype); - String *mangle = SwigType_manglestr(ptype); - - Wrapper_add_local(w, "swigself", "SV *swigself"); - Printf(w->code, "swigself = SWIG_NewPointerObj(SWIG_as_voidptr(this), SWIGTYPE%s, SWIG_SHADOW);\n", mangle); - Printf(w->code, "sv_bless(swigself, gv_stashpv(swig_get_class(), 0));\n"); - Delete(mangle); - Delete(ptype); - Append(pstack, "XPUSHs(swigself);\n"); - } - - Parm *p; - char source[256]; - - int outputs = 0; - if (!is_void) - outputs++; - - /* build argument list and type conversion string */ - idx = 0; - p = l; - while (p) { - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - continue; - } - - /* old style? caused segfaults without the p!=0 check - in the for() condition, and seems dangerous in the - while loop as well. - while (Getattr(p, "tmap:ignore")) { - p = Getattr(p, "tmap:ignore:next"); - } - */ - - if (Getattr(p, "tmap:directorargout") != 0) - outputs++; - - String *pname = Getattr(p, "name"); - String *ptype = Getattr(p, "type"); - - if ((tm = Getattr(p, "tmap:directorin")) != 0) { - sprintf(source, "obj%d", idx++); - String *input = NewString(source); - Setattr(p, "emit:directorinput", input); - Replaceall(tm, "$input", input); - Delete(input); - Replaceall(tm, "$owner", "0"); - Replaceall(tm, "$shadow", "0"); - /* Wrapper_add_localv(w, source, "SV *", source, "= 0", NIL); */ - Printv(wrap_args, "SV *", source, ";\n", NIL); - - Printv(wrap_args, tm, "\n", NIL); - Putc('O', parse_args); - Printv(pstack, "XPUSHs(", source, ");\n", NIL); - p = Getattr(p, "tmap:directorin:next"); - continue; - } else if (Cmp(ptype, "void")) { - /* special handling for pointers to other C++ director classes. - * ideally this would be left to a typemap, but there is currently no - * way to selectively apply the dynamic_cast<> to classes that have - * directors. in other words, the type "SwigDirector_$1_lname" only exists - * for classes with directors. we avoid the problem here by checking - * module.wrap::directormap, but it's not clear how to get a typemap to - * do something similar. perhaps a new default typemap (in addition - * to SWIGTYPE) called DIRECTORTYPE? - */ - if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) { - Node *module = Getattr(parent, "module"); - Node *target = Swig_directormap(module, ptype); - sprintf(source, "obj%d", idx++); - String *nonconst = 0; - /* strip pointer/reference --- should move to Swig/stype.c */ - String *nptype = NewString(Char(ptype) + 2); - /* name as pointer */ - String *ppname = Copy(pname); - if (SwigType_isreference(ptype)) { - Insert(ppname, 0, "&"); - } - /* if necessary, cast away const since Perl doesn't support it! */ - if (SwigType_isconst(nptype)) { - nonconst = NewStringf("nc_tmp_%s", pname); - String *nonconst_i = NewStringf("= const_cast< %s >(%s)", SwigType_lstr(ptype, 0), ppname); - Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL); - Delete(nonconst_i); - Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number, - "Target language argument '%s' discards const in director method %s::%s.\n", - SwigType_str(ptype, pname), SwigType_namestr(c_classname), SwigType_namestr(name)); - } else { - nonconst = Copy(ppname); - } - Delete(nptype); - Delete(ppname); - String *mangle = SwigType_manglestr(ptype); - if (target) { - String *director = NewStringf("director_%s", mangle); - Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL); - Wrapper_add_localv(w, source, "SV *", source, "= 0", NIL); - Printf(wrap_args, "%s = SWIG_DIRECTOR_CAST(%s);\n", director, nonconst); - Printf(wrap_args, "if (!%s) {\n", director); - Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); - Append(wrap_args, "} else {\n"); - Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director); - Printf(wrap_args, "SvREFCNT_inc((SV *)%s);\n", source); - Append(wrap_args, "}\n"); - Delete(director); - } else { - Wrapper_add_localv(w, source, "SV *", source, "= 0", NIL); - Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); - Printf(pstack, "XPUSHs(sv_2mortal(%s));\n", source); - } - Putc('O', parse_args); - Delete(mangle); - Delete(nonconst); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, - "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), - SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_NOWRAP; - break; - } - } - p = nextSibling(p); - } - - /* add the method name as a PyString */ - String *pyname = Getattr(n, "sym:name"); - - /* wrap complex arguments to PyObjects */ - Printv(w->code, wrap_args, NIL); - - /* pass the method call on to the Python object */ - if (dirprot_mode() && !is_public(n)) { - Printf(w->code, "swig_set_inner(\"%s\", true);\n", name); - } - - Append(w->code, "ENTER;\n"); - Append(w->code, "SAVETMPS;\n"); - Append(w->code, "PUSHMARK(SP);\n"); - Append(w->code, pstack); - Delete(pstack); - Append(w->code, "PUTBACK;\n"); - Printf(w->code, "call_method(\"%s\", G_EVAL | G_SCALAR);\n", pyname); - - if (dirprot_mode() && !is_public(n)) - Printf(w->code, "swig_set_inner(\"%s\", false);\n", name); - - /* exception handling */ - tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0); - if (!tm) { - tm = Getattr(n, "feature:director:except"); - if (tm) - tm = Copy(tm); - } - Append(w->code, "if (SvTRUE(ERRSV)) {\n"); - Append(w->code, " PUTBACK;\n FREETMPS;\n LEAVE;\n"); - if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { - Replaceall(tm, "$error", "ERRSV"); - Printv(w->code, Str(tm), "\n", NIL); - } else { - Printf(w->code, " Swig::DirectorMethodException::raise(ERRSV);\n"); - } - Append(w->code, "}\n"); - Delete(tm); - - /* - * Python method may return a simple object, or a tuple. - * for in/out arguments, we have to extract the appropriate PyObjects from the tuple, - * then marshal everything back to C/C++ (return value and output arguments). - * - */ - - /* marshal return value and other outputs (if any) from PyObject to C/C++ type */ - - String *cleanup = NewString(""); - String *outarg = NewString(""); - - if (outputs > 1) { - Wrapper_add_local(w, "output", "SV *output"); - Printf(w->code, "if (count != %d) {\n", outputs); - Printf(w->code, " Swig::DirectorTypeMismatchException::raise(\"Perl method %s.%sfailed to return a list.\");\n", classname, pyname); - Append(w->code, "}\n"); - } - - idx = 0; - - /* marshal return value */ - if (!is_void) { - Append(w->code, "SPAGAIN;\n"); - Printf(w->code, "%s = POPs;\n", Swig_cresult_name()); - tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w); - if (tm != 0) { - if (outputs > 1) { - Printf(w->code, "output = POPs;\n"); - Replaceall(tm, "$input", "output"); - } else { - Replaceall(tm, "$input", Swig_cresult_name()); - } - char temp[24]; - sprintf(temp, "%d", idx); - Replaceall(tm, "$argnum", temp); - - /* TODO check this */ - if (Getattr(n, "wrap:disown")) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - Replaceall(tm, "$result", "c_result"); - Printv(w->code, tm, "\n", NIL); - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, - "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0), - SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_ERROR; - } - } - - /* marshal outputs */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:directorargout")) != 0) { - if (outputs > 1) { - Printf(w->code, "output = POPs;\n"); - Replaceall(tm, "$result", "output"); - } else { - Replaceall(tm, "$result", Swig_cresult_name()); - } - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NIL); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } - } - - Delete(parse_args); - Delete(cleanup); - Delete(outarg); - } - - if (!ignored_method) { - Append(w->code, "PUTBACK;\n"); - Append(w->code, "FREETMPS;\n"); - Append(w->code, "LEAVE;\n"); - } - - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { - String *rettype = SwigType_str(returntype, 0); - if (!SwigType_isreference(returntype)) { - Printf(w->code, "return (%s) c_result;\n", rettype); - } else { - Printf(w->code, "return (%s) *c_result;\n", rettype); - } - Delete(rettype); - } - } - - Append(w->code, "}\n"); - - // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method - String *inline_extra_method = NewString(""); - if (dirprot_mode() && !is_public(n) && !pure_virtual) { - Printv(inline_extra_method, declaration, NIL); - String *extra_method_name = NewStringf("%sSwigPublic", name); - Replaceall(inline_extra_method, name, extra_method_name); - Replaceall(inline_extra_method, ";\n", " {\n "); - if (!is_void) - Printf(inline_extra_method, "return "); - String *methodcall = Swig_method_call(super, l); - Printv(inline_extra_method, methodcall, ";\n }\n", NIL); - Delete(methodcall); - Delete(extra_method_name); - } - - /* emit the director method */ - if (status == SWIG_OK) { - if (!Getattr(n, "defaultargs")) { - Replaceall(w->code, "$symname", symname); - Wrapper_print(w, f_directors); - Printv(f_directors_h, declaration, NIL); - Printv(f_directors_h, inline_extra_method, NIL); - } - } - - /* clean up */ - Delete(wrap_args); - Delete(pclassname); - DelWrapper(w); - return status; - } - int classDirectorDisown(Node *n) { - int rv; - member_func = 1; - rv = Language::classDirectorDisown(n); - member_func = 0; - if (rv == SWIG_OK && Swig_directorclass(n)) { - String *symname = Getattr(n, "sym:name"); - String *disown = Swig_name_disown(NSPACE_TODO, symname); - Setattr(n, "perl5:directordisown", NewStringf("%s::%s", cmodule, disown)); - } - return rv; - } - int classDirectorDestructor(Node *n) { - /* TODO: it would be nice if this didn't have to copy the body of Language::classDirectorDestructor() */ - String *DirectorClassName = directorClassName(getCurrentClass()); - String *body = NewString("\n"); - - String *ptype = Copy(getClassType()); - SwigType_add_pointer(ptype); - String *mangle = SwigType_manglestr(ptype); - - Printv(body, tab4, "dSP;\n", tab4, "SV *self = SWIG_NewPointerObj(SWIG_as_voidptr(this), SWIGTYPE", mangle, ", SWIG_SHADOW);\n", tab4, "\n", tab4, - "sv_bless(self, gv_stashpv(swig_get_class(), 0));\n", tab4, "ENTER;\n", tab4, "SAVETMPS;\n", tab4, "PUSHMARK(SP);\n", tab4, - "XPUSHs(self);\n", tab4, "XPUSHs(&PL_sv_yes);\n", tab4, "PUTBACK;\n", tab4, "call_method(\"DESTROY\", G_EVAL | G_VOID);\n", tab4, - "FREETMPS;\n", tab4, "LEAVE;\n", NIL); - - Delete(mangle); - Delete(ptype); - - if (Getattr(n, "noexcept")) { - Printf(f_directors_h, " virtual ~%s() noexcept;\n", DirectorClassName); - Printf(f_directors, "%s::~%s() noexcept {%s}\n\n", DirectorClassName, DirectorClassName, body); - } else if (Getattr(n, "throw")) { - Printf(f_directors_h, " virtual ~%s() throw();\n", DirectorClassName); - Printf(f_directors, "%s::~%s() throw() {%s}\n\n", DirectorClassName, DirectorClassName, body); - } else { - Printf(f_directors_h, " virtual ~%s();\n", DirectorClassName); - Printf(f_directors, "%s::~%s() {%s}\n\n", DirectorClassName, DirectorClassName, body); - } - return SWIG_OK; - } -}; - -/* ----------------------------------------------------------------------------- - * swig_perl5() - Instantiate module - * ----------------------------------------------------------------------------- */ - -static Language *new_swig_perl5() { - return new PERL5(); -} -extern "C" Language *swig_perl5(void) { - return new_swig_perl5(); -} diff --git a/contrib/tools/swig/Source/Modules/php.cxx b/contrib/tools/swig/Source/Modules/php.cxx deleted file mode 100644 index c8cc9212b11..00000000000 --- a/contrib/tools/swig/Source/Modules/php.cxx +++ /dev/null @@ -1,2702 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * php.cxx - * - * PHP language module for SWIG. - * ----------------------------------------------------------------------------- - */ - -#include "swigmod.h" -#include <algorithm> -#include <ctype.h> -#include <errno.h> -#include <limits.h> - -static const char *usage = "\ -PHP Options (available with -php7)\n\ - -prefix <prefix> - Prepend <prefix> to all class names in PHP wrappers\n\ -\n"; - -// How to wrap non-class functions, variables and constants: -// FIXME: Make this specifiable and also allow a real namespace. - -// Wrap as global PHP names. -static bool wrap_nonclass_global = true; - -// Wrap in a class to fake a namespace (for compatibility with SWIG's behaviour -// before PHP added namespaces. -static bool wrap_nonclass_fake_class = true; - -static String *module = 0; -static String *cap_module = 0; -static String *prefix = 0; - -static File *f_begin = 0; -static File *f_runtime = 0; -static File *f_runtime_h = 0; -static File *f_h = 0; -static File *f_directors = 0; -static File *f_directors_h = 0; - -static String *s_header; -static String *s_wrappers; -static String *s_init; -static String *r_init; // RINIT user code -static String *s_shutdown; // MSHUTDOWN user code -static String *r_shutdown; // RSHUTDOWN user code -static String *s_vdecl; -static String *s_cinit; // consttab initialization code. -static String *s_oinit; -static String *s_arginfo; -static String *s_entry; -static String *cs_entry; -static String *all_cs_entry; -static String *fake_cs_entry; -static String *s_creation; -static String *pragma_incl; -static String *pragma_code; -static String *pragma_phpinfo; -static String *pragma_version; - -static String *class_name = NULL; -static String *base_class = NULL; -static String *destructor_action = NULL; -static String *magic_set = NULL; -static String *magic_get = NULL; -static String *magic_isset = NULL; - -// Class used as pseudo-namespace for compatibility. -static String *fake_class_name() { - static String *result = NULL; - if (!result) { - result = Len(prefix) ? prefix : module; - if (!fake_cs_entry) { - fake_cs_entry = NewStringf("static const zend_function_entry class_%s_functions[] = {\n", result); - } - - Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n",result); - - Printf(s_oinit, " INIT_CLASS_ENTRY(internal_ce, \"%s\", class_%s_functions);\n", result, result); - Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", result); - Printf(s_oinit, "\n"); - } - return result; -} - -static String *swig_wrapped_interface_ce() { - static String *result = NULL; - if (!result) { - result = NewStringf("SWIG_Php_swig_wrapped_interface_ce"); - Printf(s_oinit, " INIT_CLASS_ENTRY(%s, \"SWIG\\\\wrapped\", NULL);\n", result); - } - return result; -} - -/* To reduce code size (generated and compiled) we only want to emit each - * different arginfo once, so we need to track which have been used. - */ -static Hash *arginfo_used; - -/* Track non-class pointer types we need to to wrap */ -static Hash *raw_pointer_types = 0; - -static int shadow = 1; - -// These static variables are used to pass some state from Handlers into functionWrapper -static enum { - standard = 0, - memberfn, - staticmemberfn, - membervar, - staticmembervar, - constructor, - destructor, - directorconstructor, - directordisown -} wrapperType = standard; - -extern "C" { - static void (*r_prevtracefunc) (const SwigType *t, String *mangled, String *clientdata) = 0; -} - -static void SwigPHP_emit_pointer_type_registrations() { - if (!raw_pointer_types) - return; - - Iterator ki = First(raw_pointer_types); - if (!ki.key) - return; - - Printf(s_wrappers, "/* class object handlers for pointer wrappers */\n"); - Printf(s_wrappers, "static zend_object_handlers swig_ptr_object_handlers;\n\n"); - - Printf(s_wrappers, "/* Object Creation Method for pointer wrapping class */\n"); - Printf(s_wrappers, "static zend_object *swig_ptr_object_new(zend_class_entry *ce) {\n"); - Printf(s_wrappers, " swig_object_wrapper *obj = (swig_object_wrapper*)zend_object_alloc(sizeof(swig_object_wrapper), ce);\n"); - Printf(s_wrappers, " zend_object_std_init(&obj->std, ce);\n"); - Printf(s_wrappers, " object_properties_init(&obj->std, ce);\n"); - Printf(s_wrappers, " obj->std.handlers = &swig_ptr_object_handlers;\n"); - Printf(s_wrappers, " obj->newobject = 0;\n"); - Printf(s_wrappers, " return &obj->std;\n"); - Printf(s_wrappers, "}\n\n"); - - Printf(s_wrappers, "/* Implement __toString equivalent, since that worked for the old-style resource wrapped pointers. */\n"); - Append(s_wrappers, "#if PHP_MAJOR_VERSION < 8\n"); - Printf(s_wrappers, "static int swig_ptr_cast_object(zval *z, zval *retval, int type) {\n"); - Append(s_wrappers, "#elif PHP_MAJOR_VERSION > 8 || PHP_MINOR_VERSION >= 2\n"); - Printf(s_wrappers, "static ZEND_RESULT_CODE swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n"); - Append(s_wrappers, "#else\n"); - Printf(s_wrappers, "static int swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n"); - Append(s_wrappers, "#endif\n"); - Printf(s_wrappers, " if (type == IS_STRING) {\n"); - Append(s_wrappers, "#if PHP_MAJOR_VERSION < 8\n"); - Printf(s_wrappers, " swig_object_wrapper *obj = SWIG_Z_FETCH_OBJ_P(z);\n"); - Append(s_wrappers, "#else\n"); - Printf(s_wrappers, " swig_object_wrapper *obj = swig_php_fetch_object(zobj);\n"); - Append(s_wrappers, "#endif\n"); - Printv(s_wrappers, " ZVAL_NEW_STR(retval, zend_strpprintf(0, \"SWIGPointer(%p,owned=%d)\", obj->ptr, obj->newobject));\n", NIL); - Printf(s_wrappers, " return SUCCESS;\n"); - Printf(s_wrappers, " }\n"); - Printf(s_wrappers, " return FAILURE;\n"); - Printf(s_wrappers, "}\n\n"); - - Printf(s_oinit, "\n /* Register classes to represent non-class pointer types */\n"); - Printf(s_oinit, " swig_ptr_object_handlers = *zend_get_std_object_handlers();\n"); - Printf(s_oinit, " swig_ptr_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n"); - Printf(s_oinit, " swig_ptr_object_handlers.cast_object = swig_ptr_cast_object;\n"); - - while (ki.key) { - String *type = ki.key; - - String *swig_wrapped = swig_wrapped_interface_ce(); - Printf(s_creation, "/* class entry for pointer to %s */\n", type); - Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n", type); - - Printf(s_oinit, " INIT_CLASS_ENTRY(internal_ce, \"%s\\\\%s\", NULL);\n", "SWIG", type); - Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", type); - Printf(s_oinit, " SWIG_Php_ce_%s->create_object = swig_ptr_object_new;\n", type); - Printv(s_oinit, " zend_do_implement_interface(SWIG_Php_ce_", type, ", &", swig_wrapped, ");\n", NIL); - Printf(s_oinit, " SWIG_TypeClientData(SWIGTYPE%s,SWIG_Php_ce_%s);\n", type, type); - Printf(s_oinit, "\n"); - - ki = Next(ki); - } -} - -static Hash *create_php_type_flags() { - Hash *h = NewHash(); - Setattr(h, "array", "MAY_BE_ARRAY"); - Setattr(h, "bool", "MAY_BE_BOOL"); - Setattr(h, "callable", "MAY_BE_CALLABLE"); - Setattr(h, "float", "MAY_BE_DOUBLE"); - Setattr(h, "int", "MAY_BE_LONG"); - Setattr(h, "iterable", "MAY_BE_ITERABLE"); - Setattr(h, "mixed", "MAY_BE_MIXED"); - Setattr(h, "null", "MAY_BE_NULL"); - Setattr(h, "object", "MAY_BE_OBJECT"); - Setattr(h, "resource", "MAY_BE_RESOURCE"); - Setattr(h, "string", "MAY_BE_STRING"); - Setattr(h, "void", "MAY_BE_VOID"); - return h; -} - -static Hash *php_type_flags = create_php_type_flags(); - -// php_class + ":" + php_method -> PHPTypes* -// ":" + php_function -> PHPTypes* -static Hash *all_phptypes = NewHash(); - -// php_class_name -> php_parent_class_name -static Hash *php_parent_class = NewHash(); - -// Track if a method is directed in a descendent class. -// php_class + ":" + php_method -> boolean (using SetFlag()/GetFlag()). -static Hash *has_directed_descendent = NewHash(); - -// Track required return type for parent class methods. -// php_class + ":" + php_method -> List of php types. -static Hash *parent_class_method_return_type = NewHash(); - -// Class encapsulating the machinery to add PHP type declarations. -class PHPTypes { - // List with an entry for each parameter and one for the return type. - // - // We assemble the types in here before emitting them so for an overloaded - // function we combine the type declarations from each overloaded form. - List *merged_types; - - // List with an entry for each parameter which is passed "byref" in any - // overloaded form. We use this to pass such parameters by reference in - // the dispatch function. If NULL, no parameters are passed by reference. - List *byref; - - // The id string used in the name of the arginfo for this object. - String *arginfo_id; - - // The feature:php:type value: 0, 1 or -1 for "compatibility". - int php_type_flag; - - // Does the node for this have directorNode set? - bool has_director_node; - - // Used to clamp the required number of parameters in the arginfo to be - // compatible with any parent class version of the method. - int num_required; - - int get_byref(int key) const { - return byref && key < Len(byref) && Getitem(byref, key) != None; - } - - int size() const { - return std::max(Len(merged_types), Len(byref)); - } - - String *get_phptype(int key, String *classtypes, List *more_return_types = NULL) { - Clear(classtypes); - // We want to minimise the list of class types by not redundantly listing - // a class for which a super-class is also listed. This canonicalisation - // allows for more sharing of arginfo (which reduces module size), makes - // for a cleaner list if it's shown to the user, and also will speed up - // module load a bit. - Hash *classes = NewHash(); - DOH *types = Getitem(merged_types, key); - String *result = NewStringEmpty(); - if (more_return_types) { - if (types != None) { - merge_type_lists(types, more_return_types); - } - } - if (types != None) { - SortList(types, NULL); - String *prev = NULL; - for (Iterator i = First(types); i.item; i = Next(i)) { - if (prev && Equal(prev, i.item)) { - // Skip duplicates when merging. - continue; - } - String *c = Getattr(php_type_flags, i.item); - if (c) { - if (Len(result) > 0) Append(result, "|"); - Append(result, c); - } else { - SetFlag(classes, i.item); - } - prev = i.item; - } - } - - // Remove entries for which a super-class is also listed. - Iterator i = First(classes); - while (i.key) { - String *this_class = i.key; - // We must advance the iterator early so we don't delete the element it - // points to. - i = Next(i); - String *parent = this_class; - while ((parent = Getattr(php_parent_class, parent)) != NULL) { - if (GetFlag(classes, parent)) { - Delattr(classes, this_class); - break; - } - } - } - - List *sorted_classes = SortedKeys(classes, Strcmp); - for (i = First(sorted_classes); i.item; i = Next(i)) { - if (Len(classtypes) > 0) Append(classtypes, "|"); - Append(classtypes, prefix); - Append(classtypes, i.item); - } - Delete(sorted_classes); - - // Make the mask 0 if there are only class names specified. - if (Len(result) == 0) { - Append(result, "0"); - } - return result; - } - -public: - PHPTypes(Node *n) - : merged_types(NewList()), - byref(NULL), - num_required(INT_MAX) { - String *php_type_feature = Getattr(n, "feature:php:type"); - php_type_flag = 0; - if (php_type_feature != NULL) { - if (Equal(php_type_feature, "1")) { - php_type_flag = 1; - } else if (!Equal(php_type_feature, "0")) { - php_type_flag = -1; - } - } - arginfo_id = Copy(Getattr(n, "sym:name")); - has_director_node = (Getattr(n, "directorNode") != NULL); - } - - ~PHPTypes() { - Delete(merged_types); - Delete(byref); - } - - void adjust(int num_required_, bool php_constructor) { - num_required = std::min(num_required, num_required_); - if (php_constructor) { - // Don't add a return type declaration for a PHP __construct method - // (because there it has no return type as far as PHP is concerned). - php_type_flag = 0; - } - } - - String *get_arginfo_id() const { - return arginfo_id; - } - - // key is 0 for return type, or >= 1 for parameters numbered from 1 - List *process_phptype(Node *n, int key, const String_or_char *attribute_name); - - // Merge entries from o_merge_list into merge_list, skipping any entries - // already present. - // - // Both merge_list and o_merge_list should be in sorted order. - static void merge_type_lists(List *merge_list, List *o_merge_list); - - void merge_from(const PHPTypes* o); - - void set_byref(int key) { - if (!byref) { - byref = NewList(); - } - while (Len(byref) <= key) { - Append(byref, None); - } - // If any overload takes a particular parameter by reference then the - // dispatch function also needs to take that parameter by reference so - // we can just set unconditionally here. - Setitem(byref, key, ""); // Just needs to be something != None. - } - - void emit_arginfo(DOH *item, String *key) { - Setmark(item, 1); - char *colon_ptr = Strchr(key, ':'); - assert(colon_ptr); - int colon = (int)(colon_ptr - Char(key)); - if (colon > 0 && Strcmp(colon_ptr + 1, "__construct") != 0) { - // See if there's a parent class which implements this method, and if so - // emit its arginfo and then merge its PHPTypes into ours as we need to - // be compatible with it (whether it is virtual or not). - String *this_class = NewStringWithSize(Char(key), colon); - String *parent = this_class; - while ((parent = Getattr(php_parent_class, parent)) != NULL) { - String *k = NewStringf("%s%s", parent, colon_ptr); - DOH *item = Getattr(all_phptypes, k); - if (item) { - PHPTypes *p = (PHPTypes*)Data(item); - if (!Getmark(item)) { - p->emit_arginfo(item, k); - } - merge_from(p); - Delete(k); - break; - } - Delete(k); - } - Delete(this_class); - } - - // We want to only emit each different arginfo once, as that reduces the - // size of both the generated source code and the compiled extension - // module. The parameters at this level are just named arg1, arg2, etc - // so the arginfo will be the same for any function with the same number - // of parameters and (if present) PHP type declarations for parameters and - // return type. - // - // We generate the arginfo we want (taking care to normalise, e.g. the - // lists of types are unique and in sorted order), then use the - // arginfo_used Hash to see if we've already generated it. - String *out_phptype = NULL; - String *out_phpclasses = NewStringEmpty(); - - // We provide a simple way to generate PHP return type declarations - // except for directed methods. The point of directors is to allow - // subclassing in the target language, and if the wrapped method has - // a return type declaration then an overriding method in user code - // needs to have a compatible declaration. - // - // The upshot of this is that enabling return type declarations for - // existing bindings would break compatibility with user code written - // for an older version. For parameters however the situation is - // different because if the parent class declares types for parameters - // a subclass overriding the function will be compatible whether it - // declares them or not. - // - // directorNode being present seems to indicate if this method or one - // it inherits from is directed, which is what we care about here. - // Using (!is_member_director(n)) would get it wrong for testcase - // director_frob. - if (php_type_flag && (php_type_flag > 0 || !has_director_node)) { - if (!GetFlag(has_directed_descendent, key)) { - out_phptype = get_phptype(0, out_phpclasses, Getattr(parent_class_method_return_type, key)); - } - } - - // ### in arginfo_code will be replaced with the id once that is known. - String *arginfo_code = NewStringEmpty(); - if (out_phptype) { - if (Len(out_phpclasses)) { - Replace(out_phpclasses, "\\", "\\\\", DOH_REPLACE_ANY); - Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s, %s)\n", num_required, out_phpclasses, out_phptype); - } else { - Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s)\n", num_required, out_phptype); - } - } else { - Printf(arginfo_code, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_###, 0, 0, %d)\n", num_required); - } - - int phptypes_size = size(); - for (int param_count = 1; param_count < phptypes_size; ++param_count) { - String *phpclasses = NewStringEmpty(); - String *phptype = get_phptype(param_count, phpclasses); - - int byref = get_byref(param_count); - - // FIXME: Should we be doing byref for return value as well? - - if (phptype) { - if (Len(phpclasses)) { - // We need to double any backslashes (which are PHP namespace - // separators) in the PHP class names as they get turned into - // C strings by the ZEND_ARG_OBJ_TYPE_MASK macro. - Replace(phpclasses, "\\", "\\\\", DOH_REPLACE_ANY); - Printf(arginfo_code, " ZEND_ARG_OBJ_TYPE_MASK(%d,arg%d,%s,%s,NULL)\n", byref, param_count, phpclasses, phptype); - } else { - Printf(arginfo_code, " ZEND_ARG_TYPE_MASK(%d,arg%d,%s,NULL)\n", byref, param_count, phptype); - } - } else { - Printf(arginfo_code, " ZEND_ARG_INFO(%d,arg%d)\n", byref, param_count); - } - } - Printf(arginfo_code, "ZEND_END_ARG_INFO()\n"); - - String *arginfo_id_same = Getattr(arginfo_used, arginfo_code); - if (arginfo_id_same) { - Printf(s_arginfo, "#define swig_arginfo_%s swig_arginfo_%s\n", arginfo_id, arginfo_id_same); - } else { - // Not had this arginfo before. - Setattr(arginfo_used, arginfo_code, arginfo_id); - arginfo_code = Copy(arginfo_code); - Replace(arginfo_code, "###", arginfo_id, DOH_REPLACE_FIRST); - Append(s_arginfo, arginfo_code); - } - Delete(arginfo_code); - arginfo_code = NULL; - } -}; - -static PHPTypes *phptypes = NULL; - -class PHP : public Language { -public: - PHP() { - director_language = 1; - } - - /* ------------------------------------------------------------ - * main() - * ------------------------------------------------------------ */ - - virtual void main(int argc, char *argv[]) { - SWIG_library_directory("php"); - - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "-prefix") == 0) { - if (argv[i + 1]) { - prefix = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if ((strcmp(argv[i], "-noshadow") == 0)) { - shadow = 0; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-help") == 0) { - fputs(usage, stdout); - } - } - - Preprocessor_define("SWIGPHP 1", 0); - Preprocessor_define("SWIGPHP7 1", 0); - SWIG_typemap_lang("php"); - SWIG_config_file("php.swg"); - allow_overloading(); - } - - /* ------------------------------------------------------------ - * top() - * ------------------------------------------------------------ */ - - virtual int top(Node *n) { - - String *filen; - - /* Check if directors are enabled for this module. */ - Node *mod = Getattr(n, "module"); - if (mod) { - Node *options = Getattr(mod, "options"); - if (options && Getattr(options, "directors")) { - allow_directors(); - } - } - - /* Set comparison with null for ConstructorToFunction */ - setSubclassInstanceCheck(NewString("Z_TYPE_P($arg) != IS_NULL")); - - /* Initialize all of the output files */ - String *outfile = Getattr(n, "outfile"); - String *outfile_h = Getattr(n, "outfile_h"); - - /* main output file */ - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - f_runtime = NewStringEmpty(); - - /* sections of the output file */ - s_init = NewStringEmpty(); - r_init = NewStringEmpty(); - s_shutdown = NewStringEmpty(); - r_shutdown = NewStringEmpty(); - s_header = NewString("/* header section */\n"); - s_wrappers = NewString("/* wrapper section */\n"); - s_creation = NewStringEmpty(); - /* subsections of the init section */ - s_vdecl = NewString("/* vdecl subsection */\n"); - s_cinit = NewString(" /* cinit subsection */\n"); - s_oinit = NewString(" /* oinit subsection */\n"); - pragma_phpinfo = NewStringEmpty(); - f_directors_h = NewStringEmpty(); - f_directors = NewStringEmpty(); - - if (directorsEnabled()) { - f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); - if (!f_runtime_h) { - FileErrorDisplay(outfile_h); - Exit(EXIT_FAILURE); - } - } - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", s_init); - Swig_register_filebyname("rinit", r_init); - Swig_register_filebyname("shutdown", s_shutdown); - Swig_register_filebyname("rshutdown", r_shutdown); - Swig_register_filebyname("header", s_header); - Swig_register_filebyname("wrapper", s_wrappers); - Swig_register_filebyname("director", f_directors); - Swig_register_filebyname("director_h", f_directors_h); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "PHP"); - - if (directorsEnabled()) { - Printf(f_runtime, "#define SWIG_DIRECTORS\n"); - } - - // We need to include php.h before string.h gets included, at least with - // PHP 8.2. Otherwise string.h is included without _GNU_SOURCE being - // included and memrchr() doesn't get declared, and then inline code in - // the PHP headers defines _GNU_SOURCE, includes string.h (which is a - // no op thanks to the include gaurds), then tries to use memrchr() and - // fails. - // - // We also need to suppress -Wdeclaration-after-statement if enabled - // since with PHP 8.2 zend_operators.h contains inline code which triggers - // this warning and our testsuite uses with option and -Werror. I don't - // see a good way to only do this within our testsuite, but disabling - // it globally like this shouldn't be problematic. - Append(f_runtime, - "\n" - "#if defined __GNUC__ && !defined __cplusplus\n" - "# if __GNUC__ >= 4\n" - "# pragma GCC diagnostic push\n" - "# pragma GCC diagnostic ignored \"-Wdeclaration-after-statement\"\n" - "# endif\n" - "#endif\n" - "#include \"php.h\"\n" - "#if defined __GNUC__ && !defined __cplusplus\n" - "# if __GNUC__ >= 4\n" - "# pragma GCC diagnostic pop\n" - "# endif\n" - "#endif\n\n"); - - /* Set the module name */ - module = Copy(Getattr(n, "name")); - cap_module = NewStringf("%(upper)s", module); - if (!prefix) - prefix = NewStringEmpty(); - - if (directorsEnabled()) { - Swig_banner(f_directors_h); - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", cap_module); - Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", cap_module); - - String *filename = Swig_file_filename(outfile_h); - Printf(f_directors, "\n#include \"%s\"\n\n", filename); - Delete(filename); - } - - /* sub-sections of the php file */ - pragma_code = NewStringEmpty(); - pragma_incl = NewStringEmpty(); - pragma_version = NULL; - - /* Initialize the rest of the module */ - - /* start the header section */ - Printf(s_header, "#define SWIG_name \"%s\"\n", module); - Printf(s_header, "#ifdef __cplusplus\n"); - Printf(s_header, "extern \"C\" {\n"); - Printf(s_header, "#endif\n"); - Printf(s_header, "#include \"php_ini.h\"\n"); - Printf(s_header, "#include \"ext/standard/info.h\"\n"); - Printf(s_header, "#include \"php_%s.h\"\n", module); - Printf(s_header, "#ifdef __cplusplus\n"); - Printf(s_header, "}\n"); - Printf(s_header, "#endif\n\n"); - - if (directorsEnabled()) { - // Insert director runtime - Swig_insert_file("director_common.swg", s_header); - Swig_insert_file("director.swg", s_header); - } - - /* Create the .h file too */ - filen = NewStringEmpty(); - Printv(filen, SWIG_output_directory(), "php_", module, ".h", NIL); - f_h = NewFile(filen, "w", SWIG_output_files()); - if (!f_h) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - - Swig_banner(f_h); - - Printf(f_h, "\n"); - Printf(f_h, "#ifndef PHP_%s_H\n", cap_module); - Printf(f_h, "#define PHP_%s_H\n\n", cap_module); - Printf(f_h, "extern zend_module_entry %s_module_entry;\n", module); - Printf(f_h, "#define phpext_%s_ptr &%s_module_entry\n\n", module, module); - Printf(f_h, "#ifdef PHP_WIN32\n"); - Printf(f_h, "# define PHP_%s_API __declspec(dllexport)\n", cap_module); - Printf(f_h, "#else\n"); - Printf(f_h, "# define PHP_%s_API\n", cap_module); - Printf(f_h, "#endif\n\n"); - - /* start the arginfo section */ - s_arginfo = NewString("/* arginfo subsection */\n"); - arginfo_used = NewHash(); - - /* start the function entry section */ - s_entry = NewString("/* entry subsection */\n"); - - /* holds all the per-class function entry sections */ - all_cs_entry = NewString("/* class entry subsection */\n"); - cs_entry = NULL; - fake_cs_entry = NULL; - - Printf(s_entry, "/* Every non-class user visible function must have an entry here */\n"); - Printf(s_entry, "static const zend_function_entry module_%s_functions[] = {\n", module); - - /* Emit all of the code */ - Language::top(n); - - /* Emit all the arginfo. We sort the keys so the output order doesn't depend on - * hashkey order. - */ - { - List *sorted_keys = SortedKeys(all_phptypes, Strcmp); - for (Iterator k = First(sorted_keys); k.item; k = Next(k)) { - DOH *val = Getattr(all_phptypes, k.item); - if (!Getmark(val)) { - PHPTypes *p = (PHPTypes*)Data(val); - p->emit_arginfo(val, k.item); - } - } - Delete(sorted_keys); - } - - SwigPHP_emit_pointer_type_registrations(); - Dump(s_creation, s_header); - Delete(s_creation); - s_creation = NULL; - - /* start the init section */ - { - String *s_init_old = s_init; - s_init = NewString("/* init section */\n"); - Printv(s_init, "zend_module_entry ", module, "_module_entry = {\n", NIL); - Printf(s_init, " STANDARD_MODULE_HEADER,\n"); - Printf(s_init, " \"%s\",\n", module); - Printf(s_init, " module_%s_functions,\n", module); - Printf(s_init, " PHP_MINIT(%s),\n", module); - if (Len(s_shutdown) > 0) { - Printf(s_init, " PHP_MSHUTDOWN(%s),\n", module); - } else { - Printf(s_init, " NULL, /* No MSHUTDOWN code */\n"); - } - if (Len(r_init) > 0) { - Printf(s_init, " PHP_RINIT(%s),\n", module); - } else { - Printf(s_init, " NULL, /* No RINIT code */\n"); - } - if (Len(r_shutdown) > 0) { - Printf(s_init, " PHP_RSHUTDOWN(%s),\n", module); - } else { - Printf(s_init, " NULL, /* No RSHUTDOWN code */\n"); - } - if (Len(pragma_phpinfo) > 0) { - Printf(s_init, " PHP_MINFO(%s),\n", module); - } else { - Printf(s_init, " NULL, /* No MINFO code */\n"); - } - if (Len(pragma_version) > 0) { - Printf(s_init, " \"%s\",\n", pragma_version); - } else { - Printf(s_init, " NO_VERSION_YET,\n"); - } - Printf(s_init, " STANDARD_MODULE_PROPERTIES\n"); - Printf(s_init, "};\n\n"); - - Printf(s_init, "#ifdef __cplusplus\n"); - Printf(s_init, "extern \"C\" {\n"); - Printf(s_init, "#endif\n"); - // We want to write "SWIGEXPORT ZEND_GET_MODULE(%s)" but ZEND_GET_MODULE - // in PHP7 has "extern "C" { ... }" around it so we can't do that. - Printf(s_init, "SWIGEXPORT zend_module_entry *get_module(void) { return &%s_module_entry; }\n", module); - Printf(s_init, "#ifdef __cplusplus\n"); - Printf(s_init, "}\n"); - Printf(s_init, "#endif\n\n"); - - Printf(s_init, "#define SWIG_php_minit PHP_MINIT_FUNCTION(%s)\n\n", module); - - Printv(s_init, s_init_old, NIL); - Delete(s_init_old); - } - - /* We have to register the constants before they are (possibly) used - * by the pointer typemaps. This all needs re-arranging really as - * things are being called in the wrong order - */ - - Printf(s_oinit, " /* end oinit subsection */\n"); - Printf(s_init, "%s\n", s_oinit); - - /* Constants generated during top call */ - Printf(s_cinit, " /* end cinit subsection */\n"); - Printf(s_init, "%s\n", s_cinit); - Clear(s_cinit); - Delete(s_cinit); - - Printf(s_init, " return SUCCESS;\n"); - Printf(s_init, "}\n\n"); - - // Now do REQUEST init which holds any user specified %rinit, and also vinit - if (Len(r_init) > 0) { - Printf(f_h, "PHP_RINIT_FUNCTION(%s);\n", module); - - Printf(s_init, "PHP_RINIT_FUNCTION(%s)\n{\n", module); - Printv(s_init, - "/* rinit section */\n", - r_init, "\n", - NIL); - - Printf(s_init, " return SUCCESS;\n"); - Printf(s_init, "}\n\n"); - } - - Printf(f_h, "PHP_MINIT_FUNCTION(%s);\n", module); - - if (Len(s_shutdown) > 0) { - Printf(f_h, "PHP_MSHUTDOWN_FUNCTION(%s);\n", module); - - Printv(s_init, "PHP_MSHUTDOWN_FUNCTION(", module, ")\n" - "/* shutdown section */\n" - "{\n", - s_shutdown, - " return SUCCESS;\n" - "}\n\n", NIL); - } - - if (Len(r_shutdown) > 0) { - Printf(f_h, "PHP_RSHUTDOWN_FUNCTION(%s);\n", module); - - Printf(s_init, "PHP_RSHUTDOWN_FUNCTION(%s)\n{\n", module); - Printf(s_init, "/* rshutdown section */\n"); - Printf(s_init, "%s\n", r_shutdown); - Printf(s_init, " return SUCCESS;\n"); - Printf(s_init, "}\n\n"); - } - - if (Len(pragma_phpinfo) > 0) { - Printf(f_h, "PHP_MINFO_FUNCTION(%s);\n", module); - - Printf(s_init, "PHP_MINFO_FUNCTION(%s)\n{\n", module); - Printf(s_init, "%s", pragma_phpinfo); - Printf(s_init, "}\n"); - } - - Printf(s_init, "/* end init section */\n"); - - Printf(f_h, "\n#endif /* PHP_%s_H */\n", cap_module); - - Delete(f_h); - - String *type_table = NewStringEmpty(); - SwigType_emit_type_table(f_runtime, type_table); - Printf(s_header, "%s", type_table); - Delete(type_table); - - /* Oh dear, more things being called in the wrong order. This whole - * function really needs totally redoing. - */ - - if (directorsEnabled()) { - Dump(f_directors_h, f_runtime_h); - Printf(f_runtime_h, "\n"); - Printf(f_runtime_h, "#endif\n"); - Delete(f_runtime_h); - } - - Printf(s_header, "/* end header section */\n"); - Printf(s_wrappers, "/* end wrapper section */\n"); - Printf(s_vdecl, "/* end vdecl subsection */\n"); - - Dump(f_runtime, f_begin); - Printv(f_begin, s_header, NIL); - if (directorsEnabled()) { - Dump(f_directors, f_begin); - } - Printv(f_begin, s_vdecl, s_wrappers, NIL); - Printv(f_begin, s_arginfo, "\n\n", all_cs_entry, "\n\n", s_entry, - " ZEND_FE_END\n};\n\n", NIL); - if (fake_cs_entry) { - Printv(f_begin, fake_cs_entry, " ZEND_FE_END\n};\n\n", NIL); - Delete(fake_cs_entry); - fake_cs_entry = NULL; - } - Printv(f_begin, s_init, NIL); - Delete(s_header); - Delete(s_wrappers); - Delete(s_init); - Delete(s_vdecl); - Delete(all_cs_entry); - Delete(s_entry); - Delete(s_arginfo); - Delete(f_runtime); - Delete(f_begin); - Delete(arginfo_used); - - if (Len(pragma_incl) > 0 || Len(pragma_code) > 0) { - /* PHP module file */ - String *php_filename = NewStringEmpty(); - Printv(php_filename, SWIG_output_directory(), module, ".php", NIL); - - File *f_phpcode = NewFile(php_filename, "w", SWIG_output_files()); - if (!f_phpcode) { - FileErrorDisplay(php_filename); - Exit(EXIT_FAILURE); - } - - Printf(f_phpcode, "<?php\n\n"); - - if (Len(pragma_incl) > 0) { - Printv(f_phpcode, pragma_incl, "\n", NIL); - } - - if (Len(pragma_code) > 0) { - Printv(f_phpcode, pragma_code, "\n", NIL); - } - - Delete(f_phpcode); - Delete(php_filename); - } - - return SWIG_OK; - } - - /* Just need to append function names to function table to register with PHP. */ - void create_command(String *cname, String *fname, Node *n, bool dispatch, String *modes = NULL) { - // This is for the single main zend_function_entry record - ParmList *l = Getattr(n, "parms"); - if (cname && !Equal(Getattr(n, "storage"), "friend")) { - Printf(f_h, "static PHP_METHOD(%s%s,%s);\n", prefix, cname, fname); - if (wrapperType != staticmemberfn && - wrapperType != staticmembervar && - !Equal(fname, "__construct")) { - // Skip the first entry in the parameter list which is the this pointer. - if (l) l = Getattr(l, "tmap:in:next"); - // FIXME: does this throw the phptype key value off? - } - } else { - if (dispatch) { - Printf(f_h, "static ZEND_NAMED_FUNCTION(%s);\n", fname); - } else { - Printf(f_h, "static PHP_FUNCTION(%s);\n", fname); - } - } - - phptypes->adjust(emit_num_required(l), Equal(fname, "__construct") ? true : false); - - String *arginfo_id = phptypes->get_arginfo_id(); - String *s = cs_entry; - if (!s) s = s_entry; - if (cname && !Equal(Getattr(n, "storage"), "friend")) { - Printf(all_cs_entry, " PHP_ME(%s%s,%s,swig_arginfo_%s,%s)\n", prefix, cname, fname, arginfo_id, modes); - } else { - if (dispatch) { - if (wrap_nonclass_global) { - Printf(s, " ZEND_NAMED_FE(%(lower)s,%s,swig_arginfo_%s)\n", Getattr(n, "sym:name"), fname, arginfo_id); - } - - if (wrap_nonclass_fake_class) { - (void)fake_class_name(); - Printf(fake_cs_entry, " ZEND_NAMED_ME(%(lower)s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", Getattr(n, "sym:name"), fname, arginfo_id); - } - } else { - if (wrap_nonclass_global) { - Printf(s, " PHP_FE(%s,swig_arginfo_%s)\n", fname, arginfo_id); - } - - if (wrap_nonclass_fake_class) { - String *fake_class = fake_class_name(); - Printf(fake_cs_entry, " PHP_ME(%s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", fake_class, fname, arginfo_id); - } - } - } - } - - /* ------------------------------------------------------------ - * dispatchFunction() - * ------------------------------------------------------------ */ - void dispatchFunction(Node *n, int constructor) { - /* Last node in overloaded chain */ - - int maxargs; - String *tmp = NewStringEmpty(); - String *dispatch = Swig_overload_dispatch(n, "%s(INTERNAL_FUNCTION_PARAM_PASSTHRU); return;", &maxargs); - - /* Generate a dispatch wrapper for all overloaded functions */ - - Wrapper *f = NewWrapper(); - String *symname = Getattr(n, "sym:name"); - String *wname = NULL; - String *modes = NULL; - bool constructorRenameOverload = false; - - if (constructor) { - if (!Equal(class_name, Getattr(n, "constructorHandler:sym:name"))) { - // Renamed constructor - turn into static factory method - constructorRenameOverload = true; - wname = Copy(Getattr(n, "constructorHandler:sym:name")); - } else { - wname = NewString("__construct"); - } - } else if (class_name) { - wname = Getattr(n, "wrapper:method:name"); - } else { - wname = Swig_name_wrapper(symname); - } - - if (constructor) { - modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_CTOR"); - if (constructorRenameOverload) { - Append(modes, " | ZEND_ACC_STATIC"); - } - } else if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"), "static") == 0) { - modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_STATIC"); - } else { - modes = NewString("ZEND_ACC_PUBLIC"); - } - - create_command(class_name, wname, n, true, modes); - - if (class_name && !Equal(Getattr(n, "storage"), "friend")) { - Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL); - } else { - Printv(f->def, "static ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL); - } - - Wrapper_add_local(f, "argc", "int argc"); - - Printf(tmp, "zval argv[%d]", maxargs); - Wrapper_add_local(f, "argv", tmp); - - Printf(f->code, "argc = ZEND_NUM_ARGS();\n"); - - Printf(f->code, "zend_get_parameters_array_ex(argc, argv);\n"); - - Replaceall(dispatch, "$args", "self,args"); - - Printv(f->code, dispatch, "\n", NIL); - - Printf(f->code, "zend_throw_exception(zend_ce_type_error, \"No matching function for overloaded '%s'\", 0);\n", symname); - Printv(f->code, "fail:\n", NIL); - Printv(f->code, "return;\n", NIL); - Printv(f->code, "}\n", NIL); - Wrapper_print(f, s_wrappers); - - DelWrapper(f); - Delete(dispatch); - Delete(tmp); - } - - /* ------------------------------------------------------------ - * functionWrapper() - * ------------------------------------------------------------ */ - - /* Helper function to check if class is wrapped */ - bool is_class_wrapped(String *className) { - if (!className) - return false; - Node *n = symbolLookup(className); - return n && Getattr(n, "classtype") != NULL; - } - - void generate_magic_property_methods(Node *class_node) { - String *swig_base = base_class; - if (Equal(swig_base, "Exception") || !is_class_wrapped(swig_base)) { - swig_base = NULL; - } - - static bool generated_magic_arginfo = false; - if (!generated_magic_arginfo) { - // Create arginfo entries for __get, __set and __isset. - Append(s_arginfo, - "ZEND_BEGIN_ARG_INFO_EX(swig_magic_arginfo_get, 0, 0, 1)\n" - " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n" - "ZEND_END_ARG_INFO()\n"); - Append(s_arginfo, - "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_magic_arginfo_set, 0, 1, MAY_BE_VOID)\n" - " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n" - " ZEND_ARG_INFO(0,arg2)\n" - "ZEND_END_ARG_INFO()\n"); - Append(s_arginfo, - "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_magic_arginfo_isset, 0, 1, MAY_BE_BOOL)\n" - " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n" - "ZEND_END_ARG_INFO()\n"); - generated_magic_arginfo = true; - } - - Wrapper *f = NewWrapper(); - - Printf(f_h, "PHP_METHOD(%s%s,__set);\n", prefix, class_name); - Printf(all_cs_entry, " PHP_ME(%s%s,__set,swig_magic_arginfo_set,ZEND_ACC_PUBLIC)\n", prefix, class_name); - Printf(f->code, "PHP_METHOD(%s%s,__set) {\n", prefix, class_name); - - Printf(f->code, " swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n"); - Printf(f->code, " zval args[2];\n zval tempZval;\n zend_string *arg2 = 0;\n\n"); - Printf(f->code, " if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {\n"); - Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n"); - Printf(f->code, " if (!arg) {\n"); - Printf(f->code, " zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n"); - Printf(f->code, " return;\n"); - Printf(f->code, " }\n"); - Printf(f->code, " arg2 = Z_STR(args[0]);\n\n"); - - Printf(f->code, "if (!arg2) {\n RETVAL_NULL();\n}\n"); - if (magic_set) { - Append(f->code, magic_set); - } - Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n"); - Printf(f->code, "arg->newobject = zval_get_long(&args[1]);\n"); - if (Swig_directorclass(class_node)) { - Printv(f->code, "if (arg->newobject == 0) {\n", - " Swig::Director *director = SWIG_DIRECTOR_CAST((", Getattr(class_node, "classtype"), "*)(arg->ptr));\n", - " if (director) director->swig_disown();\n", - "}\n", NIL); - } - if (swig_base) { - Printf(f->code, "} else {\nPHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n", prefix, swig_base); - } else if (Getattr(class_node, "feature:php:allowdynamicproperties")) { - Printf(f->code, "} else {\nadd_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n"); - } - Printf(f->code, "}\n"); - - Printf(f->code, "fail:\n"); - Printf(f->code, "return;\n"); - Printf(f->code, "}\n\n\n"); - - - Printf(f_h, "PHP_METHOD(%s%s,__get);\n", prefix, class_name); - Printf(all_cs_entry, " PHP_ME(%s%s,__get,swig_magic_arginfo_get,ZEND_ACC_PUBLIC)\n", prefix, class_name); - Printf(f->code, "PHP_METHOD(%s%s,__get) {\n",prefix, class_name); - - Printf(f->code, " swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n"); - Printf(f->code, " zval args[1];\n zval tempZval;\n zend_string *arg2 = 0;\n\n"); - Printf(f->code, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n"); - Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n"); - Printf(f->code, " if (!arg) {\n"); - Printf(f->code, " zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n"); - Printf(f->code, " return;\n"); - Printf(f->code, " }\n"); - Printf(f->code, " arg2 = Z_STR(args[0]);\n\n"); - - Printf(f->code, "if (!arg2) {\n RETVAL_NULL();\n}\n"); - if (magic_get) { - Append(f->code, magic_get); - } - Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n"); - Printf(f->code, "if(arg->newobject) {\nRETVAL_LONG(1);\n}\nelse {\nRETVAL_LONG(0);\n}\n}\n\n"); - Printf(f->code, "else {\n"); - if (swig_base) { - Printf(f->code, "PHP_MN(%s%s___get)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base); - } else { - // __get is only called if the property isn't set on the zend_object. - Printf(f->code, "RETVAL_NULL();\n}\n"); - } - - Printf(f->code, "fail:\n"); - Printf(f->code, "return;\n"); - Printf(f->code, "}\n\n\n"); - - - Printf(f_h, "PHP_METHOD(%s%s,__isset);\n", prefix, class_name); - Printf(all_cs_entry, " PHP_ME(%s%s,__isset,swig_magic_arginfo_isset,ZEND_ACC_PUBLIC)\n", prefix, class_name); - Printf(f->code, "PHP_METHOD(%s%s,__isset) {\n",prefix, class_name); - - Printf(f->code, " swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n"); - Printf(f->code, " zval args[1];\n zend_string *arg2 = 0;\n\n"); - Printf(f->code, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n"); - Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n"); - Printf(f->code, " if(!arg) {\n"); - Printf(f->code, " zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n"); - Printf(f->code, " return;\n"); - Printf(f->code, " }\n"); - Printf(f->code, " arg2 = Z_STR(args[0]);\n\n"); - - Printf(f->code, "if (!arg2) {\n RETVAL_FALSE;\n}\n"); - Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n"); - Printf(f->code, "RETVAL_TRUE;\n}\n\n"); - if (magic_isset) { - Append(f->code, magic_isset); - } - Printf(f->code, "else {\n"); - if (swig_base) { - Printf(f->code, "PHP_MN(%s%s___isset)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base); - } else { - // __isset is only called if the property isn't set on the zend_object. - Printf(f->code, "RETVAL_FALSE;\n}\n"); - } - - Printf(f->code, "fail:\n"); - Printf(f->code, "return;\n"); - Printf(f->code, "}\n\n\n"); - - Wrapper_print(f, s_wrappers); - DelWrapper(f); - f = NULL; - - Delete(magic_set); - Delete(magic_get); - Delete(magic_isset); - magic_set = NULL; - magic_get = NULL; - magic_isset = NULL; - } - - String *getAccessMode(String *access) { - if (Cmp(access, "protected") == 0) { - return NewString("ZEND_ACC_PROTECTED"); - } else if (Cmp(access, "private") == 0) { - return NewString("ZEND_ACC_PRIVATE"); - } - return NewString("ZEND_ACC_PUBLIC"); - } - - bool is_setter_method(Node *n) { - const char *p = GetChar(n, "sym:name"); - if (strlen(p) > 4) { - p += strlen(p) - 4; - if (strcmp(p, "_set") == 0) { - return true; - } - } - return false; - } - - bool is_getter_method(Node *n) { - const char *p = GetChar(n, "sym:name"); - if (strlen(p) > 4) { - p += strlen(p) - 4; - if (strcmp(p, "_get") == 0) { - return true; - } - } - return false; - } - - virtual int functionWrapper(Node *n) { - if (wrapperType == directordisown) { - // Handled via __set magic method - no explicit wrapper method wanted. - return SWIG_OK; - } - String *name = GetChar(n, "name"); - String *iname = GetChar(n, "sym:name"); - SwigType *d = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - String *nodeType = Getattr(n, "nodeType"); - int newobject = GetFlag(n, "feature:new"); - int constructor = (Cmp(nodeType, "constructor") == 0); - - Parm *p; - int i; - int numopt; - String *tm; - Wrapper *f; - - String *wname = NewStringEmpty(); - String *overloadwname = NULL; - int overloaded = 0; - String *modes = NULL; - bool static_setter = false; - bool static_getter = false; - - modes = getAccessMode(Getattr(n, "access")); - - if (constructor) { - Append(modes, " | ZEND_ACC_CTOR"); - } - if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"), "static") == 0) { - Append(modes, " | ZEND_ACC_STATIC"); - } - if (GetFlag(n, "abstract") && Swig_directorclass(Swig_methodclass(n)) && !is_member_director(n)) - Append(modes, " | ZEND_ACC_ABSTRACT"); - - if (Getattr(n, "sym:overloaded")) { - overloaded = 1; - overloadwname = NewString(Swig_name_wrapper(iname)); - Printf(overloadwname, "%s", Getattr(n, "sym:overname")); - } else { - if (!addSymbol(iname, n)) - return SWIG_ERROR; - } - - if (constructor) { - if (!Equal(class_name, Getattr(n, "constructorHandler:sym:name"))) { - // Renamed constructor - turn into static factory method - wname = Copy(Getattr(n, "constructorHandler:sym:name")); - } else { - wname = NewString("__construct"); - } - } else if (wrapperType == membervar) { - wname = Copy(Getattr(n, "membervariableHandler:sym:name")); - if (is_setter_method(n)) { - Append(wname, "_set"); - } else if (is_getter_method(n)) { - Append(wname, "_get"); - } - } else if (wrapperType == memberfn) { - wname = Getattr(n, "memberfunctionHandler:sym:name"); - } else if (wrapperType == staticmembervar) { - // Shape::nshapes -> nshapes - wname = Getattr(n, "staticmembervariableHandler:sym:name"); - - /* We get called twice for getter and setter methods. But to maintain - compatibility, Shape::nshapes() is being used for both setter and - getter methods. So using static_setter and static_getter variables - to generate half of the code each time. - */ - static_setter = is_setter_method(n); - - if (is_getter_method(n)) { - // This is to overcome types that can't be set and hence no setter. - if (!Equal(Getattr(n, "feature:immutable"), "1")) - static_getter = true; - } - } else if (wrapperType == staticmemberfn) { - wname = Getattr(n, "staticmemberfunctionHandler:sym:name"); - } else { - if (class_name) { - if (Cmp(Getattr(n, "storage"), "friend") == 0 && Cmp(Getattr(n, "view"), "globalfunctionHandler") == 0) { - wname = iname; - } else { - wname = Getattr(n, "destructorHandler:sym:name"); - } - } else { - wname = iname; - } - } - - if (wrapperType == destructor) { - // We don't explicitly wrap the destructor for PHP - Zend manages the - // reference counting, and the user can just do `$obj = null;' or similar - // to remove a reference to an object. - Setattr(n, "wrap:name", wname); - (void)emit_action(n); - return SWIG_OK; - } - - if (!static_getter) { - // Create or find existing PHPTypes. - phptypes = NULL; - - String *key; - if (class_name && !Equal(Getattr(n, "storage"), "friend")) { - key = NewStringf("%s:%s", class_name, wname); - } else { - key = NewStringf(":%s", wname); - } - - PHPTypes *p = (PHPTypes*)GetVoid(all_phptypes, key); - if (p) { - // We already have an entry so use it. - phptypes = p; - Delete(key); - } else { - phptypes = new PHPTypes(n); - SetVoid(all_phptypes, key, phptypes); - } - } - - f = NewWrapper(); - - if (static_getter) { - Printf(f->def, "{\n"); - } - - String *outarg = NewStringEmpty(); - String *cleanup = NewStringEmpty(); - - if (!overloaded) { - if (!static_getter) { - if (class_name && !Equal(Getattr(n, "storage"), "friend")) { - Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL); - } else { - if (wrap_nonclass_global) { - Printv(f->def, "static PHP_METHOD(", fake_class_name(), ",", wname, ") {\n", - " PHP_FN(", wname, ")(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n", - "}\n\n", NIL); - } - - if (wrap_nonclass_fake_class) { - Printv(f->def, "static PHP_FUNCTION(", wname, ") {\n", NIL); - } - } - } - } else { - Printv(f->def, "static ZEND_NAMED_FUNCTION(", overloadwname, ") {\n", NIL); - } - - emit_parameter_variables(l, f); - /* Attach standard typemaps */ - - emit_attach_parmmaps(l, f); - - if (wrapperType == memberfn || wrapperType == membervar) { - // Assign "this" to arg1 and remove first entry from ParmList l. - Printf(f->code, "arg1 = (%s)SWIG_Z_FETCH_OBJ_P(ZEND_THIS)->ptr;\n", SwigType_lstr(Getattr(l, "type"), "")); - l = nextSibling(l); - } - - // wrap:parms is used by overload resolution. - Setattr(n, "wrap:parms", l); - - int num_arguments = emit_num_arguments(l); - int num_required = emit_num_required(l); - numopt = num_arguments - num_required; - - if (num_arguments > 0) { - String *args = NewStringEmpty(); - Printf(args, "zval args[%d]", num_arguments); - Wrapper_add_local(f, "args", args); - Delete(args); - args = NULL; - } - if (wrapperType == directorconstructor) { - Wrapper_add_local(f, "arg0", "zval *arg0 = ZEND_THIS"); - } - - // This generated code may be called: - // 1) as an object method, or - // 2) as a class-method/function (without a "this_ptr") - // Option (1) has "this_ptr" for "this", option (2) needs it as - // first parameter - - // NOTE: possible we ignore this_ptr as a param for native constructor - - if (numopt > 0) { // membervariable wrappers do not have optional args - Wrapper_add_local(f, "arg_count", "int arg_count"); - Printf(f->code, "arg_count = ZEND_NUM_ARGS();\n"); - Printf(f->code, "if(arg_count<%d || arg_count>%d ||\n", num_required, num_arguments); - Printf(f->code, " zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)\n"); - Printf(f->code, "\tWRONG_PARAM_COUNT;\n\n"); - } else if (static_setter || static_getter) { - if (num_arguments == 0) { - Printf(f->code, "if(ZEND_NUM_ARGS() == 0) {\n"); - } else { - Printf(f->code, "if(ZEND_NUM_ARGS() == %d && zend_get_parameters_array_ex(%d, args) == SUCCESS) {\n", num_arguments, num_arguments); - } - } else { - if (num_arguments == 0) { - Printf(f->code, "if(ZEND_NUM_ARGS() != 0) {\n"); - } else { - Printf(f->code, "if(ZEND_NUM_ARGS() != %d || zend_get_parameters_array_ex(%d, args) != SUCCESS) {\n", num_arguments, num_arguments); - } - Printf(f->code, "WRONG_PARAM_COUNT;\n}\n\n"); - } - - /* Now convert from PHP to C variables */ - // At this point, argcount if used is the number of deliberately passed args - // not including this_ptr even if it is used. - // It means error messages may be out by argbase with error - // reports. We can either take argbase into account when raising - // errors, or find a better way of dealing with _thisptr. - // I would like, if objects are wrapped, to assume _thisptr is always - // _this and not the first argument. - // This may mean looking at Language::memberfunctionHandler - - for (i = 0, p = l; i < num_arguments; i++) { - /* Skip ignored arguments */ - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - /* Check if optional */ - if (i >= num_required) { - Printf(f->code, "\tif(arg_count > %d) {\n", i); - } - - tm = Getattr(p, "tmap:in"); - if (!tm) { - SwigType *pt = Getattr(p, "type"); - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); - p = nextSibling(p); - continue; - } - - phptypes->process_phptype(p, i + 1, "tmap:in:phptype"); - if (GetFlag(p, "tmap:in:byref")) phptypes->set_byref(i + 1); - - String *source = NewStringf("args[%d]", i); - Replaceall(tm, "$input", source); - Setattr(p, "emit:input", source); - Printf(f->code, "%s\n", tm); - if (i == 0 && Getattr(p, "self")) { - Printf(f->code, "\tif(!arg1) {\n"); - Printf(f->code, "\t zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n"); - Printf(f->code, "\t return;\n"); - Printf(f->code, "\t}\n"); - } - - if (i >= num_required) { - Printf(f->code, "}\n"); - } - - p = Getattr(p, "tmap:in:next"); - - Delete(source); - } - - if (is_member_director(n)) { - Wrapper_add_local(f, "director", "Swig::Director *director = 0"); - Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n"); - Wrapper_add_local(f, "upcall", "bool upcall = false"); - Printf(f->code, "upcall = (director && (director->swig_get_self()==Z_OBJ_P(ZEND_THIS)));\n"); - } - - Swig_director_emit_dynamic_cast(n, f); - - /* Insert constraint checking code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert cleanup code */ - for (i = 0, p = l; p; i++) { - if ((tm = Getattr(p, "tmap:freearg"))) { - Printv(cleanup, tm, "\n", NIL); - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert argument output code */ - for (i = 0, p = l; p; i++) { - if ((tm = Getattr(p, "tmap:argout")) && Len(tm)) { - Replaceall(tm, "$result", "return_value"); - Replaceall(tm, "$arg", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - if (!overloaded) { - Setattr(n, "wrap:name", wname); - } else { - Setattr(n, "wrap:name", overloadwname); - } - Setattr(n, "wrapper:method:name", wname); - - bool php_constructor = (constructor && Cmp(class_name, Getattr(n, "constructorHandler:sym:name")) == 0); - - /* emit function call */ - String *actioncode = emit_action(n); - - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { - Replaceall(tm, "$input", Swig_cresult_name()); - Replaceall(tm, "$result", php_constructor ? "ZEND_THIS" : "return_value"); - Replaceall(tm, "$owner", newobject ? "1" : "0"); - Printf(f->code, "%s\n", tm); - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name); - } - emit_return_variable(n, d, f); - - List *return_types = phptypes->process_phptype(n, 0, "tmap:out:phptype"); - - if (class_name && !Equal(Getattr(n, "storage"), "friend")) { - if (is_member_director(n)) { - String *parent = class_name; - while ((parent = Getattr(php_parent_class, parent)) != NULL) { - // Mark this method name as having no return type declaration for all - // classes we're derived from. - SetFlag(has_directed_descendent, NewStringf("%s:%s", parent, wname)); - } - } else if (return_types) { - String *parent = class_name; - while ((parent = Getattr(php_parent_class, parent)) != NULL) { - String *key = NewStringf("%s:%s", parent, wname); - // The parent class method needs to have a superset of the possible - // return types of methods with the same name in subclasses. - List *v = Getattr(parent_class_method_return_type, key); - if (!v) { - // New entry. - Setattr(parent_class_method_return_type, key, Copy(return_types)); - } else { - // Update existing entry. - PHPTypes::merge_type_lists(v, return_types); - } - } - } - } - - if (outarg) { - Printv(f->code, outarg, NIL); - } - - if (static_setter && cleanup) { - Printv(f->code, cleanup, NIL); - } - - /* Look to see if there is any newfree cleanup code */ - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - Delete(tm); - } - } - - /* See if there is any return cleanup code */ - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - Delete(tm); - } - - if (static_getter) { - Printf(f->code, "}\n"); - } - - if (static_setter || static_getter) { - Printf(f->code, "}\n"); - } - - if (!static_setter) { - Printf(f->code, "fail:\n"); - Printv(f->code, cleanup, NIL); - Printf(f->code, "return;\n"); - Printf(f->code, "}\n"); - } - - Replaceall(f->code, "$cleanup", cleanup); - Replaceall(f->code, "$symname", iname); - - Wrapper_print(f, s_wrappers); - DelWrapper(f); - f = NULL; - - if (overloaded) { - if (!Getattr(n, "sym:nextSibling")) { - dispatchFunction(n, constructor); - } - } else { - if (!static_setter) { - create_command(class_name, wname, n, false, modes); - } - } - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * globalvariableHandler() - * ------------------------------------------------------------ */ - - /* PHP doesn't support intercepting reads and writes to global variables - * (nor static property reads and writes so we can't wrap them as static - * properties on a dummy class) so just let SWIG do its default thing and - * wrap them as name_get() and name_set(). - */ - //virtual int globalvariableHandler(Node *n) { - //} - - /* ------------------------------------------------------------ - * constantWrapper() - * ------------------------------------------------------------ */ - - virtual int constantWrapper(Node *n) { - String *name = GetChar(n, "name"); - String *iname = GetChar(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - String *rawval = Getattr(n, "rawval"); - String *value = rawval ? rawval : Getattr(n, "value"); - String *tm; - - if (!addSymbol(iname, n)) - return SWIG_ERROR; - - SwigType_remember(type); - - String *wrapping_member_constant = Getattr(n, "memberconstantHandler:sym:name"); - if (!wrapping_member_constant) { - { - tm = Swig_typemap_lookup("consttab", n, name, 0); - Replaceall(tm, "$value", value); - if (Getattr(n, "tmap:consttab:rinit")) { - Printf(r_init, "%s\n", tm); - } else { - Printf(s_cinit, "%s\n", tm); - } - } - - { - tm = Swig_typemap_lookup("classconsttab", n, name, 0); - - Replaceall(tm, "$class", fake_class_name()); - Replaceall(tm, "$const_name", iname); - Replaceall(tm, "$value", value); - if (Getattr(n, "tmap:classconsttab:rinit")) { - Printf(r_init, "%s\n", tm); - } else { - Printf(s_cinit, "%s\n", tm); - } - } - } else { - tm = Swig_typemap_lookup("classconsttab", n, name, 0); - Replaceall(tm, "$class", class_name); - Replaceall(tm, "$const_name", wrapping_member_constant); - Replaceall(tm, "$value", value); - if (Getattr(n, "tmap:classconsttab:rinit")) { - Printf(r_init, "%s\n", tm); - } else { - Printf(s_cinit, "%s\n", tm); - } - } - - wrapperType = standard; - return SWIG_OK; - } - - /* - * PHP::pragma() - * - * Pragma directive. - * - * %pragma(php) code="String" # Includes a string in the .php file - * %pragma(php) include="file.php" # Includes a file in the .php file - */ - - virtual int pragmaDirective(Node *n) { - if (!ImportMode) { - String *lang = Getattr(n, "lang"); - String *type = Getattr(n, "name"); - String *value = Getattr(n, "value"); - - if (Strcmp(lang, "php") == 0) { - if (Strcmp(type, "code") == 0) { - if (value) { - Printf(pragma_code, "%s\n", value); - } - } else if (Strcmp(type, "include") == 0) { - if (value) { - Printf(pragma_incl, "include '%s';\n", value); - } - } else if (Strcmp(type, "phpinfo") == 0) { - if (value) { - Printf(pragma_phpinfo, "%s\n", value); - } - } else if (Strcmp(type, "version") == 0) { - if (value) { - pragma_version = value; - } - } else { - Swig_warning(WARN_PHP_UNKNOWN_PRAGMA, input_file, line_number, "Unrecognized pragma <%s>.\n", type); - } - } - } - return Language::pragmaDirective(n); - } - - /* ------------------------------------------------------------ - * classDeclaration() - * ------------------------------------------------------------ */ - - virtual int classDeclaration(Node *n) { - return Language::classDeclaration(n); - } - - /* ------------------------------------------------------------ - * classHandler() - * ------------------------------------------------------------ */ - - virtual int classHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - - class_name = symname; - base_class = NULL; - destructor_action = NULL; - - Printf(all_cs_entry, "static const zend_function_entry class_%s_functions[] = {\n", class_name); - - // namespace code to introduce namespaces into wrapper classes. - //if (nameSpace != NULL) - //Printf(s_oinit, "INIT_CLASS_ENTRY(internal_ce, \"%s\\\\%s\", class_%s_functions);\n", nameSpace, class_name, class_name); - //else - Printf(s_oinit, " INIT_CLASS_ENTRY(internal_ce, \"%s%s\", class_%s_functions);\n", prefix, class_name, class_name); - - if (shadow) { - char *rename = GetChar(n, "sym:name"); - - if (!addSymbol(rename, n)) - return SWIG_ERROR; - - /* Deal with inheritance */ - List *baselist = Getattr(n, "bases"); - if (baselist) { - Iterator base = First(baselist); - while (base.item) { - if (!GetFlag(base.item, "feature:ignore")) { - if (!base_class) { - base_class = Getattr(base.item, "sym:name"); - } else { - /* Warn about multiple inheritance for additional base class(es) */ - String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); - String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0); - Swig_warning(WARN_PHP_MULTIPLE_INHERITANCE, input_file, line_number, - "Warning for %s, base %s ignored. Multiple inheritance is not supported in PHP.\n", proxyclassname, baseclassname); - } - } - base = Next(base); - } - } - } - - if (GetFlag(n, "feature:exceptionclass") && Getattr(n, "feature:except")) { - /* PHP requires thrown objects to be instances of or derived from - * Exception, so that really needs to take priority over any - * explicit base class. - */ - if (base_class) { - String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); - Swig_warning(WARN_PHP_MULTIPLE_INHERITANCE, input_file, line_number, - "Warning for %s, base %s ignored. Multiple inheritance is not supported in PHP.\n", proxyclassname, base_class); - } - base_class = NewString("Exception"); - } - - if (!base_class) { - Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name); - } else if (Equal(base_class, "Exception")) { - Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, zend_ce_exception);\n", class_name); - } else if (is_class_wrapped(base_class)) { - Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, SWIG_Php_ce_%s);\n", class_name, base_class); - Setattr(php_parent_class, class_name, base_class); - } else { - Printf(s_oinit, " {\n"); - Printf(s_oinit, " swig_type_info *type_info = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, \"_p_%s\");\n", base_class); - Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, (zend_class_entry*)(type_info ? type_info->clientdata : NULL));\n", class_name); - Printf(s_oinit, " }\n"); - } - - if (Getattr(n, "abstracts") && !GetFlag(n, "feature:notabstract")) { - Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;\n", class_name); - } - if (Getattr(n, "feature:php:allowdynamicproperties")) { - Append(s_oinit, "#ifdef ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES\n"); - Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES;\n", class_name); - Append(s_oinit, "#endif\n"); - } else { - Append(s_oinit, "#ifdef ZEND_ACC_NO_DYNAMIC_PROPERTIES\n"); - Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES;\n", class_name); - Append(s_oinit, "#endif\n"); - } - String *swig_wrapped = swig_wrapped_interface_ce(); - Printv(s_oinit, " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", &", swig_wrapped, ");\n", NIL); - - { - Node *node = NewHash(); - Setattr(node, "type", Getattr(n, "name")); - Setfile(node, Getfile(n)); - Setline(node, Getline(n)); - String *interfaces = Swig_typemap_lookup("phpinterfaces", node, "", 0); - Replaceall(interfaces, " ", ""); - if (interfaces && Len(interfaces) > 0) { - // It seems we need to wait until RINIT time to look up class entries - // for interfaces by name. The downside is that this then happens for - // every request. - // - // Most pre-defined interfaces are accessible via zend_class_entry* - // variables declared in the PHP C API - these we can use at MINIT - // time, so we special case them. This will also be a little faster - // than looking up by name. - Printv(s_header, - "#ifdef __cplusplus\n", - "extern \"C\" {\n", - "#endif\n", - NIL); - - String *r_init_prefix = NewStringEmpty(); - - List *interface_list = Split(interfaces, ',', -1); - int num_interfaces = Len(interface_list); - for (int i = 0; i < num_interfaces; ++i) { - String *interface = Getitem(interface_list, i); - // We generate conditional code in both minit and rinit - then we or the user - // just need to define SWIG_PHP_INTERFACE_xxx_CE (and optionally - // SWIG_PHP_INTERFACE_xxx_HEADER) to handle interface `xxx` at minit-time. - Printv(s_header, - "#ifdef SWIG_PHP_INTERFACE_", interface, "_HEADER\n", - "# include SWIG_PHP_INTERFACE_", interface, "_HEADER\n", - "#endif\n", - NIL); - Printv(s_oinit, - "#ifdef SWIG_PHP_INTERFACE_", interface, "_CE\n", - " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", SWIG_PHP_INTERFACE_", interface, "_CE);\n", - "#endif\n", - NIL); - Printv(r_init_prefix, - "#ifndef SWIG_PHP_INTERFACE_", interface, "_CE\n", - " {\n", - " zend_class_entry *swig_interface_ce = zend_lookup_class(zend_string_init(\"", interface, "\", sizeof(\"", interface, "\") - 1, 0));\n", - " if (swig_interface_ce)\n", - " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", swig_interface_ce);\n", - " else\n", - " zend_throw_exception(zend_ce_error, \"Interface \\\"", interface, "\\\" not found\", 0);\n", - " }\n", - "#endif\n", - NIL); - } - - // Handle interfaces at the start of rinit so that they're added - // before any potential constant objects, etc which might be created - // later in rinit. - Insert(r_init, 0, r_init_prefix); - Delete(r_init_prefix); - - Printv(s_header, - "#ifdef __cplusplus\n", - "}\n", - "#endif\n", - NIL); - } - Delete(interfaces); - } - - Language::classHandler(n); - - static bool emitted_base_object_handlers = false; - if (!emitted_base_object_handlers) { - Printf(s_creation, "static zend_object_handlers Swig_Php_base_object_handlers;\n\n"); - - // Set up a base zend_object_handlers structure which we can use as-is - // for classes without a destructor, and copy as the basis for other - // classes. - Printf(s_oinit, " Swig_Php_base_object_handlers = *zend_get_std_object_handlers();\n"); - Printf(s_oinit, " Swig_Php_base_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n"); - Printf(s_oinit, " Swig_Php_base_object_handlers.clone_obj = NULL;\n"); - emitted_base_object_handlers = true; - } - - Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n", class_name); - - if (Getattr(n, "has_destructor")) { - if (destructor_action ? Equal(destructor_action, "free((char *) arg1);") : !CPlusPlus) { - // We can use a single function if the destructor action calls free() - // (either explicitly or as the default in C-mode) since free() doesn't - // care about the object's type. We currently only check for the exact - // code that Swig_cdestructor_call() emits. - static bool emitted_common_cdestructor = false; - if (!emitted_common_cdestructor) { - Printf(s_creation, "static zend_object_handlers Swig_Php_common_c_object_handlers;\n\n"); - Printf(s_creation, "static void SWIG_Php_common_c_free_obj(zend_object *object) {free(SWIG_Php_free_obj(object));}\n\n"); - Printf(s_creation, "static zend_object *SWIG_Php_common_c_create_object(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &Swig_Php_common_c_object_handlers);}\n"); - - Printf(s_oinit, " Swig_Php_common_c_object_handlers = Swig_Php_base_object_handlers;\n"); - Printf(s_oinit, " Swig_Php_common_c_object_handlers.free_obj = SWIG_Php_common_c_free_obj;\n"); - - emitted_common_cdestructor = true; - } - - Printf(s_oinit, " SWIG_Php_ce_%s->create_object = SWIG_Php_common_c_create_object;\n", class_name); - } else { - Printf(s_creation, "static zend_object_handlers %s_object_handlers;\n", class_name); - Printf(s_creation, "static zend_object *SWIG_Php_create_object_%s(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &%s_object_handlers);}\n", class_name, class_name); - - Printf(s_creation, "static void SWIG_Php_free_obj_%s(zend_object *object) {",class_name); - String *type = Getattr(n, "classtype"); - // Special case handling the delete call generated by - // Swig_cppdestructor_call() and generate simpler code. - if (destructor_action && !Equal(destructor_action, "delete arg1;")) { - Printv(s_creation, "\n" - " ", type, " *arg1 = (" , type, " *)SWIG_Php_free_obj(object);\n" - " if (arg1) {\n" - " ", destructor_action, "\n" - " }\n", NIL); - } else { - Printf(s_creation, "delete (%s *)SWIG_Php_free_obj(object);", type); - } - Printf(s_creation, "}\n\n"); - - Printf(s_oinit, " SWIG_Php_ce_%s->create_object = SWIG_Php_create_object_%s;\n", class_name, class_name); - Printf(s_oinit, " %s_object_handlers = Swig_Php_base_object_handlers;\n", class_name); - Printf(s_oinit, " %s_object_handlers.free_obj = SWIG_Php_free_obj_%s;\n", class_name, class_name); - } - } else { - static bool emitted_destructorless_create_object = false; - if (!emitted_destructorless_create_object) { - emitted_destructorless_create_object = true; - Printf(s_creation, "static zend_object *SWIG_Php_create_object(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &Swig_Php_base_object_handlers);}\n", class_name); - } - - Printf(s_oinit, " SWIG_Php_ce_%s->create_object = SWIG_Php_create_object;\n", class_name); - } - - // If not defined we aren't wrapping any functions which use this type as a - // parameter or return value, in which case we don't need the clientdata - // set. - Printf(s_oinit, "#ifdef SWIGTYPE_p%s\n", SwigType_manglestr(Getattr(n, "classtypeobj"))); - Printf(s_oinit, " SWIG_TypeClientData(SWIGTYPE_p%s,SWIG_Php_ce_%s);\n", SwigType_manglestr(Getattr(n, "classtypeobj")), class_name); - Printf(s_oinit, "#endif\n"); - Printf(s_oinit, "\n"); - - generate_magic_property_methods(n); - Printf(all_cs_entry, " ZEND_FE_END\n};\n\n"); - - class_name = NULL; - base_class = NULL; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * memberfunctionHandler() - * ------------------------------------------------------------ */ - - virtual int memberfunctionHandler(Node *n) { - wrapperType = memberfn; - Language::memberfunctionHandler(n); - wrapperType = standard; - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * membervariableHandler() - * ------------------------------------------------------------ */ - - virtual int membervariableHandler(Node *n) { - if (magic_set == NULL) { - magic_set = NewStringEmpty(); - magic_get = NewStringEmpty(); - magic_isset = NewStringEmpty(); - } - - String *v_name = GetChar(n, "name"); - - Printf(magic_set, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name); - Printf(magic_set, "ZVAL_STRING(&tempZval, \"%s_set\");\n", v_name); - Printf(magic_set, "call_user_function(EG(function_table),ZEND_THIS,&tempZval,return_value,1,&args[1]);\n}\n"); - - Printf(magic_get, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name); - Printf(magic_get, "ZVAL_STRING(&tempZval, \"%s_get\");\n", v_name); - Printf(magic_get, "call_user_function(EG(function_table),ZEND_THIS,&tempZval,return_value,0,NULL);\n}\n"); - - Printf(magic_isset, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name); - Printf(magic_isset, "RETVAL_TRUE;\n}\n"); - - wrapperType = membervar; - Language::membervariableHandler(n); - wrapperType = standard; - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * staticmembervariableHandler() - * ------------------------------------------------------------ */ - - virtual int staticmembervariableHandler(Node *n) { - wrapperType = staticmembervar; - Language::staticmembervariableHandler(n); - wrapperType = standard; - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * staticmemberfunctionHandler() - * ------------------------------------------------------------ */ - - virtual int staticmemberfunctionHandler(Node *n) { - wrapperType = staticmemberfn; - Language::staticmemberfunctionHandler(n); - wrapperType = standard; - - return SWIG_OK; - } - - int abstractConstructorHandler(Node *) { - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constructorHandler() - * ------------------------------------------------------------ */ - - virtual int constructorHandler(Node *n) { - if (Swig_directorclass(n)) { - String *ctype = GetChar(Swig_methodclass(n), "classtype"); - String *sname = GetChar(Swig_methodclass(n), "sym:name"); - String *args = NewStringEmpty(); - ParmList *p = Getattr(n, "parms"); - int i; - - for (i = 0; p; p = nextSibling(p), i++) { - if (i) { - Printf(args, ", "); - } - if (Strcmp(GetChar(p, "type"), SwigType_str(GetChar(p, "type"), 0))) { - SwigType *t = Getattr(p, "type"); - Printf(args, "%s", SwigType_rcaststr(t, 0)); - if (SwigType_isreference(t)) { - Append(args, "*"); - } - } - Printf(args, "arg%d", i+1); - } - - /* director ctor code is specific for each class */ - Delete(director_ctor_code); - director_ctor_code = NewStringEmpty(); - director_prot_ctor_code = NewStringEmpty(); - Printf(director_ctor_code, "if (Z_OBJCE_P(arg0) == SWIG_Php_ce_%s) { /* not subclassed */\n", class_name); - Printf(director_prot_ctor_code, "if (Z_OBJCE_P(arg0) == SWIG_Php_ce_%s) { /* not subclassed */\n", class_name); - Printf(director_ctor_code, " %s = new %s(%s);\n", Swig_cresult_name(), ctype, args); - Printf(director_prot_ctor_code, - " zend_throw_exception(zend_ce_type_error, \"accessing abstract class or protected constructor\", 0);\n" - " return;\n"); - if (i) { - Insert(args, 0, ", "); - } - Printf(director_ctor_code, "} else {\n %s = (%s *)new SwigDirector_%s(arg0%s);\n}\n", Swig_cresult_name(), ctype, sname, args); - Printf(director_prot_ctor_code, "} else {\n %s = (%s *)new SwigDirector_%s(arg0%s);\n}\n", Swig_cresult_name(), ctype, sname, args); - Delete(args); - - wrapperType = directorconstructor; - } else { - wrapperType = constructor; - } - Language::constructorHandler(n); - wrapperType = standard; - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * destructorHandler() - * ------------------------------------------------------------ */ - virtual int destructorHandler(Node *n) { - wrapperType = destructor; - Language::destructorHandler(n); - destructor_action = Getattr(n, "wrap:action"); - wrapperType = standard; - return SWIG_OK; - } - - int classDirectorInit(Node *n) { - String *declaration = Swig_director_declaration(n); - Printf(f_directors_h, "%s\n", declaration); - Printf(f_directors_h, "public:\n"); - Delete(declaration); - return Language::classDirectorInit(n); - } - - int classDirectorEnd(Node *n) { - Printf(f_directors_h, "};\n"); - return Language::classDirectorEnd(n); - } - - int classDirectorConstructor(Node *n) { - Node *parent = Getattr(n, "parentNode"); - String *decl = Getattr(n, "decl"); - String *supername = Swig_class_name(parent); - String *classname = NewStringEmpty(); - Printf(classname, "SwigDirector_%s", supername); - - /* insert self parameter */ - Parm *p; - ParmList *superparms = Getattr(n, "parms"); - ParmList *parms = CopyParmList(superparms); - String *type = NewString("zval"); - SwigType_add_pointer(type); - p = NewParm(type, NewString("self"), n); - set_nextSibling(p, parms); - parms = p; - - if (!Getattr(n, "defaultargs")) { - // There should always be a "self" parameter first. - assert(ParmList_len(parms) > 0); - - /* constructor */ - { - Wrapper *w = NewWrapper(); - String *call; - String *basetype = Getattr(parent, "classtype"); - - String *target = Swig_method_decl(0, decl, classname, parms, 0); - call = Swig_csuperclass_call(0, basetype, superparms); - Printf(w->def, "%s::%s: %s, Swig::Director(self) {", classname, target, call); - Append(w->def, "}"); - Delete(target); - Wrapper_print(w, f_directors); - Delete(call); - DelWrapper(w); - } - - /* constructor header */ - { - String *target = Swig_method_decl(0, decl, classname, parms, 1); - Printf(f_directors_h, " %s;\n", target); - Delete(target); - } - } - return Language::classDirectorConstructor(n); - } - - int classDirectorMethod(Node *n, Node *parent, String *super) { - int is_void = 0; - int is_pointer = 0; - String *decl = Getattr(n, "decl"); - String *returntype = Getattr(n, "type"); - String *name = Getattr(n, "name"); - String *classname = Getattr(parent, "sym:name"); - String *c_classname = Getattr(parent, "name"); - String *symname = Getattr(n, "sym:name"); - String *declaration = NewStringEmpty(); - ParmList *l = Getattr(n, "parms"); - Wrapper *w = NewWrapper(); - String *tm; - String *wrap_args = NewStringEmpty(); - String *value = Getattr(n, "value"); - String *storage = Getattr(n, "storage"); - bool pure_virtual = false; - int status = SWIG_OK; - int idx; - bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; - - if (Cmp(storage, "virtual") == 0) { - if (Cmp(value, "0") == 0) { - pure_virtual = true; - } - } - - /* determine if the method returns a pointer */ - is_pointer = SwigType_ispointer_return(decl); - is_void = (Cmp(returntype, "void") == 0 && !is_pointer); - - /* virtual method definition */ - String *target; - String *pclassname = NewStringf("SwigDirector_%s", classname); - String *qualified_name = NewStringf("%s::%s", pclassname, name); - SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type"); - target = Swig_method_decl(rtype, decl, qualified_name, l, 0); - Printf(w->def, "%s", target); - Delete(qualified_name); - Delete(target); - /* header declaration */ - target = Swig_method_decl(rtype, decl, name, l, 1); - Printf(declaration, " virtual %s", target); - Delete(target); - - // Get any exception classes in the throws typemap - if (Getattr(n, "noexcept")) { - Append(w->def, " noexcept"); - Append(declaration, " noexcept"); - } - ParmList *throw_parm_list = 0; - - if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { - Parm *p; - int gencomma = 0; - - Append(w->def, " throw("); - Append(declaration, " throw("); - - if (throw_parm_list) - Swig_typemap_attach_parms("throws", throw_parm_list, 0); - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - if (gencomma++) { - Append(w->def, ", "); - Append(declaration, ", "); - } - String *str = SwigType_str(Getattr(p, "type"), 0); - Append(w->def, str); - Append(declaration, str); - Delete(str); - } - } - - Append(w->def, ")"); - Append(declaration, ")"); - } - - Append(w->def, " {"); - Append(declaration, ";\n"); - - /* declare method return value - * if the return value is a reference or const reference, a specialized typemap must - * handle it, including declaration of c_result ($result). - */ - if (!is_void && (!ignored_method || pure_virtual)) { - if (!SwigType_isclass(returntype)) { - if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { - String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); - Delete(construct_result); - } else { - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); - } - } else { - String *cres = SwigType_lstr(returntype, "c_result"); - Printf(w->code, "%s;\n", cres); - Delete(cres); - } - } - - if (ignored_method) { - if (!pure_virtual) { - if (!is_void) - Printf(w->code, "return "); - String *super_call = Swig_method_call(super, l); - Printf(w->code, "%s;\n", super_call); - Delete(super_call); - } else { - Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname), - SwigType_namestr(name)); - } - } else { - /* attach typemaps to arguments (C/C++ -> PHP) */ - Swig_director_parms_fixup(l); - - /* remove the wrapper 'w' since it was producing spurious temps */ - Swig_typemap_attach_parms("in", l, 0); - Swig_typemap_attach_parms("directorin", l, w); - Swig_typemap_attach_parms("directorargout", l, w); - - Parm *p; - - /* build argument list and type conversion string */ - idx = 0; - p = l; - while (p) { - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - continue; - } - - String *pname = Getattr(p, "name"); - String *ptype = Getattr(p, "type"); - - if ((tm = Getattr(p, "tmap:directorin")) != 0) { - String *parse = Getattr(p, "tmap:directorin:parse"); - if (!parse) { - String *input = NewStringf("&args[%d]", idx++); - Setattr(p, "emit:directorinput", input); - Replaceall(tm, "$input", input); - Delete(input); - Replaceall(tm, "$owner", "0"); - Printv(wrap_args, tm, "\n", NIL); - } else { - Setattr(p, "emit:directorinput", pname); - Replaceall(tm, "$input", pname); - Replaceall(tm, "$owner", "0"); - if (Len(tm) == 0) - Append(tm, pname); - } - p = Getattr(p, "tmap:directorin:next"); - continue; - } else if (Cmp(ptype, "void")) { - Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, - "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), - SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_NOWRAP; - break; - } - p = nextSibling(p); - } - - if (!idx) { - Printf(w->code, "zval *args = NULL;\n"); - } else { - Printf(w->code, "zval args[%d];\n", idx); - } - // typemap_directorout testcase requires that 0 can be assigned to the - // variable named after the result of Swig_cresult_name(), so that can't - // be a zval - make it a pointer to one instead. - Printf(w->code, "zval swig_zval_result;\n"); - Printf(w->code, "zval * SWIGUNUSED %s = &swig_zval_result;\n", Swig_cresult_name()); - - /* wrap complex arguments to zvals */ - Append(w->code, wrap_args); - - const char *funcname = GetChar(n, "sym:name"); - Append(w->code, "{\n"); - Append(w->code, "#if PHP_MAJOR_VERSION < 8\n"); - Printf(w->code, "zval swig_funcname;\n"); - Printf(w->code, "ZVAL_STRINGL(&swig_funcname, \"%s\", %d);\n", funcname, strlen(funcname)); - Printf(w->code, "call_user_function(EG(function_table), &swig_self, &swig_funcname, &swig_zval_result, %d, args);\n", idx); - Append(w->code, "#else\n"); - Printf(w->code, "zend_string *swig_funcname = zend_string_init(\"%s\", %d, 0);\n", funcname, strlen(funcname)); - Append(w->code, "zend_function *swig_zend_func = zend_std_get_method(&Z_OBJ(swig_self), swig_funcname, NULL);\n"); - Append(w->code, "zend_string_release(swig_funcname);\n"); - Printf(w->code, "if (swig_zend_func) zend_call_known_instance_method(swig_zend_func, Z_OBJ(swig_self), &swig_zval_result, %d, args);\n", idx); - Append(w->code, "#endif\n"); - - /* exception handling */ - tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0); - if (!tm) { - tm = Getattr(n, "feature:director:except"); - if (tm) - tm = Copy(tm); - } - if (!tm || Len(tm) == 0 || Equal(tm, "1")) { - // Skip marshalling the return value as there isn't one. - tm = NewString("if ($error) SWIG_fail;"); - } - - Replaceall(tm, "$error", "EG(exception)"); - Printv(w->code, Str(tm), "\n}\n{\n", NIL); - Delete(tm); - - /* marshal return value from PHP to C/C++ type */ - - String *cleanup = NewStringEmpty(); - String *outarg = NewStringEmpty(); - - idx = 0; - - /* marshal return value */ - if (!is_void) { - tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w); - if (tm != 0) { - Replaceall(tm, "$input", Swig_cresult_name()); - char temp[24]; - sprintf(temp, "%d", idx); - Replaceall(tm, "$argnum", temp); - - /* TODO check this */ - if (Getattr(n, "wrap:disown")) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - Replaceall(tm, "$result", "c_result"); - Printv(w->code, tm, "\n", NIL); - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, - "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0), - SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_ERROR; - } - } - - /* marshal outputs */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:directorargout")) != 0) { - Replaceall(tm, "$result", Swig_cresult_name()); - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NIL); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } - } - - Append(w->code, "}\n"); - - Delete(cleanup); - Delete(outarg); - } - - Append(w->code, "fail: ;\n"); - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { - String *rettype = SwigType_str(returntype, 0); - if (!SwigType_isreference(returntype)) { - Printf(w->code, "return (%s) c_result;\n", rettype); - } else { - Printf(w->code, "return (%s) *c_result;\n", rettype); - } - Delete(rettype); - } - } - Append(w->code, "}\n"); - - // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method - String *inline_extra_method = NewStringEmpty(); - if (dirprot_mode() && !is_public(n) && !pure_virtual) { - Printv(inline_extra_method, declaration, NIL); - String *extra_method_name = NewStringf("%sSwigPublic", name); - Replaceall(inline_extra_method, name, extra_method_name); - Replaceall(inline_extra_method, ";\n", " {\n "); - if (!is_void) - Printf(inline_extra_method, "return "); - String *methodcall = Swig_method_call(super, l); - Printv(inline_extra_method, methodcall, ";\n }\n", NIL); - Delete(methodcall); - Delete(extra_method_name); - } - - /* emit the director method */ - if (status == SWIG_OK) { - if (!Getattr(n, "defaultargs")) { - Replaceall(w->code, "$symname", symname); - Wrapper_print(w, f_directors); - Printv(f_directors_h, declaration, NIL); - Printv(f_directors_h, inline_extra_method, NIL); - } - } - - /* clean up */ - Delete(wrap_args); - Delete(pclassname); - DelWrapper(w); - return status; - } - - int classDirectorDisown(Node *n) { - wrapperType = directordisown; - int result = Language::classDirectorDisown(n); - wrapperType = standard; - return result; - } -}; /* class PHP */ - -static PHP *maininstance = 0; - -List *PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute_name) { - - while (Len(merged_types) <= key) { - Append(merged_types, NewList()); - } - - String *phptype = Getattr(n, attribute_name); - if (!phptype || Len(phptype) == 0) { - // There's no type declaration, so any merged version has no type declaration. - // - // Use a DOH None object as a marker to indicate there's no type - // declaration for this parameter/return value (you can't store NULL as a - // value in a DOH List). - Setitem(merged_types, key, None); - return NULL; - } - - DOH *merge_list = Getitem(merged_types, key); - if (merge_list == None) return NULL; - - List *types = Split(phptype, '|', -1); - String *first_type = Getitem(types, 0); - if (Char(first_type)[0] == '?') { - if (Len(types) > 1) { - Printf(stderr, "warning: Invalid phptype: '%s' (can't use ? and | together)\n", phptype); - } - // Treat `?foo` just like `foo|null`. - Append(types, "null"); - Setitem(types, 0, NewString(Char(first_type) + 1)); - } - - SortList(types, NULL); - String *prev = NULL; - for (Iterator i = First(types); i.item; i = Next(i)) { - if (prev && Equal(prev, i.item)) { - Printf(stderr, "warning: Invalid phptype: '%s' (duplicate entry for '%s')\n", phptype, i.item); - continue; - } - - if (key > 0 && Equal(i.item, "void")) { - // Reject void for parameter type. - Printf(stderr, "warning: Invalid phptype: '%s' ('%s' can't be used as a parameter phptype)\n", phptype, i.item); - continue; - } - - if (Equal(i.item, "SWIGTYPE")) { - String *type = Getattr(n, "type"); - Node *class_node = maininstance->classLookup(type); - if (class_node) { - // FIXME: Prefix classname with a backslash to prevent collisions - // with built-in types? Or are non of those valid anyway and so will - // have been renamed at this point? - Append(merge_list, Getattr(class_node, "sym:name")); - } else { - // SWIG wraps a pointer to a non-object type as an object in a PHP - // class named based on the SWIG-mangled C/C++ type. - // - // FIXME: We should check this is actually a known pointer to - // non-object type so we complain about `phptype="SWIGTYPE"` being - // used for PHP types like `int` or `string` (currently this only - // fails at runtime and the error isn't very helpful). We could - // check the condition - // - // raw_pointer_types && Getattr(raw_pointer_types, SwigType_manglestr(type)) - // - // except that raw_pointer_types may not have been fully filled in when - // we are called. - Append(merge_list, NewStringf("SWIG\\%s", SwigType_manglestr(type))); - } - } else { - Append(merge_list, i.item); - } - prev = i.item; - } - SortList(merge_list, NULL); - return merge_list; -} - -void PHPTypes::merge_type_lists(List *merge_list, List *o_merge_list) { - int i = 0, j = 0; - while (j < Len(o_merge_list)) { - String *candidate = Getitem(o_merge_list, j); - while (i < Len(merge_list)) { - int cmp = Cmp(Getitem(merge_list, i), candidate); - if (cmp == 0) - goto handled; - if (cmp > 0) - break; - ++i; - } - Insert(merge_list, i, candidate); - ++i; -handled: - ++j; - } -} - -void PHPTypes::merge_from(const PHPTypes* o) { - num_required = std::min(num_required, o->num_required); - - if (o->byref) { - if (byref == NULL) { - byref = Copy(o->byref); - } else { - int len = std::min(Len(byref), Len(o->byref)); - // Start at 1 because we only want to merge parameter types, and key 0 is - // the return type. - for (int key = 1; key < len; ++key) { - if (Getitem(byref, key) == None && - Getitem(o->byref, key) != None) { - Setitem(byref, key, ""); - } - } - for (int key = len; key < Len(o->byref); ++key) { - Append(byref, Getitem(o->byref, key)); - } - } - } - - int len = std::min(Len(merged_types), Len(o->merged_types)); - for (int key = 0; key < len; ++key) { - DOH *merge_list = Getitem(merged_types, key); - // None trumps anything else in the merge. - if (merge_list == None) continue; - DOH *o_merge_list = Getitem(o->merged_types, key); - if (o_merge_list == None) { - Setitem(merged_types, key, None); - continue; - } - merge_type_lists(merge_list, o_merge_list); - } - // Copy over any additional entries. - for (int key = len; key < Len(o->merged_types); ++key) { - Append(merged_types, Copy(Getitem(o->merged_types, key))); - } -} - -// Collect non-class pointer types from the type table so we can set up PHP -// classes for them later. -// -// NOTE: it's a function NOT A PHP::METHOD -extern "C" { -static void typetrace(const SwigType *ty, String *mangled, String *clientdata) { - if (maininstance->classLookup(ty) == NULL) { - // a non-class pointer - if (!raw_pointer_types) { - raw_pointer_types = NewHash(); - } - Setattr(raw_pointer_types, mangled, mangled); - } - if (r_prevtracefunc) - (*r_prevtracefunc) (ty, mangled, clientdata); -} -} - -/* ----------------------------------------------------------------------------- - * new_swig_php() - Instantiate module - * ----------------------------------------------------------------------------- */ - -static Language *new_swig_php() { - maininstance = new PHP; - if (!r_prevtracefunc) { - r_prevtracefunc = SwigType_remember_trace(typetrace); - } else { - Printf(stderr, "php Typetrace vector already saved!\n"); - assert(0); - } - return maininstance; -} - -extern "C" Language *swig_php(void) { - return new_swig_php(); -} diff --git a/contrib/tools/swig/Source/Modules/python.cxx b/contrib/tools/swig/Source/Modules/python.cxx deleted file mode 100644 index 63f0c1650d9..00000000000 --- a/contrib/tools/swig/Source/Modules/python.cxx +++ /dev/null @@ -1,5768 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * python.cxx - * - * Python language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" -#include <limits.h> -#include <ctype.h> -#include <errno.h> -#include <stdint.h> -#include "pydoc.h" - -#define PYSHADOW_MEMBER 0x2 -#define WARN_PYTHON_MULTIPLE_INH 405 - -#define PYTHON_INT_MAX (2147483647) -#define PYTHON_INT_MIN (-2147483647-1) - -static String *const_code = 0; -static String *module = 0; -static String *package = 0; -static String *mainmodule = 0; -static String *interface = 0; -static String *global_name = 0; -static int shadow = 1; -static int use_kw = 0; -static int director_method_index = 0; -static int builtin = 0; - -static File *f_begin = 0; -static File *f_runtime = 0; -static File *f_runtime_h = 0; -static File *f_header = 0; -static File *f_wrappers = 0; -static File *f_directors = 0; -static File *f_directors_h = 0; -static File *f_init = 0; -static File *f_shadow_py = 0; -static String *f_shadow = 0; -static String *f_shadow_begin = 0; -static Hash *f_shadow_imports = 0; -static String *f_shadow_after_begin = 0; -static String *f_shadow_stubs = 0; -static Hash *builtin_getset = 0; -static Hash *builtin_closures = 0; -static Hash *class_members = 0; -static File *f_builtins = 0; -static String *builtin_tp_init = 0; -static String *builtin_methods = 0; -static String *builtin_default_unref = 0; -static String *builtin_closures_code = 0; - -static String *methods; -static String *methods_proxydocs; -static String *class_name; -static String *shadow_indent = 0; -static int in_class = 0; -static int no_header_file = 0; -static int max_bases = 0; -static int builtin_bases_needed = 0; - -/* C++ Support + Shadow Classes */ - -static int have_constructor = 0; -static int have_repr = 0; -static bool have_builtin_static_member_method_callback = false; -static bool have_fast_proxy_static_member_method_callback = false; -static String *real_classname; - -/* Thread Support */ -static int threads = 0; -static int nothreads = 0; - -/* Other options */ -static int dirvtable = 0; -static int doxygen = 0; -static int fastunpack = 1; -static int fastproxy = 0; -static int olddefs = 0; -static int castmode = 0; -static int extranative = 0; -static int nortti = 0; -static int relativeimport = 0; -static int flat_static_method = 0; - -/* flags for the make_autodoc function */ -namespace { -enum autodoc_t { - AUTODOC_CLASS, - AUTODOC_CTOR, - AUTODOC_DTOR, - AUTODOC_STATICFUNC, - AUTODOC_FUNC, - AUTODOC_METHOD, - AUTODOC_CONST, - AUTODOC_VAR -}; -} - -static const char *usage1 = "\ -Python Options (available with -python)\n\ - -builtin - Create Python built-in types rather than proxy classes, for better performance\n\ - -castmode - Enable the casting mode, which allows implicit cast between types in Python\n\ - -debug-doxygen-parser - Display doxygen parser module debugging information\n\ - -debug-doxygen-translator - Display doxygen translator module debugging information\n\ - -dirvtable - Generate a pseudo virtual table for directors for faster dispatch\n\ - -doxygen - Convert C++ doxygen comments to pydoc comments in proxy classes\n\ - -extranative - Return extra native wrappers for C++ std containers wherever possible\n\ - -fastproxy - Use fast proxy mechanism for member methods\n\ - -flatstaticmethod - Generate additional flattened Python methods for C++ static methods\n\ - -globals <name> - Set <name> used to access C global variable (default: 'cvar')\n\ - -interface <mod>- Set low-level C/C++ module name to <mod> (default: module name prefixed by '_')\n\ - -keyword - Use keyword arguments\n"; -static const char *usage2 = "\ - -nofastunpack - Use traditional UnpackTuple method to parse the argument functions\n\ - -noh - Don't generate the output header file\n"; -static const char *usage3 = "\ - -noproxy - Don't generate proxy classes\n\ - -nortti - Disable the use of the native C++ RTTI with directors\n\ - -nothreads - Disable thread support for the entire interface\n\ - -olddefs - Keep the old method definitions when using -fastproxy\n\ - -relativeimport - Use relative Python imports\n\ - -threads - Add thread support for all the interface\n\ - -O - Enable the following optimization options:\n\ - -fastdispatch -fastproxy -fvirtual\n\ -\n"; - -static String *getSlot(Node *n = NULL, const char *key = NULL, String *default_slot = NULL) { - static String *zero = NewString("0"); - String *val = n && key && *key ? Getattr(n, key) : NULL; - return val ? val : default_slot ? default_slot : zero; -} - -static void printSlot(File *f, String *slotval, const char *slotname, const char *functype = NULL) { - String *slotval_override = 0; - if (functype && Strcmp(slotval, "0") == 0) - slotval = slotval_override = NewStringf("(%s) %s", functype, slotval); - int len = Len(slotval); - int fieldwidth = len > 41 ? (len > 61 ? 0 : 61 - len) : 41 - len; - Printf(f, " %s,%*s/* %s */\n", slotval, fieldwidth, "", slotname); - Delete(slotval_override); -} - -static String *getClosure(String *functype, String *wrapper, int funpack = 0) { - static const char *functypes[] = { - "unaryfunc", "SWIGPY_UNARYFUNC_CLOSURE", - "destructor", "SWIGPY_DESTRUCTOR_CLOSURE", - "inquiry", "SWIGPY_INQUIRY_CLOSURE", - "getiterfunc", "SWIGPY_GETITERFUNC_CLOSURE", - "binaryfunc", "SWIGPY_BINARYFUNC_CLOSURE", - "ternaryfunc", "SWIGPY_TERNARYFUNC_CLOSURE", - "ternarycallfunc", "SWIGPY_TERNARYCALLFUNC_CLOSURE", - "lenfunc", "SWIGPY_LENFUNC_CLOSURE", - "ssizeargfunc", "SWIGPY_SSIZEARGFUNC_CLOSURE", - "ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE", - "ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE", - "ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE", - "objobjproc", "SWIGPY_OBJOBJPROC_CLOSURE", - "objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE", - "reprfunc", "SWIGPY_REPRFUNC_CLOSURE", - "hashfunc", "SWIGPY_HASHFUNC_CLOSURE", - "iternextfunc", "SWIGPY_ITERNEXTFUNC_CLOSURE", - NULL - }; - - static const char *funpack_functypes[] = { - "unaryfunc", "SWIGPY_UNARYFUNC_CLOSURE", - "destructor", "SWIGPY_DESTRUCTOR_CLOSURE", - "inquiry", "SWIGPY_INQUIRY_CLOSURE", - "getiterfunc", "SWIGPY_GETITERFUNC_CLOSURE", - "ternaryfunc", "SWIGPY_TERNARYFUNC_CLOSURE", - "ternarycallfunc", "SWIGPY_TERNARYCALLFUNC_CLOSURE", - "lenfunc", "SWIGPY_LENFUNC_CLOSURE", - "ssizeargfunc", "SWIGPY_FUNPACK_SSIZEARGFUNC_CLOSURE", - "ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE", - "ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE", - "ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE", - "objobjproc", "SWIGPY_FUNPACK_OBJOBJPROC_CLOSURE", - "objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE", - "reprfunc", "SWIGPY_REPRFUNC_CLOSURE", - "hashfunc", "SWIGPY_HASHFUNC_CLOSURE", - "iternextfunc", "SWIGPY_ITERNEXTFUNC_CLOSURE", - NULL - }; - - if (!functype) - return NULL; - char *c = Char(functype); - int i; - if (funpack) { - for (i = 0; funpack_functypes[i] != NULL; i += 2) { - if (!strcmp(c, funpack_functypes[i])) - return NewStringf("%s(%s)", funpack_functypes[i + 1], wrapper); - } - } else { - for (i = 0; functypes[i] != NULL; i += 2) { - if (!strcmp(c, functypes[i])) - return NewStringf("%s(%s)", functypes[i + 1], wrapper); - } - } - return NULL; -} - -class PYTHON:public Language { -public: - PYTHON() { - /* Add code to manage protected constructors and directors */ - director_prot_ctor_code = NewString(""); - Printv(director_prot_ctor_code, - "if ( $comparison ) { /* subclassed */\n", - " $director_new \n", - "} else {\n", " SWIG_SetErrorMsg(PyExc_RuntimeError,\"accessing abstract class or protected constructor\"); \n", " SWIG_fail;\n", "}\n", NIL); - director_multiple_inheritance = 1; - director_language = 1; - } - - ~PYTHON() { - delete doxygenTranslator; - } - - /* ------------------------------------------------------------ - * Thread Implementation - * ------------------------------------------------------------ */ - int threads_enable(Node *n) const { - return threads && !GetFlagAttr(n, "feature:nothread"); - } - - int initialize_threads(String *f_init) { - if (!threads) { - return SWIG_OK; - } - Printf(f_init, "\n"); - Printf(f_init, "/* Initialize threading */\n"); - Printf(f_init, "SWIG_PYTHON_INITIALIZE_THREADS;\n"); - - return SWIG_OK; - } - - virtual void thread_begin_block(Node *n, String *f) { - if (!GetFlag(n, "feature:nothreadblock")) { - String *bb = Getattr(n, "feature:threadbeginblock"); - if (bb) { - Append(f, bb); - } else { - Append(f, "SWIG_PYTHON_THREAD_BEGIN_BLOCK;\n"); - } - } - } - - virtual void thread_end_block(Node *n, String *f) { - if (!GetFlag(n, "feature:nothreadblock")) { - String *eb = Getattr(n, "feature:threadendblock"); - if (eb) { - Append(f, eb); - } else { - Append(f, "SWIG_PYTHON_THREAD_END_BLOCK;\n"); - } - } - } - - virtual void thread_begin_allow(Node *n, String *f) { - if (!GetFlag(n, "feature:nothreadallow")) { - String *bb = Getattr(n, "feature:threadbeginallow"); - Append(f, "{\n"); - if (bb) { - Append(f, bb); - } else { - Append(f, "SWIG_PYTHON_THREAD_BEGIN_ALLOW;\n"); - } - } - } - - virtual void thread_end_allow(Node *n, String *f) { - if (!GetFlag(n, "feature:nothreadallow")) { - String *eb = Getattr(n, "feature:threadendallow"); - Append(f, "\n"); - if (eb) { - Append(f, eb); - } else { - Append(f, "SWIG_PYTHON_THREAD_END_ALLOW;"); - } - Append(f, "\n}"); - } - } - - - /* ------------------------------------------------------------ - * main() - * ------------------------------------------------------------ */ - - virtual void main(int argc, char *argv[]) { - - SWIG_library_directory("python"); - - int doxygen_translator_flags = 0; - - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-interface") == 0) { - if (argv[i + 1]) { - interface = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-globals") == 0) { - if (argv[i + 1]) { - global_name = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) { - shadow = 1; - Swig_mark_arg(i); - } else if ((strcmp(argv[i], "-noproxy") == 0)) { - shadow = 0; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-keyword") == 0) { - use_kw = 1; - SWIG_cparse_set_compact_default_args(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nortti") == 0) { - nortti = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-threads") == 0) { - threads = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nothreads") == 0) { - /* Turn off thread support mode */ - nothreads = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-dirvtable") == 0) { - dirvtable = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-doxygen") == 0) { - doxygen = 1; - scan_doxygen_comments = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-debug-doxygen-translator") == 0) { - doxygen_translator_flags |= DoxygenTranslator::debug_translator; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-debug-doxygen-parser") == 0) { - doxygen_translator_flags |= DoxygenTranslator::debug_parser; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nofastunpack") == 0) { - fastunpack = 0; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-fastproxy") == 0) { - fastproxy = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-olddefs") == 0) { - olddefs = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-castmode") == 0) { - castmode = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-extranative") == 0) { - extranative = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-flatstaticmethod") == 0) { - flat_static_method = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-noh") == 0) { - no_header_file = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-newvwm") == 0) { - /* Turn on new value wrapper mode */ - /* Undocumented option, did have -help text: New value wrapper mode, use only when everything else fails */ - Swig_value_wrapper_mode(1); - no_header_file = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-O") == 0) { - fastproxy = 1; - Wrapper_fast_dispatch_mode_set(1); - Wrapper_virtual_elimination_mode_set(1); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-help") == 0) { - fputs(usage1, stdout); - fputs(usage2, stdout); - fputs(usage3, stdout); - } else if (strcmp(argv[i], "-builtin") == 0) { - builtin = 1; - Preprocessor_define("SWIGPYTHON_BUILTIN", 0); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-relativeimport") == 0) { - relativeimport = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-cppcast") == 0 || - strcmp(argv[i], "-fastinit") == 0 || - strcmp(argv[i], "-fastquery") == 0 || - strcmp(argv[i], "-fastunpack") == 0 || - strcmp(argv[i], "-modern") == 0 || - strcmp(argv[i], "-modernargs") == 0 || - strcmp(argv[i], "-noproxydel") == 0 || - strcmp(argv[i], "-safecstrings") == 0) { - Printf(stderr, "Deprecated command line option: %s. Ignored, this option is now always on.\n", argv[i]); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-py3") == 0) { - Printf(stderr, "Deprecated command line option: %s. Ignored, this option is no longer supported.\n", argv[i]); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-aliasobj0") == 0 || - strcmp(argv[i], "-buildnone") == 0 || - strcmp(argv[i], "-classic") == 0 || - strcmp(argv[i], "-classptr") == 0 || - strcmp(argv[i], "-new_repr") == 0 || - strcmp(argv[i], "-new_vwm") == 0 || - strcmp(argv[i], "-newrepr") == 0 || - strcmp(argv[i], "-noaliasobj0") == 0 || - strcmp(argv[i], "-nobuildnone") == 0 || - strcmp(argv[i], "-nocastmode") == 0 || - strcmp(argv[i], "-nocppcast") == 0 || - strcmp(argv[i], "-nodirvtable") == 0 || - strcmp(argv[i], "-noextranative") == 0 || - strcmp(argv[i], "-nofastinit") == 0 || - strcmp(argv[i], "-nofastproxy") == 0 || - strcmp(argv[i], "-nofastquery") == 0 || - strcmp(argv[i], "-nomodern") == 0 || - strcmp(argv[i], "-nomodernargs") == 0 || - strcmp(argv[i], "-noolddefs") == 0 || - strcmp(argv[i], "-nooutputtuple") == 0 || - strcmp(argv[i], "-noproxyimport") == 0 || - strcmp(argv[i], "-nosafecstrings") == 0 || - strcmp(argv[i], "-old_repr") == 0 || - strcmp(argv[i], "-oldrepr") == 0 || - strcmp(argv[i], "-outputtuple") == 0 || - strcmp(argv[i], "-proxydel") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is no longer available.\n", argv[i]); - Swig_mark_arg(i); - Exit(EXIT_FAILURE); - } - - } - } - - if (builtin && !shadow) { - Printf(stderr, "Incompatible options -builtin and -noproxy specified.\n"); - Exit(EXIT_FAILURE); - } - - if (fastproxy) { - Preprocessor_define("SWIGPYTHON_FASTPROXY", 0); - } - - if (doxygen) - doxygenTranslator = new PyDocConverter(doxygen_translator_flags); - - if (!global_name) - global_name = NewString("cvar"); - Preprocessor_define("SWIGPYTHON 1", 0); - SWIG_typemap_lang("python"); - SWIG_config_file("python.swg"); - allow_overloading(); - } - - - /* ------------------------------------------------------------ - * top() - * ------------------------------------------------------------ */ - - virtual int top(Node *n) { - /* check if directors are enabled for this module. note: this - * is a "master" switch, without which no director code will be - * emitted. %feature("director") statements are also required - * to enable directors for individual classes or methods. - * - * use %module(directors="1") modulename at the start of the - * interface file to enable director generation. - */ - String *mod_docstring = NULL; - String *moduleimport = NULL; - { - Node *mod = Getattr(n, "module"); - if (mod) { - Node *options = Getattr(mod, "options"); - if (options) { - int dirprot = 0; - if (Getattr(options, "dirprot")) { - dirprot = 1; - } - if (Getattr(options, "nodirprot")) { - dirprot = 0; - } - if (Getattr(options, "directors")) { - allow_directors(); - if (dirprot) - allow_dirprot(); - } - if (Getattr(options, "threads")) { - threads = 1; - } - if (Getattr(options, "castmode")) { - castmode = 1; - } - if (Getattr(options, "nocastmode")) { - Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nocastmode"); - Exit(EXIT_FAILURE); - } - if (Getattr(options, "extranative")) { - extranative = 1; - } - if (Getattr(options, "noextranative")) { - Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "noextranative"); - Exit(EXIT_FAILURE); - } - if (Getattr(options, "outputtuple")) { - Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "outputtuple"); - Exit(EXIT_FAILURE); - } - if (Getattr(options, "nooutputtuple")) { - Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nooutputtuple"); - Exit(EXIT_FAILURE); - } - mod_docstring = Getattr(options, "docstring"); - package = Getattr(options, "package"); - moduleimport = Getattr(options, "moduleimport"); - } - } - } - - /* Set comparison with none for ConstructorToFunction */ - setSubclassInstanceCheck(NewString("$arg != Py_None")); - - /* Initialize all of the output files */ - String *outfile = Getattr(n, "outfile"); - String *outfile_h = !no_header_file ? Getattr(n, "outfile_h") : 0; - - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - f_wrappers = NewString(""); - f_directors_h = NewString(""); - f_directors = NewString(""); - builtin_getset = NewHash(); - builtin_closures = NewHash(); - builtin_closures_code = NewString(""); - class_members = NewHash(); - builtin_methods = NewString(""); - builtin_default_unref = NewString("delete $self;"); - - if (builtin) { - f_builtins = NewString(""); - } - - if (directorsEnabled()) { - if (!no_header_file) { - f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); - if (!f_runtime_h) { - FileErrorDisplay(outfile_h); - Exit(EXIT_FAILURE); - } - } else { - f_runtime_h = f_runtime; - } - } - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", f_init); - Swig_register_filebyname("director", f_directors); - Swig_register_filebyname("director_h", f_directors_h); - - const_code = NewString(""); - methods = NewString(""); - methods_proxydocs = NewString(""); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "PYTHON"); - - if (directorsEnabled()) { - Printf(f_runtime, "#define SWIG_DIRECTORS\n"); - } - - if (nothreads) { - Printf(f_runtime, "#define SWIG_PYTHON_NO_THREADS\n"); - } else if (threads) { - Printf(f_runtime, "#define SWIG_PYTHON_THREADS\n"); - } - - if (!dirvtable) { - Printf(f_runtime, "#define SWIG_PYTHON_DIRECTOR_NO_VTABLE\n"); - } - - if (nortti) { - Printf(f_runtime, "#ifndef SWIG_DIRECTOR_NORTTI\n"); - Printf(f_runtime, "#define SWIG_DIRECTOR_NORTTI\n"); - Printf(f_runtime, "#endif\n"); - } - - if (castmode) { - Printf(f_runtime, "#define SWIG_CASTRANK_MODE\n"); - Printf(f_runtime, "#define SWIG_PYTHON_CAST_MODE\n"); - } - - if (extranative) { - Printf(f_runtime, "#define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS\n"); - } - - if (builtin) { - Printf(f_runtime, "#define SWIGPYTHON_BUILTIN\n"); - } - - if (fastproxy) { - Printf(f_runtime, "#define SWIGPYTHON_FASTPROXY\n"); - } - - Printf(f_runtime, "\n"); - - Printf(f_header, "#ifdef SWIG_TypeQuery\n"); - Printf(f_header, "# undef SWIG_TypeQuery\n"); - Printf(f_header, "#endif\n"); - Printf(f_header, "#define SWIG_TypeQuery SWIG_Python_TypeQuery\n"); - - - /* Set module name */ - module = Copy(Getattr(n, "name")); - mainmodule = Getattr(n, "name"); - - if (directorsEnabled()) { - Swig_banner(f_directors_h); - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module); - Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module); - if (dirprot_mode()) { - Printf(f_directors_h, "#include <map>\n"); - Printf(f_directors_h, "#include <string>\n\n"); - } - - Printf(f_directors, "\n\n"); - Printf(f_directors, "/* ---------------------------------------------------\n"); - Printf(f_directors, " * C++ director class methods\n"); - Printf(f_directors, " * --------------------------------------------------- */\n\n"); - if (outfile_h) { - String *filename = Swig_file_filename(outfile_h); - Printf(f_directors, "#include \"%s\"\n\n", filename); - Delete(filename); - } - } - - /* If shadow classing is enabled, we're going to change the module name to "_module" */ - String *default_import_code = NewString(""); - if (shadow) { - String *filen = NewStringf("%s%s.py", SWIG_output_directory(), Char(module)); - // If we don't have an interface then change the module name X to _X - if (interface) - module = interface; - else - Insert(module, 0, "_"); - if ((f_shadow_py = NewFile(filen, "w", SWIG_output_files())) == 0) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - Delete(filen); - filen = NULL; - - f_shadow = NewString(""); - f_shadow_begin = NewString(""); - f_shadow_imports = NewHash(); - f_shadow_after_begin = NewString(""); - f_shadow_stubs = NewString(""); - - Swig_register_filebyname("shadow", f_shadow); - Swig_register_filebyname("python", f_shadow); - - if (!builtin) { - /* Import the low-level C/C++ module. This should be a relative import, - * since the shadow module may also have been imported by a relative - * import, and there is thus no guarantee that the low-level C/C++ module is on - * sys.path. Relative imports must be explicitly specified from 2.6.0 - * onwards (implicit relative imports raised a DeprecationWarning in 2.6, - * and fail in 2.7 onwards). - * - * First check for __package__ which is available from 2.6 onwards, see PEP366. - * Next try determine the shadow wrapper's package based on the __name__ it - * was given by the importer that loaded it. - * If the module is in a package, load the low-level C/C++ module from the - * same package, otherwise load it as a global module. - */ - Printv(default_import_code, "# Import the low-level C/C++ module\n", NULL); - Printv(default_import_code, "if __package__ or \".\" in __name__:\n", NULL); - Printv(default_import_code, tab4, "from . import ", module, "\n", NULL); - Printv(default_import_code, "else:\n", NULL); - Printv(default_import_code, tab4, "import ", module, "\n", NULL); - } else { - Printv(default_import_code, "# Pull in all the attributes from the low-level C/C++ module\n", NULL); - Printv(default_import_code, "if __package__ or \".\" in __name__:\n", NULL); - Printv(default_import_code, tab4, "from .", module, " import *\n", NULL); - Printv(default_import_code, "else:\n", NULL); - Printv(default_import_code, tab4, "from ", module, " import *\n", NULL); - } - - if (!builtin) { - /* Need builtins to qualify names like Exception that might also be - defined in this module (try both Python 3 and Python 2 names) */ - Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL); - } - - if (!builtin && fastproxy) { - Printf(f_shadow, "\n"); - Printf(f_shadow, "_swig_new_instance_method = %s.SWIG_PyInstanceMethod_New\n", module); - Printf(f_shadow, "_swig_new_static_method = %s.SWIG_PyStaticMethod_New\n", module); - } - - if (!builtin) { - Printv(f_shadow, "\n", - "def _swig_repr(self):\n", - tab4, "try:\n", - tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n", - tab4, "except __builtin__.Exception:\n", - tab4, tab4, "strthis = \"\"\n", - tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL); - - Printv(f_shadow, "\n", - "def _swig_setattr_nondynamic_instance_variable(set):\n", - tab4, "def set_instance_attr(self, name, value):\n", - tab4, tab4, "if name == \"this\":\n", - tab4, tab4, tab4, "set(self, name, value)\n", - tab4, tab4, "elif name == \"thisown\":\n", - tab4, tab4, tab4, "self.this.own(value)\n", - tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n", - tab4, tab4, tab4, "set(self, name, value)\n", - tab4, tab4, "else:\n", - tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n", - tab4, "return set_instance_attr\n\n", NIL); - - Printv(f_shadow, "\n", - "def _swig_setattr_nondynamic_class_variable(set):\n", - tab4, "def set_class_attr(cls, name, value):\n", - tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n", - tab4, tab4, tab4, "set(cls, name, value)\n", - tab4, tab4, "else:\n", - tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n", - tab4, "return set_class_attr\n\n", NIL); - - Printv(f_shadow, "\n", - "def _swig_add_metaclass(metaclass):\n", - tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n", - tab4, "def wrapper(cls):\n", - tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n", - tab4, "return wrapper\n\n", NIL); - - Printv(f_shadow, "\n", - "class _SwigNonDynamicMeta(type):\n", - tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n", - tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n", - "\n", NIL); - - Printv(f_shadow, "\n", NIL); - - if (directorsEnabled()) - Printv(f_shadow, "import weakref\n\n", NIL); - } - } - // Include some information in the code - Printf(f_header, "\n/*-----------------------------------------------\n @(target):= %s.so\n\ - ------------------------------------------------*/\n", module); - - Printf(f_header, "#if PY_VERSION_HEX >= 0x03000000\n"); - Printf(f_header, "# define SWIG_init PyInit_%s\n\n", module); - Printf(f_header, "#else\n"); - Printf(f_header, "# define SWIG_init init%s\n\n", module); - Printf(f_header, "#endif\n"); - Printf(f_header, "#define SWIG_name \"%s\"\n", module); - - Printf(f_wrappers, "#ifdef __cplusplus\n"); - Printf(f_wrappers, "extern \"C\" {\n"); - Printf(f_wrappers, "#endif\n"); - Append(const_code, "static swig_const_info swig_const_table[] = {\n"); - Append(methods, "static PyMethodDef SwigMethods[] = {\n"); - Append(methods_proxydocs, "static PyMethodDef SwigMethods_proxydocs[] = {\n"); - - /* the method exported for replacement of new.instancemethod in Python 3 */ - add_pyinstancemethod_new(); - add_pystaticmethod_new(); - - if (builtin) { - SwigType *s = NewString("SwigPyObject"); - SwigType_add_pointer(s); - SwigType_remember(s); - Delete(s); - } - - /* emit code */ - Language::top(n); - - if (directorsEnabled()) { - // Insert director runtime into the f_runtime file (make it occur before %header section) - Swig_insert_file("director_common.swg", f_runtime); - Swig_insert_file("director.swg", f_runtime); - } - - /* Close language module */ - Append(methods, "\t { NULL, NULL, 0, NULL }\n"); - Append(methods, "};\n"); - Printf(f_wrappers, "%s\n", methods); - Append(methods_proxydocs, "\t { NULL, NULL, 0, NULL }\n"); - Append(methods_proxydocs, "};\n"); - if ((fastproxy && !builtin) || have_fast_proxy_static_member_method_callback) - Printf(f_wrappers, "%s\n", methods_proxydocs); - - if (builtin) { - Dump(f_builtins, f_wrappers); - } - - SwigType_emit_type_table(f_runtime, f_wrappers); - - Append(const_code, "{0, 0, 0, 0.0, 0, 0}};\n"); - Printf(f_wrappers, "%s\n", const_code); - - if (have_fast_proxy_static_member_method_callback) - Printf(f_init, " SWIG_Python_FixMethods(SwigMethods_proxydocs, swig_const_table, swig_types, swig_type_initial);\n\n"); - - initialize_threads(f_init); - - Printf(f_init, "#if PY_VERSION_HEX >= 0x03000000\n"); - Printf(f_init, " return m;\n"); - Printf(f_init, "#else\n"); - Printf(f_init, " return;\n"); - Printf(f_init, "#endif\n"); - Printf(f_init, "}\n"); - - Printf(f_wrappers, "#ifdef __cplusplus\n"); - Printf(f_wrappers, "}\n"); - Printf(f_wrappers, "#endif\n"); - - if (shadow) { - Swig_banner_target_lang(f_shadow_py, "#"); - - if (mod_docstring) { - if (Len(mod_docstring)) { - const char *triple_double = "\"\"\""; - // follow PEP257 rules: https://www.python.org/dev/peps/pep-0257/ - // reported by pep257: https://github.com/GreenSteam/pep257 - bool multi_line_ds = Strchr(mod_docstring, '\n') != 0; - Printv(f_shadow_py, "\n", triple_double, multi_line_ds ? "\n":"", mod_docstring, multi_line_ds ? "\n":"", triple_double, "\n", NIL); - } - Delete(mod_docstring); - mod_docstring = NULL; - } - - if (Len(f_shadow_begin) > 0) - Printv(f_shadow_py, "\n", f_shadow_begin, "\n", NIL); - - Printv(f_shadow_py, "\nfrom sys import version_info as _swig_python_version_info\n", NULL); - - if (Len(f_shadow_after_begin) > 0) - Printv(f_shadow_py, f_shadow_after_begin, "\n", NIL); - - if (moduleimport) { - Replaceall(moduleimport, "$module", module); - Printv(f_shadow_py, moduleimport, "\n", NIL); - } else { - Printv(f_shadow_py, default_import_code, NIL); - } - - if (Len(f_shadow) > 0) - Printv(f_shadow_py, "\n", f_shadow, "\n", NIL); - if (Len(f_shadow_stubs) > 0) - Printv(f_shadow_py, f_shadow_stubs, "\n", NIL); - Delete(f_shadow_py); - } - - /* Close all of the files */ - Dump(f_runtime, f_begin); - Dump(f_header, f_begin); - - if (directorsEnabled()) { - Dump(f_directors_h, f_runtime_h); - Printf(f_runtime_h, "\n"); - Printf(f_runtime_h, "#endif\n"); - if (f_runtime_h != f_begin) - Delete(f_runtime_h); - Dump(f_directors, f_begin); - } - - Dump(f_wrappers, f_begin); - if (builtin && builtin_bases_needed) - Printf(f_begin, "static PyTypeObject *builtin_bases[%d];\n\n", max_bases + 2); - Wrapper_pretty_print(f_init, f_begin); - - Delete(default_import_code); - Delete(f_shadow_after_begin); - Delete(f_shadow_imports); - Delete(f_shadow_begin); - Delete(f_shadow); - Delete(f_header); - Delete(f_wrappers); - Delete(f_builtins); - Delete(f_init); - Delete(f_directors); - Delete(f_directors_h); - Delete(f_runtime); - Delete(f_begin); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * Emit the wrapper for PyInstanceMethod_New to MethodDef array. - * This wrapper is used to implement -fastproxy, - * as a replacement of new.instancemethod in Python 3. - * ------------------------------------------------------------ */ - int add_pyinstancemethod_new() { - if (!builtin && fastproxy) { - String *name = NewString("SWIG_PyInstanceMethod_New"); - String *line = NewString(""); - Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name); - Append(methods, line); - Append(methods_proxydocs, line); - Delete(line); - Delete(name); - } - return 0; - } - - /* ------------------------------------------------------------ - * Emit the wrapper for PyStaticMethod_New to MethodDef array. - * This wrapper is used to ensure the correct documentation is - * generated for static methods when using -fastproxy - * ------------------------------------------------------------ */ - int add_pystaticmethod_new() { - if (!builtin && fastproxy) { - String *name = NewString("SWIG_PyStaticMethod_New"); - String *line = NewString(""); - Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name); - Append(methods, line); - Append(methods_proxydocs, line); - Delete(line); - Delete(name); - } - return 0; - } - - /* ------------------------------------------------------------ - * subpkg_tail() - * - * Return the name of 'other' package relative to 'base'. - * - * 1. If 'other' is a sub-package of 'base', returns the 'other' relative to - * 'base'. - * 2. If 'other' and 'base' are equal, returns empty string "". - * 3. In any other case, NULL pointer is returned. - * - * The 'base' and 'other' are expected to be fully qualified names. - * - * NOTE: none of 'base' nor 'other' can be null. - * - * Examples: - * - * # base other tail - * -- ---- ----- ---- - * 1 "Foo" "Foo.Bar" -> "Bar" - * 2 "Foo" "Foo." -> "" - * 3 "Foo" "FooB.ar" -> NULL - * 4 "Foo.Bar" "Foo.Bar" -> "" - * 5 "Foo.Bar" "Foo" -> NULL - * 6 "Foo.Bar" "Foo.Gez" -> NULL - * - * NOTE: the example #2 is actually a syntax error (at input). I believe - * swig parser prevents us from this case happening here. - * ------------------------------------------------------------ */ - - static String *subpkg_tail(const String *base, const String *other) { - int baselen = Len(base); - int otherlen = Len(other); - - if (Strncmp(other, base, baselen) == 0) { - if ((baselen < otherlen) && (Char(other))[baselen] == '.') { - return NewString((Char(other)) + baselen + 1); - } else if (baselen == otherlen) { - return NewString(""); - } else { - return 0; - } - } else { - return 0; - } - } - - /* ------------------------------------------------------------ - * abs_import_directive_string() - * - * Return a string containing python code to import module. - * - * pkg package name or the module being imported - * mod module name of the module being imported - * pfx optional prefix to module name - * - * NOTE: keep this function consistent with abs_import_name_string(). - * ------------------------------------------------------------ */ - - static String *abs_import_directive_string(const String *pkg, const String *mod, const char *pfx = "") { - String *out = NewString(""); - - if (pkg && *Char(pkg)) { - Printf(out, "import %s.%s%s\n", pkg, pfx, mod); - } else { - Printf(out, "import %s%s\n", pfx, mod); - } - return out; - } - - /* ------------------------------------------------------------ - * rel_import_directive_string() - * - * Return a string containing python code to import module that - * is potentially within a package. - * - * mainpkg package name of the module which imports the other module - * pkg package name or the module being imported - * mod module name of the module being imported - * pfx optional prefix to module name - * - * NOTE: keep this function consistent with rel_import_name_string(). - * ------------------------------------------------------------ */ - - static String *rel_import_directive_string(const String *mainpkg, const String *pkg, const String *mod, const char *pfx = "") { - - /* NOTE: things are not so trivial. This is what we do here (by examples): - * - * 0. To import module 'foo', which is not in any package, we do absolute - * import: - * - * import foo - * - * 1. To import 'pkg1.pkg2.foo', when mainpkg != "pkg1" and - * mainpkg != "pkg1.pkg2" or when mainpkg is not given we do absolute - * import: - * - * import pkg1.pkg2.foo - * - * 2. To import module pkg1.foo, when mainpkg == "pkg1", we do: - * - * - for py3 = 0: - * - * import foo - * - * - for py3 = 1: - * - * from . import foo - * - * 3. To import "pkg1.pkg2.pkg3.foo", when mainpkg = "pkg1", we do: - * - * - for py3 == 0: - * - * import pkg2.pkg3.foo - * - * - for py3 == 1: - * - * from . import pkg2 # [1] - * import pkg1.pkg2.pkg3.foo - * - * NOTE: [1] is necessary for pkg2.foo to be present in the importing module - */ - - String *apkg = 0; // absolute (FQDN) package name of pkg - String *rpkg = 0; // relative package name - int py3_rlen1 = 0; // length of 1st level sub-package name, used by py3 - String *out = NewString(""); - - if (pkg && *Char(pkg)) { - if (mainpkg) { - String *tail = subpkg_tail(mainpkg, pkg); - if (tail) { - if (*Char(tail)) { - rpkg = NewString(tail); - const char *py3_end1 = Strchr(rpkg, '.'); - if (!py3_end1) - py3_end1 = (Char(rpkg)) + Len(rpkg); - py3_rlen1 = (int)(py3_end1 - Char(rpkg)); - } else { - rpkg = NewString(""); - } - Delete(tail); - } else { - apkg = NewString(pkg); - } - } else { - apkg = NewString(pkg); - } - } else { - apkg = NewString(""); - } - - if (apkg) { - Printf(out, "import %s%s%s%s\n", apkg, *Char(apkg) ? "." : "", pfx, mod); - Delete(apkg); - } else { - if (py3_rlen1) - Printf(out, "from . import %.*s\n", py3_rlen1, rpkg); - Printf(out, "from .%s import %s%s\n", rpkg, pfx, mod); - Delete(rpkg); - } - return out; - } - - /* ------------------------------------------------------------ - * import_directive_string() - * ------------------------------------------------------------ */ - - static String *import_directive_string(const String *mainpkg, const String *pkg, const String *mod, const char *pfx = "") { - if (!relativeimport) { - return abs_import_directive_string(pkg, mod, pfx); - } else { - return rel_import_directive_string(mainpkg, pkg, mod, pfx); - } - } - - /* ------------------------------------------------------------ - * abs_import_name_string() - * - * Return a string with the name of a symbol (perhaps imported - * from external module by absolute import directive). - * - * mainpkg package name of current module - * mainmod module name of current module - * pkg package name of (perhaps other) module - * mod module name of (perhaps other) module - * sym symbol name - * - * NOTE: mainmod, mod, and sym can't be NULL. - * NOTE: keep this function consistent with abs_import_directive_string() - * ------------------------------------------------------------ */ - - static String *abs_import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) { - String *out = NewString(""); - if (pkg && *Char(pkg)) { - if (mainpkg && *Char(mainpkg)) { - if (Strcmp(mainpkg,pkg) != 0 || Strcmp(mainmod, mod) != 0) { - Printf(out, "%s.%s.", pkg, mod); - } - } else { - Printf(out, "%s.%s.", pkg, mod); - } - } else if ((mainpkg && *Char(mainpkg)) || Strcmp(mainmod, mod) != 0) { - Printf(out, "%s.", mod); - } - Append(out, sym); - return out; - } - - /* ------------------------------------------------------------ - * rel_import_name_string() - * - * Return a string with the name of a symbol (perhaps imported - * from external module by relative import directive). - * - * mainpkg package name of current module - * mainmod module name of current module - * pkg package name of (perhaps other) module - * mod module name of (perhaps other) module - * sym symbol name - * - * NOTE: mainmod, mod, and sym can't be NULL. - * NOTE: keep this function consistent with rel_import_directive_string() - * ------------------------------------------------------------ */ - - static String *rel_import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) { - String *out = NewString(""); - if (pkg && *Char(pkg)) { - String *tail = 0; - if (mainpkg) - tail = subpkg_tail(mainpkg, pkg); - if (!tail) - tail = NewString(pkg); - if (*Char(tail)) { - Printf(out, "%s.%s.", tail, mod); - } else if (Strcmp(mainmod, mod) != 0) { - Printf(out, "%s.", mod); - } - Delete(tail); - } else if ((mainpkg && *Char(mainpkg)) || Strcmp(mainmod, mod) != 0) { - Printf(out, "%s.", mod); - } - Append(out, sym); - return out; - } - - /* ------------------------------------------------------------ - * import_name_string() - * ------------------------------------------------------------ */ - - static String *import_name_string(const String *mainpkg, const String *mainmod, const String *pkg, const String *mod, const String *sym) { - if (!relativeimport) { - return abs_import_name_string(mainpkg,mainmod,pkg,mod,sym); - } else { - return rel_import_name_string(mainpkg,mainmod,pkg,mod,sym); - } - } - - /* ------------------------------------------------------------ - * importDirective() - * ------------------------------------------------------------ */ - - virtual int importDirective(Node *n) { - if (shadow) { - String *modname = Getattr(n, "module"); - - if (modname) { - // Find the module node for this imported module. It should be the - // first child but search just in case. - Node *mod = firstChild(n); - while (mod && Strcmp(nodeType(mod), "module") != 0) - mod = nextSibling(mod); - - Node *options = Getattr(mod, "options"); - String *pkg = options ? Getattr(options, "package") : 0; - - if (!options || (!Getattr(options, "noshadow") && !Getattr(options, "noproxy"))) { - String *_import = import_directive_string(package, pkg, modname, "_"); - if (!GetFlagAttr(f_shadow_imports, _import)) { - String *import = import_directive_string(package, pkg, modname); - Printf(builtin ? f_shadow_after_begin : f_shadow, "%s", import); - Delete(import); - SetFlag(f_shadow_imports, _import); - } - Delete(_import); - } - - } - } - return Language::importDirective(n); - } - - /* ------------------------------------------------------------ - * funcCall() - * - * Emit shadow code to call a function in the extension - * module. Using proper argument and calling style for - * given node n. - * ------------------------------------------------------------ */ - String *funcCall(String *name, String *parms) { - String *str = NewString(""); - - Printv(str, module, ".", name, "(", parms, ")", NIL); - return str; - } - - /* ------------------------------------------------------------ - * indent_pythoncode() - * - * Format (indent) Python code. - * Remove leading whitespace from 'code' and re-indent using - * the indentation string in 'indent'. - * ------------------------------------------------------------ */ - - String *indent_pythoncode(const String *code, const_String_or_char_ptr indent, String *file, int line, const char *directive_name) { - String *out = NewString(""); - String *temp; - char *t; - if (!indent) - indent = ""; - - temp = NewString(code); - - t = Char(temp); - if (*t == '{') { - Delitem(temp, 0); - Delitem(temp, DOH_END); - } - - /* Split the input text into lines */ - List *clist = SplitLines(temp); - Delete(temp); - - // Line number within the pythoncode. - int py_line = 0; - - String *initial = 0; - Iterator si; - - /* Get the initial indentation. Skip lines which only contain whitespace - * and/or a comment, as the indentation of those doesn't matter: - * - * A logical line that contains only spaces, tabs, formfeeds and - * possibly a comment, is ignored (i.e., no NEWLINE token is - * generated). - * - * see: - * https://docs.python.org/2/reference/lexical_analysis.html#blank-lines - * https://docs.python.org/3/reference/lexical_analysis.html#blank-lines - */ - for (si = First(clist); si.item; si = Next(si), ++py_line) { - const char *c = Char(si.item); - int i; - for (i = 0; isspace((unsigned char)c[i]); i++) { - // Scan forward until we find a non-space (which may be a null byte). - } - char ch = c[i]; - if (ch && ch != '#') { - // Found a line with actual content. - initial = NewStringWithSize(c, i); - break; - } - if (ch) { - Printv(out, indent, c, NIL); - } - Putc('\n', out); - } - - // Process remaining lines. - for ( ; si.item; si = Next(si), ++py_line) { - const char *c = Char(si.item); - // If no prefixed line was found, the above loop should have completed. - assert(initial); - - int i; - for (i = 0; isspace((unsigned char)c[i]); i++) { - // Scan forward until we find a non-space (which may be a null byte). - } - char ch = c[i]; - if (!ch) { - // Line is just whitespace - emit an empty line. - Putc('\n', out); - continue; - } - - if (ch == '#') { - // Comment - the indentation doesn't matter to python, but try to - // adjust the whitespace for the benefit of human readers (though SWIG - // currently seems to always remove any whitespace before a '#' before - // we get here, in which case we'll just leave the comment at the start - // of the line). - if (i >= Len(initial)) { - Printv(out, indent, NIL); - } - - Printv(out, c + i, "\n", NIL); - continue; - } - - if (i < Len(initial)) { - // There's non-whitespace in the initial prefix of this line. - Swig_error(file, line, "Line indented less than expected (line %d of %s) as no line should be indented less than the indentation in line 1\n", py_line, directive_name); - Printv(out, indent, c, "\n", NIL); - } else { - if (memcmp(c, Char(initial), Len(initial)) == 0) { - // Prefix matches initial, so just remove it. - Printv(out, indent, c + Len(initial), "\n", NIL); - continue; - } - Swig_warning(WARN_PYTHON_INDENT_MISMATCH, - file, line, "Whitespace indentation is inconsistent compared to earlier lines (line %d of %s)\n", py_line, directive_name); - // To avoid gratuitously breaking interface files which worked with - // SWIG <= 3.0.5, we remove a prefix of the same number of bytes for - // lines which start with different whitespace to the line we got - // 'initial' from. - Printv(out, indent, c + Len(initial), "\n", NIL); - } - } - Delete(clist); - return out; - } - - /* ------------------------------------------------------------ - * indent_docstring() - * - * Format (indent) a Python docstring. - * Remove leading whitespace from 'code' and re-indent using - * the indentation string in 'indent'. - * ------------------------------------------------------------ */ - - String *indent_docstring(const String *code, const_String_or_char_ptr indent) { - String *out = NewString(""); - String *temp; - char *t; - if (!indent) - indent = ""; - - temp = NewString(code); - - t = Char(temp); - if (*t == '{') { - Delitem(temp, 0); - Delitem(temp, DOH_END); - } - - /* Split the input text into lines */ - List *clist = SplitLines(temp); - Delete(temp); - - Iterator si; - - int truncate_characters_count = INT_MAX; - for (si = First(clist); si.item; si = Next(si)) { - const char *c = Char(si.item); - int i; - for (i = 0; isspace((unsigned char)c[i]); i++) { - // Scan forward until we find a non-space (which may be a null byte). - } - char ch = c[i]; - if (ch) { - // Found a line which isn't just whitespace - if (i < truncate_characters_count) - truncate_characters_count = i; - } - } - - if (truncate_characters_count == INT_MAX) - truncate_characters_count = 0; - - for (si = First(clist); si.item; si = Next(si)) { - const char *c = Char(si.item); - - int i; - for (i = 0; isspace((unsigned char)c[i]); i++) { - // Scan forward until we find a non-space (which may be a null byte). - } - char ch = c[i]; - if (!ch) { - // Line is just whitespace - emit an empty line. - Putc('\n', out); - continue; - } - - Printv(out, indent, c + truncate_characters_count, "\n", NIL); - } - Delete(clist); - return out; - } - - /* ------------------------------------------------------------ - * autodoc level declarations - * ------------------------------------------------------------ */ - - enum autodoc_l { - NO_AUTODOC = -2, // no autodoc - STRING_AUTODOC = -1, // use provided string - NAMES_AUTODOC = 0, // only parameter names - TYPES_AUTODOC = 1, // parameter names and types - EXTEND_AUTODOC = 2, // extended documentation and parameter names - EXTEND_TYPES_AUTODOC = 3 // extended documentation and parameter types + names - }; - - - autodoc_l autodoc_level(String *autodoc) { - autodoc_l dlevel = NO_AUTODOC; - char *c = Char(autodoc); - if (c) { - if (isdigit(c[0])) { - dlevel = (autodoc_l) atoi(c); - } else { - if (strcmp(c, "extended") == 0) { - dlevel = EXTEND_AUTODOC; - } else { - dlevel = STRING_AUTODOC; - } - } - } - return dlevel; - } - - - /* ------------------------------------------------------------ - * have_docstring() - * - * Check if there is a docstring directive and it has text, - * or there is an autodoc flag set - * ------------------------------------------------------------ */ - - bool have_docstring(Node *n) { - String *str = Getattr(n, "feature:docstring"); - return ((str && Len(str) > 0) - || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) - || (doxygen && doxygenTranslator->hasDocumentation(n)) - ); - } - - /* ------------------------------------------------------------ - * build_combined_docstring() - * - * Build the full docstring: - * Use the docstring if there is one present otherwise - * use the Doxygen comment if there is one present. - * Ignore autodoc if there is a Doxygen comment, otherwise - * create the autodoc string and append to any docstring. - * - * Return new string to be deleted by caller (never NIL but - * may be empty if there is no docstring). - * ------------------------------------------------------------ */ - - String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "", bool low_level = false) { - bool add_autodoc = true; - String *docstr = Getattr(n, "feature:docstring"); - if (docstr) { - // Simplify the code below by just ignoring empty docstrings. - if (!Len(docstr)) - docstr = NULL; - else - docstr = Copy(docstr); - } - - if (docstr) { - char *t = Char(docstr); - if (*t == '{') { - Delitem(docstr, 0); - Delitem(docstr, DOH_END); - } - } - - if (!docstr) { - if (doxygen && doxygenTranslator->hasDocumentation(n)) { - docstr = Getattr(n, "python:docstring"); - if (!docstr) { - docstr = doxygenTranslator->getDocumentation(n, 0); - - // Avoid rebuilding it again the next time: notice that we can't do - // this for the combined doc string as autodoc part of it depends on - // the sym:name of the node and it is changed while handling it, so - // the cached results become incorrect. But Doxygen docstring only - // depends on the comment which is not going to change, so we can - // safely cache it. - Setattr(n, "python:docstring", Copy(docstr)); - } else { - // Must copy here since if the docstring is multi-line, the String* - // here will get Deleted below, which is bad if it is a pointer to - // the cached object! - docstr = Copy(docstr); - } - add_autodoc = false; - } - } - - if (add_autodoc && Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) { - String *autodoc = make_autodoc(n, ad_type, low_level); - if (autodoc && Len(autodoc) > 0) { - if (docstr) { - Append(autodoc, "\n"); - Append(autodoc, docstr); - } - - String *tmp = autodoc; - autodoc = docstr; - docstr = tmp; - } - - Delete(autodoc); - } - - if (!docstr) - docstr = NewString(""); - - // If there is more than one line then make docstrings like this: - // - // """ - // This is line1 - // And here is line2 followed by the rest of them - // """ - // - // otherwise, put it all on a single line - if (Strchr(docstr, '\n')) { - String *tmp = NewString(""); - Append(tmp, "\n"); - Append(tmp, indent_docstring(docstr, indent)); - Append(tmp, indent); - Delete(docstr); - docstr = tmp; - } - - return docstr; - } - - /* ------------------------------------------------------------ - * docstring() - * - * Get the docstring text, stripping off {} if necessary, - * and enclose in triple double quotes. If autodoc is also - * set then it will build a combined docstring. - * ------------------------------------------------------------ */ - - String *docstring(Node *n, autodoc_t ad_type, const String *indent, bool low_level = false) { - String *docstr = build_combined_docstring(n, ad_type, indent, low_level); - const int len = Len(docstr); - if (!len) - return docstr; - - // Notice that all comments are created as raw strings (prefix "r"), - // because '\' is used often in comments, but may break Python module from - // loading. For example, in doxy comment one may write path in quotes: - // - // This is path to file "C:\x\file.txt" - // - // Python will not load the module with such comment because of illegal - // escape '\x'. '\' may additionally appear in verbatim or htmlonly sections - // of doxygen doc, Latex expressions, ... - String *doc = NewString(""); - - // Determine which kind of quotes to use as delimiters: for single line - // strings we can avoid problems with having a quote as the last character - // of the docstring by using different kind of quotes as delimiters. For - // multi-line strings this problem doesn't arise, as we always have a new - // line or spaces at the end of it, but it still does no harm to do it for - // them too. - // - // Note: we use double quotes by default, i.e. if there is no reason to - // prefer using single ones, for consistency with the older SWIG versions. - const bool useSingleQuotes = (Char(docstr))[len - 1] == '"'; - - Append(doc, useSingleQuotes ? "r'''" : "r\"\"\""); - - // We also need to avoid having triple quotes of whichever type we use, as - // this would break Python doc string syntax too. Unfortunately there is no - // way to have triple quotes inside of raw-triple-quoted string, so we have - // to break the string in parts and rely on concatenation of the adjacent - // string literals. - if (useSingleQuotes) - Replaceall(docstr, "'''", "''' \"'''\" '''"); - else - Replaceall(docstr, "\"\"\"", "\"\"\" '\"\"\"' \"\"\""); - - Append(doc, docstr); - Append(doc, useSingleQuotes ? "'''" : "\"\"\""); - Delete(docstr); - - return doc; - } - - /* ------------------------------------------------------------ - * cdocstring() - * - * Get the docstring text as it would appear in C-language - * source code (but without quotes around it). - * ------------------------------------------------------------ */ - - String *cdocstring(Node *n, autodoc_t ad_type, bool low_level = false) { - String *ds = build_combined_docstring(n, ad_type, "", low_level); - Replaceall(ds, "\\", "\\\\"); - Replaceall(ds, "\"", "\\\""); - Replaceall(ds, "\n", "\\n\"\n\t\t\""); - return ds; - } - - /* ----------------------------------------------------------------------------- - * addMissingParameterNames() - * - * For functions that have not had nameless parameters set in the Language class. - * - * Inputs: - * plist - entire parameter list - * arg_num - the number to start from when naming arguments - * Side effects: - * The "lname" attribute in each parameter in plist will be contain a parameter name - * ----------------------------------------------------------------------------- */ - - void addMissingParameterNames(Node *n, ParmList *plist, int arg_num) { - Parm *p = plist; - int i = arg_num; - while (p) { - if (!Getattr(p, "lname")) { - String *name = makeParameterName(n, p, i); - Setattr(p, "lname", name); - Delete(name); - } - i++; - p = nextSibling(p); - } - } - - /* ------------------------------------------------------------ - * make_autodocParmList() - * - * Generate the documentation for the function parameters - * Parameters: - * arg_num: The number to start assigning unnamed arguments from - * func_annotation: Function annotation support - * ------------------------------------------------------------ */ - - String *make_autodocParmList(Node *n, bool showTypes, int arg_num = 1, bool calling = false, bool func_annotation = false) { - - String *doc = NewString(""); - String *pdocs = 0; - ParmList *plist = CopyParmList(Getattr(n, "parms")); - Parm *p; - Parm *pnext; - - if (calling) - func_annotation = false; - - addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms - Swig_typemap_attach_parms("in", plist, 0); - Swig_typemap_attach_parms("doc", plist, 0); - - if (Strcmp(ParmList_protostr(plist), "void") == 0) { - //No parameters actually - return doc; - } - - for (p = plist; p; p = pnext) { - String *tm = Getattr(p, "tmap:in"); - if (tm) { - pnext = Getattr(p, "tmap:in:next"); - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - continue; - } - } else { - pnext = nextSibling(p); - } - - String *name = 0; - String *type = 0; - String *value = 0; - String *pdoc = Getattr(p, "tmap:doc"); - if (pdoc) { - name = Getattr(p, "tmap:doc:name"); - type = Getattr(p, "tmap:doc:type"); - value = Getattr(p, "tmap:doc:value"); - } - - // Skip the "self" argument - it is added to the parameter list automatically - // and shouldn't be included in the Parameters block - if (Getattr(p, "self")) { - continue; - } - - // Note: the generated name should be consistent with that in kwnames[] - String *made_name = 0; - if (!name) { - name = made_name = makeParameterName(n, p, arg_num); - } - - // Increment the argument number once we are sure this is a real argument to count - arg_num++; - - type = type ? type : Getattr(p, "type"); - value = value ? value : Getattr(p, "value"); - - if (SwigType_isvarargs(type)) { - Delete(made_name); - break; - } - - if (Len(doc)) { - // add a comma to the previous one if any - Append(doc, ", "); - } - - // Do the param type too? - Node *nn = classLookup(Getattr(p, "type")); - String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0); - if (showTypes) - Printf(doc, "%s ", type_str); - - Append(doc, name); - if (pdoc) { - if (!pdocs) - // numpydoc style: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt - pdocs = NewString("\nParameters\n----------\n"); - Printf(pdocs, "%s\n", pdoc); - } - // Write the function annotation - if (func_annotation) - Printf(doc, ": \"%s\"", type_str); - - // Write default value - if (value && !calling) { - String *new_value = convertValue(value, Getattr(p, "type")); - if (new_value) { - value = new_value; - } else { - // Even if the value is not representable in the target language, still use it in the documentation, for compatibility with the previous SWIG versions - // and because it can still be useful to see the C++ expression there. - Node *lookup = Swig_symbol_clookup(value, 0); - if (lookup) - value = Getattr(lookup, "sym:name"); - } - Printf(doc, "=%s", value); - - if (new_value) - Delete(new_value); - } - Delete(type_str); - Delete(made_name); - } - if (pdocs) - Setattr(n, "feature:pdocs", pdocs); - Delete(plist); - return doc; - } - - /* ------------------------------------------------------------ - * make_autodoc() - * - * Build a docstring for the node, using parameter and other - * info in the parse tree. If the value of the autodoc - * attribute is "0" then do not include parameter types, if - * it is "1" (the default) then do. If it has some other - * value then assume it is supplied by the extension writer - * and use it directly. - * ------------------------------------------------------------ */ - - String *make_autodoc(Node *n, autodoc_t ad_type, bool low_level = false) { - int extended = 0; - bool first_func = true; - // If the function is overloaded then this function is called - // for the last one. Rewind to the first so the docstrings are - // in order. - while (Getattr(n, "sym:previousSibling")) - n = Getattr(n, "sym:previousSibling"); - - String *doc = NewString(""); - while (n) { - bool showTypes = false; - bool skipAuto = false; - String *autodoc = Getattr(n, "feature:autodoc"); - autodoc_l dlevel = autodoc_level(autodoc); - switch (dlevel) { - case NO_AUTODOC: - break; - case NAMES_AUTODOC: - showTypes = false; - break; - case TYPES_AUTODOC: - showTypes = true; - break; - case EXTEND_AUTODOC: - extended = 1; - showTypes = false; - break; - case EXTEND_TYPES_AUTODOC: - extended = 1; - showTypes = true; - break; - case STRING_AUTODOC: - Append(doc, autodoc); - skipAuto = true; - break; - } - - if (!skipAuto) { - /* Check if a documentation name was given for either the low-level C API or high-level Python shadow API */ - String *symname = Getattr(n, low_level ? "doc:low:name" : "doc:high:name"); - if (!symname) { - symname = Getattr(n, "sym:name"); - } - - SwigType *type = Getattr(n, "type"); - String *type_str = NULL; - - // If the function has default arguments, then that documentation covers this version too - if (Getattr(n, "defaultargs") != NULL) { - n = Getattr(n, "sym:nextSibling"); - continue; - } - - if (!first_func) - Append(doc, "\n"); - - if (type) { - if (Strcmp(type, "void") == 0) { - type_str = NULL; - } else { - Node *nn = classLookup(type); - type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0); - } - } - - /* Treat the low-level C API functions for getting/setting variables as methods for documentation purposes */ - String *kind = Getattr(n, "kind"); - if (kind && Strcmp(kind, "variable") == 0) { - if (ad_type == AUTODOC_FUNC) { - ad_type = AUTODOC_METHOD; - } - } - /* Treat destructors as methods for documentation purposes */ - String *nodeType = Getattr(n, "nodeType"); - if (nodeType && Strcmp(nodeType, "destructor") == 0) { - if (ad_type == AUTODOC_FUNC) { - ad_type = AUTODOC_METHOD; - } - } - - switch (ad_type) { - case AUTODOC_CLASS: - { - // Only do the autodoc if there isn't a docstring for the class - String *str = Getattr(n, "feature:docstring"); - if (!str || Len(str) == 0) { - if (builtin) { - String *name = Getattr(n, "name"); - String *rname = add_explicit_scope(SwigType_namestr(name)); - Printf(doc, "%s", rname); - Delete(rname); - } else { - if (CPlusPlus) { - Printf(doc, "Proxy of C++ %s class.", SwigType_namestr(real_classname)); - } else { - Printf(doc, "Proxy of C %s struct.", SwigType_namestr(real_classname)); - } - } - } - } - break; - case AUTODOC_CTOR: - if (Strcmp(class_name, symname) == 0) { - String *paramList = make_autodocParmList(n, showTypes, 2); - Printf(doc, "__init__("); - if (showTypes) - Printf(doc, "%s ", class_name); - if (Len(paramList)) - Printf(doc, "self, %s) -> %s", paramList, class_name); - else - Printf(doc, "self) -> %s", class_name); - } else - Printf(doc, "%s(%s) -> %s", symname, make_autodocParmList(n, showTypes), class_name); - break; - - case AUTODOC_DTOR: - if (showTypes) - Printf(doc, "__del__(%s self)", class_name); - else - Printf(doc, "__del__(self)"); - break; - - case AUTODOC_STATICFUNC: - Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes)); - if (type_str) - Printf(doc, " -> %s", type_str); - break; - - case AUTODOC_FUNC: - Printf(doc, "%s(%s)", symname, make_autodocParmList(n, showTypes)); - if (type_str) - Printf(doc, " -> %s", type_str); - break; - - case AUTODOC_METHOD: - { - String *paramList = make_autodocParmList(n, showTypes, 2); - Printf(doc, "%s(", symname); - if (showTypes) - Printf(doc, "%s ", class_name); - if (Len(paramList)) - Printf(doc, "self, %s)", paramList); - else - Printf(doc, "self)"); - if (type_str) - Printf(doc, " -> %s", type_str); - } - break; - - case AUTODOC_CONST: - // There is no autodoc support for constants currently, this enum - // element only exists to allow calling docstring() with it. - return NULL; - case AUTODOC_VAR: - // Variables can also be documented (e.g. through the property() function in python) - Printf(doc, "%s", symname); - if (showTypes) { - String *type = Getattr(n, "tmap:doc:type"); - if (!type) - type = Getattr(n, "membervariableHandler:type"); - if (!type) - type = Getattr(n, "type"); - Printf(doc, " : %s", type); - } - break; - } - Delete(type_str); - - // Special case: wrapper functions to get a variable should have no parameters. - // Because the node is re-used for the setter and getter, the feature:pdocs field will - // exist for the getter function, so explicitly avoid printing parameters in this case. - bool variable_getter = kind && Strcmp(kind, "variable") == 0 && Getattr(n, "memberget"); - if (extended && ad_type != AUTODOC_VAR && !variable_getter) { - String *pdocs = Getattr(n, "feature:pdocs"); - if (pdocs) { - Printv(doc, "\n", pdocs, NULL); - } - } - } - // if it's overloaded then get the next decl and loop around again - n = Getattr(n, "sym:nextSibling"); - if (n) - first_func = false; - } - - return doc; - } - - /* ------------------------------------------------------------ - * convertIntegerValue() - * - * Check if string v is an integer and can be represented in - * Python. If so, return an appropriate Python representation, - * otherwise (or if we are unsure), return NIL. - * ------------------------------------------------------------ */ - String *convertIntegerValue(String *v, SwigType *resolved_type) { - const char *const s = Char(v); - char *end; - String *result = NIL; - - // Check if this is an integer number in any base. - errno = 0; - long value = strtol(s, &end, 0); - if (errno == ERANGE || end == s) - return NIL; - - if (*end != '\0') { - // If there is a suffix after the number, we can safely ignore "l" - // and (provided the number is unsigned) "u", and also combinations of - // these, but not anything else. - for (char *p = end; *p != '\0'; ++p) { - switch (*p) { - case 'l': - case 'L': - break; - case 'u': - case 'U': - if (value < 0) - return NIL; - break; - default: - return NIL; - } - } - } - // So now we are certain that we are indeed dealing with an integer - // that has a representation as long given by value. - - // Restrict to guaranteed supported range in Python, see maxint docs: https://docs.python.org/2/library/sys.html#sys.maxint - // Don't do this pointless check when long is 32 bits or smaller as strtol will have already failed with ERANGE -#if LONG_MAX > PYTHON_INT_MAX || LONG_MIN < PYTHON_INT_MIN - if (value > PYTHON_INT_MAX || value < PYTHON_INT_MIN) { - return NIL; - } -#endif - - if (Cmp(resolved_type, "bool") == 0) - // Allow integers as the default value for a bool parameter. - return NewString(value ? "True" : "False"); - - if (value == 0) - return NewString(SwigType_ispointer(resolved_type) ? "None" : "0"); - - // v may still be octal or hexadecimal: - const char *p = s; - if (*p == '+' || *p == '-') - ++p; - if (*p == '0' && *(p+1) != 'x' && *(p+1) != 'X') { - // This must have been an octal number. This is the only case we - // cannot use in Python directly, since Python 2 and 3 use non- - // compatible representations. - result = NewString(*s == '-' ? "int(\"-" : "int(\""); - String *octal_string = NewStringWithSize(p, (int) (end - p)); - Append(result, octal_string); - Append(result, "\", 8)"); - Delete(octal_string); - return result; - } - result = *end == '\0' ? Copy(v) : NewStringWithSize(s, (int) (end - s)); - return result; - } - - /* ------------------------------------------------------------ - * convertDoubleValue() - * - * Check if the given string looks like a decimal floating point constant - * and return it if it does, otherwise return NIL. - * ------------------------------------------------------------ */ - String *convertDoubleValue(String *v) { - const char *const s = Char(v); - char *end; - - errno = 0; - double value = strtod(s, &end); - (void) value; - if (errno != ERANGE && end != s) { - // An added complication: at least some versions of strtod() recognize - // hexadecimal floating point numbers which don't exist in Python, so - // detect them ourselves and refuse to convert them (this can't be done - // without loss of precision in general). - // - // Also don't accept neither "NAN" nor "INFINITY" (both of which - // conveniently contain "n"). - if (strpbrk(s, "xXnN")) - return NIL; - - // Disregard optional "f" suffix, it can be just dropped in Python as it - // uses doubles for everything anyhow. - for (char * p = end; *p != '\0'; ++p) { - switch (*p) { - case 'f': - case 'F': - break; - - default: - return NIL; - } - } - - // Avoid unnecessary string allocation in the common case when we don't - // need to remove any suffix. - return *end == '\0' ? Copy(v) : NewStringWithSize(s, (int)(end - s)); - } - - return NIL; - } - - /* ------------------------------------------------------------ - * convertValue() - * - * Check if string v can be a Python value literal or a - * constant. Return an equivalent Python representation, - * or NIL if it isn't, or we are unsure. - * ------------------------------------------------------------ */ - String *convertValue(String *v, SwigType *type) { - const char *const s = Char(v); - String *result = NIL; - SwigType *resolved_type = SwigType_typedef_resolve_all(type); - - result = convertIntegerValue(v, resolved_type); - if (!result) { - result = convertDoubleValue(v); - if (!result) { - if (Strcmp(v, "true") == 0) - result = NewString("True"); - else if (Strcmp(v, "false") == 0) - result = NewString("False"); - else if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) - result = SwigType_ispointer(resolved_type) ? NewString("None") : NewString("0"); - // This could also be an enum type, default value of which could be - // representable in Python if it doesn't include any scope (which could, - // but currently is not, translated). - else if (!Strchr(s, ':')) { - Node *lookup = Swig_symbol_clookup(v, 0); - if (lookup) { - if (Cmp(Getattr(lookup, "nodeType"), "enumitem") == 0) - result = Copy(Getattr(lookup, "sym:name")); - } - } - } - } - - Delete(resolved_type); - return result; - } - - /* ------------------------------------------------------------ - * is_representable_as_pyargs() - * - * Check if the function parameters default argument values - * can be represented in Python. - * - * If this method returns false, the parameters will be translated - * to a generic "*args" which allows us to deal with default values - * at C++ code level where they can always be handled. - * ------------------------------------------------------------ */ - bool is_representable_as_pyargs(Node *n) { - ParmList *plist = CopyParmList(Getattr(n, "parms")); - Swig_typemap_attach_parms("default", plist, NULL); - - Parm *p; - Parm *pnext; - - for (p = plist; p; p = pnext) { - pnext = nextSibling(p); - String *tm = Getattr(p, "tmap:in"); - if (tm) { - Parm *in_next = Getattr(p, "tmap:in:next"); - if (in_next) - pnext = in_next; - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - continue; - } - } - - // "default" typemap can contain arbitrary C++ code, so while it could, in - // principle, be possible to examine it and check if it's just something - // simple of the form "$1 = expression" and then use convertValue() to - // check if expression can be used in Python, but for now we just - // pessimistically give up and prefer to handle this at C++ level only. - if (Getattr(p, "tmap:default")) - return false; - - String *value = Getattr(p, "value"); - if (value) { - String *convertedValue = convertValue(value, Getattr(p, "type")); - if (!convertedValue) - return false; - Delete(convertedValue); - } - } - - return true; - } - - - /* ------------------------------------------------------------ - * is_real_overloaded() - * - * Check if the function is overloaded, but not just have some - * siblings generated due to the original function having - * default arguments. - * ------------------------------------------------------------ */ - bool is_real_overloaded(Node *n) { - Node *h = Getattr(n, "sym:overloaded"); - Node *i; - if (!h) - return false; - - i = Getattr(h, "sym:nextSibling"); - while (i) { - Node *nn = Getattr(i, "defaultargs"); - if (nn != h) { - /* Check if overloaded function has defaultargs and - * pointed to the first overloaded. */ - return true; - } - i = Getattr(i, "sym:nextSibling"); - } - - return false; - } - - /* ------------------------------------------------------------ - * make_pyParmList() - * - * Generate parameter list for Python functions or methods, - * reuse make_autodocParmList() to do so. - * ------------------------------------------------------------ */ - String *make_pyParmList(Node *n, bool in_class, bool is_calling, int kw, bool has_self_for_count = false) { - /* Get the original function for a defaultargs copy, - * see default_arguments() in parser.y. */ - Node *nn = Getattr(n, "defaultargs"); - if (nn) - n = nn; - - Parm *parms = Getattr(n, "parms"); - int varargs = parms ? emit_isvarargs(parms) : 0; - - /* We prefer to explicitly list all parameters of the C function in the - generated Python code as this makes the function more convenient to use, - however in some cases we must replace the real parameters list with just - the catch all "*args". This happens when: - - 1. The function is overloaded as Python doesn't support this. - 2. We were explicitly asked to use the "compact" arguments form. - 3. We were explicitly asked to use default args from C via the "python:cdefaultargs" feature. - 4. One of the default argument values can't be represented in Python. - 5. Varargs that haven't been forced to use a fixed number of arguments with %varargs. - */ - if (is_real_overloaded(n) || GetFlag(n, "feature:compactdefaultargs") || GetFlag(n, "feature:python:cdefaultargs") || !is_representable_as_pyargs(n) || varargs) { - String *parms = NewString(""); - if (in_class) - Printf(parms, "self, "); - Printf(parms, "*args"); - if (kw) - Printf(parms, ", **kwargs"); - return parms; - } - - bool funcanno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false; - String *params = NewString(""); - String *_params = make_autodocParmList(n, false, ((in_class || has_self_for_count)? 2 : 1), is_calling, funcanno); - - if (in_class) { - Printf(params, "self"); - if (Len(_params) > 0) - Printf(params, ", "); - } - - Printv(params, _params, NULL); - - return params; - } - - /* ------------------------------------------------------------ - * have_pythonprepend() - * - * Check if there is a %pythonprepend directive and it has text - * ------------------------------------------------------------ */ - - bool have_pythonprepend(Node *n) { - String *str = Getattr(n, "feature:pythonprepend"); - return (str && Len(str) > 0); - } - - /* ------------------------------------------------------------ - * pythonprepend() - * - * Get the %pythonprepend code, stripping off {} if necessary - * ------------------------------------------------------------ */ - - String *pythonprepend(Node *n) { - String *str = Getattr(n, "feature:pythonprepend"); - char *t = Char(str); - if (*t == '{') { - Delitem(str, 0); - Delitem(str, DOH_END); - } - return str; - } - - /* ------------------------------------------------------------ - * have_pythonappend() - * - * Check if there is a %pythonappend directive and it has text - * ------------------------------------------------------------ */ - - bool have_pythonappend(Node *n) { - String *str = Getattr(n, "feature:pythonappend"); - if (!str) - str = Getattr(n, "feature:addtofunc"); - return (str && Len(str) > 0); - } - - /* ------------------------------------------------------------ - * pythonappend() - * - * Get the %pythonappend code, stripping off {} if necessary - * ------------------------------------------------------------ */ - - String *pythonappend(Node *n) { - String *str = Getattr(n, "feature:pythonappend"); - if (!str) - str = Getattr(n, "feature:addtofunc"); - - char *t = Char(str); - if (*t == '{') { - Delitem(str, 0); - Delitem(str, DOH_END); - } - return str; - } - - /* ------------------------------------------------------------ - * have_addtofunc() - * - * Check if there is a %addtofunc directive and it has text - * ------------------------------------------------------------ */ - - bool have_addtofunc(Node *n) { - return have_pythonappend(n) || have_pythonprepend(n); - } - - - /* ------------------------------------------------------------ - * returnTypeAnnotation() - * - * Helper function for constructing the function annotation - * of the returning type, return a empty string for Python 2.x - * ------------------------------------------------------------ */ - String *returnTypeAnnotation(Node *n) { - String *ret = 0; - Parm *p = Getattr(n, "parms"); - String *tm; - /* Try to guess the returning type by argout typemap, - * however the result may not accurate. */ - while (p) { - if ((tm = Getattr(p, "tmap:argout:match_type"))) { - tm = SwigType_str(tm, 0); - if (ret) - Printv(ret, ", ", tm, NULL); - else - ret = tm; - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - /* If no argout typemap, then get the returning type from - * the function prototype. */ - if (!ret) { - ret = Getattr(n, "type"); - if (ret) - ret = SwigType_str(ret, 0); - } - bool funcanno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false; - return (ret && funcanno) ? NewStringf(" -> \"%s\"", ret) : NewString(""); - } - - /* ------------------------------------------------------------ - * variableAnnotation() - * - * Helper function for constructing a variable annotation - * ------------------------------------------------------------ */ - - String *variableAnnotation(Node *n) { - String *type = Getattr(n, "type"); - if (type) - type = SwigType_str(type, 0); - bool anno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false; - anno = GetFlag(n, "feature:python:annotations:novar") ? false : anno; - String *annotation = (type && anno) ? NewStringf(": \"%s\"", type) : NewString(""); - Delete(type); - return annotation; - } - - /* ------------------------------------------------------------ - * emitFunctionShadowHelper() - * - * Refactoring some common code out of functionWrapper and - * dispatchFunction that writes the proxy code for non-member - * functions. - * ------------------------------------------------------------ */ - - void emitFunctionShadowHelper(Node *n, File *f_dest, String *name, int kw) { - String *parms = make_pyParmList(n, false, false, kw); - String *callParms = make_pyParmList(n, false, true, kw); - - // Callbacks need the C function in order to extract the pointer from the swig_ptr: string - bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback"); - - if (!fast || olddefs) { - /* Make a wrapper function to insert the code into */ - Printv(f_dest, "\n", "def ", name, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); - if (have_docstring(n)) - Printv(f_dest, tab4, docstring(n, AUTODOC_FUNC, tab4, true), "\n", NIL); - if (have_pythonprepend(n)) - Printv(f_dest, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL); - if (have_pythonappend(n)) { - Printv(f_dest, tab4 "val = ", funcCall(name, callParms), "\n", NIL); - Printv(f_dest, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL); - Printv(f_dest, tab4 "return val\n", NIL); - } else { - Printv(f_dest, tab4 "return ", funcCall(name, callParms), "\n", NIL); - } - } - - // Below may result in a 2nd definition of the method when -olddefs is used. The Python interpreter will use the second definition as it overwrites the first. - if (fast) { - /* If there is no addtofunc directive then just assign from the extension module (for speed up) */ - Printv(f_dest, name, " = ", module, ".", name, "\n", NIL); - } - } - - - /* ------------------------------------------------------------ - * check_kwargs() - * - * check if using kwargs is allowed for this Node - * ------------------------------------------------------------ */ - - int check_kwargs(Node *n) const { - return (use_kw || GetFlag(n, "feature:kwargs")) - && !GetFlag(n, "memberset") && !GetFlag(n, "memberget"); - } - - - - /* ------------------------------------------------------------ - * add_method() - * ------------------------------------------------------------ */ - - void add_method(String *name, String *function, int kw, Node *n = 0, int funpack = 0, int num_required = -1, int num_arguments = -1) { - String * meth_str = NewString(""); - if (!kw) { - if (funpack) { - if (num_required == 0 && num_arguments == 0) { - Printf(meth_str, "\t { \"%s\", %s, METH_NOARGS, ", name, function); - } else if (num_required == 1 && num_arguments == 1) { - Printf(meth_str, "\t { \"%s\", %s, METH_O, ", name, function); - } else { - Printf(meth_str, "\t { \"%s\", %s, METH_VARARGS, ", name, function); - } - } else { - Printf(meth_str, "\t { \"%s\", %s, METH_VARARGS, ", name, function); - } - } else { - // Cast via void(*)(void) to suppress GCC -Wcast-function-type warning. - // Python should always call the function correctly, but the Python C API - // requires us to store it in function pointer of a different type. - Printf(meth_str, "\t { \"%s\", (PyCFunction)(void(*)(void))%s, METH_VARARGS|METH_KEYWORDS, ", name, function); - } - Append(methods, meth_str); - if (fastproxy) { - Append(methods_proxydocs, meth_str); - } - Delete(meth_str); - - if (!n) { - Append(methods, "NULL"); - if (fastproxy) { - Append(methods_proxydocs, "NULL"); - } - } else if (have_docstring(n)) { - /* Use the low-level docstring here since this is the docstring that will be used for the C API */ - String *ds = cdocstring(n, Getattr(n, "memberfunction") ? AUTODOC_METHOD : AUTODOC_FUNC, true); - Printf(methods, "\"%s\"", ds); - if (fastproxy) { - /* In the fastproxy case, we must also record the high-level docstring for use in the Python shadow API */ - Delete(ds); - ds = cdocstring(n, Getattr(n, "memberfunction") ? AUTODOC_METHOD : AUTODOC_FUNC); - Printf(methods_proxydocs, "\"%s\"", ds); - } - Delete(ds); - } else if (Getattr(n, "feature:callback")) { - Printf(methods, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name")); - if (fastproxy) { - Printf(methods_proxydocs, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name")); - have_fast_proxy_static_member_method_callback = true; - } - } else { - Append(methods, "NULL"); - if (fastproxy) { - Append(methods_proxydocs, "NULL"); - } - } - - Append(methods, "},\n"); - if (fastproxy) { - Append(methods_proxydocs, "},\n"); - } - } - - /* ------------------------------------------------------------ - * dispatchFunction() - * ------------------------------------------------------------ */ - void dispatchFunction(Node *n, String *linkage, int funpack = 0, bool builtin_self = false, bool builtin_ctor = false, bool director_class = false, bool use_static_method = false) { - /* Last node in overloaded chain */ - - bool add_self = builtin_self && (!builtin_ctor || director_class); - - int maxargs; - - String *tmp = NewString(""); - String *dispatch; - - const char *dispatch_call = funpack ? "%s(self, argc, argv);" : (builtin_ctor ? "%s(self, args, NULL);" : "%s(self, args);"); - String *dispatch_code = NewStringf("return %s", dispatch_call); - - if (castmode) { - dispatch = Swig_overload_dispatch_cast(n, dispatch_code, &maxargs); - } else { - String *fastdispatch_code; - if (builtin_ctor) - fastdispatch_code = NewStringf("int retval = %s\nif (retval == 0 || !SWIG_Python_TypeErrorOccurred(NULL)) return retval;\nSWIG_fail;", dispatch_call); - else - fastdispatch_code = NewStringf("PyObject *retobj = %s\nif (!SWIG_Python_TypeErrorOccurred(retobj)) return retobj;\nSWIG_fail;", dispatch_call); - if (!CPlusPlus) { - Insert(fastdispatch_code, 0, "{\n"); - Append(fastdispatch_code, "\n}"); - } - dispatch = Swig_overload_dispatch(n, dispatch_code, &maxargs, fastdispatch_code); - Delete(fastdispatch_code); - } - - /* Generate a dispatch wrapper for all overloaded functions */ - - Wrapper *f = NewWrapper(); - String *symname = Getattr(n, "sym:name"); - String *wname = Swig_name_wrapper(symname); - - const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : ""; - Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL); - - if (builtin) { - /* Avoid warning if the self parameter is not used. */ - Append(f->code, "(void)self;\n"); - } - - Wrapper_add_local(f, "argc", "Py_ssize_t argc"); - Printf(tmp, "PyObject *argv[%d] = {0}", maxargs + 1); - Wrapper_add_local(f, "argv", tmp); - - if (!fastunpack) { - Wrapper_add_local(f, "ii", "Py_ssize_t ii"); - - if (builtin_ctor) - Printf(f->code, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", symname); - - if (maxargs - (add_self ? 1 : 0) > 0) { - Append(f->code, "if (!PyTuple_Check(args)) SWIG_fail;\n"); - Append(f->code, "argc = PyObject_Length(args);\n"); - } else { - Append(f->code, "argc = args ? PyObject_Length(args) : 0;\n"); - } - - if (add_self) - Append(f->code, "argv[0] = self;\n"); - Printf(f->code, "for (ii = 0; (ii < %d) && (ii < argc); ii++) {\n", add_self ? maxargs - 1 : maxargs); - Printf(f->code, "argv[ii%s] = PyTuple_GET_ITEM(args,ii);\n", add_self ? " + 1" : ""); - Append(f->code, "}\n"); - if (add_self) - Append(f->code, "argc++;\n"); - } else { - if (builtin_ctor) - Printf(f->code, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", symname); - Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args, \"%s\", 0, %d, argv%s))) SWIG_fail;\n", symname, maxargs, add_self ? "+1" : ""); - if (add_self) - Append(f->code, "argv[0] = self;\n"); - else - Append(f->code, "--argc;\n"); - } - - Replaceall(dispatch, "$args", "self, args"); - - Printv(f->code, dispatch, "\n", NIL); - - if (GetFlag(n, "feature:python:maybecall")) { - Append(f->code, "fail:\n"); - Append(f->code, " Py_INCREF(Py_NotImplemented);\n"); - Append(f->code, " return Py_NotImplemented;\n"); - } else { - Node *sibl = n; - while (Getattr(sibl, "sym:previousSibling")) - sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up - String *protoTypes = NewString(""); - do { - String *fulldecl = Swig_name_decl(sibl); - Printf(protoTypes, "\n\" %s\\n\"", fulldecl); - Delete(fulldecl); - } while ((sibl = Getattr(sibl, "sym:nextSibling"))); - Append(f->code, "fail:\n"); - Printf(f->code, " SWIG_Python_RaiseOrModifyTypeError(" - "\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" "\n\" Possible C/C++ prototypes are:\\n\"%s);\n", symname, protoTypes); - Printf(f->code, "return %s;\n", builtin_ctor ? "-1" : "0"); - Delete(protoTypes); - } - Printv(f->code, "}\n", NIL); - Wrapper_print(f, f_wrappers); - Node *p = Getattr(n, "sym:previousSibling"); - if (!builtin_self && (use_static_method || !builtin)) - add_method(symname, wname, 0, p); - - /* Create a shadow for this function (if enabled and not in a member function) */ - if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) { - emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, symname, 0); - } - DelWrapper(f); - Delete(dispatch); - Delete(dispatch_code); - Delete(tmp); - Delete(wname); - } - - /* ------------------------------------------------------------ - * functionWrapper() - * ------------------------------------------------------------ */ - - /* - A note about argument marshalling with built-in types. - There are three distinct cases for member (non-static) methods: - - 1) An ordinary member function. In this case, the first param in - the param list is 'this'. For builtin types, 'this' is taken from - the first argument to the wrapper (usually called 'self); it's not - extracted from the second argument (which is usually a tuple). - - 2) A constructor for a non-director class. In this case, the - param list doesn't contain an entry for 'this', but the first ('self') - argument to the wrapper *does* contain the newly-allocated, - uninitialized object. - - 3) A constructor for a director class. In this case, the param - list contains a 'self' param, which comes from the first argument - to the wrapper function. - */ - - const char *get_implicitconv_flag(Node *klass) { - int conv = 0; - if (klass && GetFlag(klass, "feature:implicitconv")) { - conv = 1; - } - return conv ? "SWIG_POINTER_IMPLICIT_CONV" : "0"; - } - - - virtual int functionWrapper(Node *n) { - - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - SwigType *d = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - Node *parent = Swig_methodclass(n); - - int director_method = 0; - - Parm *p; - int i; - char source[64]; - Wrapper *f; - String *self_parse; - String *parse_args; - String *arglist; - String *get_pointers; - String *cleanup; - String *outarg; - String *kwargs; - String *tm; - String *overname = 0; - - int num_required; - int num_arguments; - int num_fixed_arguments; - int tuple_required; - int tuple_arguments; - int varargs = 0; - int allow_kwargs = check_kwargs(n); - - String *nodeType = Getattr(n, "nodeType"); - int constructor = (!Cmp(nodeType, "constructor")); - int destructor = (!Cmp(nodeType, "destructor")); - String *storage = Getattr(n, "storage"); - /* Only the first constructor is handled as init method. Others - constructor can be emitted via %rename */ - int handled_as_init = 0; - if (!have_constructor && (constructor || Getattr(n, "handled_as_constructor")) - && ((shadow & PYSHADOW_MEMBER))) { - String *nname = Getattr(n, "sym:name"); - String *sname = Getattr(getCurrentClass(), "sym:name"); - String *cname = Swig_name_construct(NSPACE_TODO, sname); - handled_as_init = (Strcmp(nname, sname) == 0) || (Strcmp(nname, cname) == 0); - Delete(cname); - } - bool builtin_self = builtin && in_class && (constructor || (l && Getattr(l, "self"))); - bool builtin_ctor = false; - if (builtin_self && constructor) { - String *class_mname = Getattr(getCurrentClass(), "sym:name"); - String *mrename = Swig_name_construct(getNSpace(), class_mname); - if (Cmp(iname, mrename)) - builtin_self = false; - else - builtin_ctor = true; - Delete(mrename); - } - bool director_class = (getCurrentClass() && Swig_directorclass(getCurrentClass())); - bool add_self = builtin_self && (!builtin_ctor || director_class); - bool builtin_getter = (builtin && GetFlag(n, "memberget")); - bool builtin_setter = (builtin && GetFlag(n, "memberset") && !builtin_getter); - char const *wrap_return = builtin_ctor ? "int " : "PyObject *"; - String *linkage = NewString("SWIGINTERN "); - String *wrapper_name = Swig_name_wrapper(iname); - - if (Getattr(n, "sym:overloaded")) { - overname = Getattr(n, "sym:overname"); - } else { - if (!addSymbol(iname, n)) - return SWIG_ERROR; - } - - f = NewWrapper(); - self_parse = NewString(""); - parse_args = NewString(""); - arglist = NewString(""); - get_pointers = NewString(""); - cleanup = NewString(""); - outarg = NewString(""); - kwargs = NewString(""); - - int allow_thread = threads_enable(n); - - Wrapper_add_local(f, "resultobj", "PyObject *resultobj = 0"); - - // Emit all of the local variables for holding arguments. - emit_parameter_variables(l, f); - - /* Attach the standard typemaps */ - emit_attach_parmmaps(l, f); - Setattr(n, "wrap:parms", l); - /* Get number of required and total arguments */ - tuple_arguments = num_arguments = emit_num_arguments(l); - tuple_required = num_required = emit_num_required(l); - if (add_self) { - --tuple_arguments; - --tuple_required; - } - num_fixed_arguments = tuple_required; - - // builtin handles/checks kwargs by default except in constructor wrappers so we need to explicitly handle them in the C constructor wrapper - // The check below is for zero arguments. Sometimes (eg directors) self is the first argument for a method with zero arguments. - if (((num_arguments == 0) && (num_required == 0)) || ((num_arguments == 1) && (num_required == 1) && Getattr(l, "self"))) - if (!builtin_ctor) - allow_kwargs = 0; - varargs = emit_isvarargs(l); - - String *wname = Copy(wrapper_name); - if (overname) { - Append(wname, overname); - } - - const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : ""; - if (!allow_kwargs || overname) { - if (!varargs) { - Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL); - } else { - Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *self, PyObject *args, PyObject *varargs", builtin_kwargs, ") {", NIL); - } - if (allow_kwargs) { - Swig_warning(WARN_LANG_OVERLOAD_KEYWORD, input_file, line_number, "Can't use keyword arguments with overloaded functions (%s).\n", Swig_name_decl(n)); - allow_kwargs = 0; - } - } else { - if (varargs) { - Swig_warning(WARN_LANG_VARARGS_KEYWORD, input_file, line_number, "Can't wrap varargs with keyword arguments enabled\n"); - varargs = 0; - } - Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args, PyObject *kwargs) {", NIL); - /* Avoid warning if the self parameter is not used. */ - Append(f->def, "(void)self;\n"); - } - - if (builtin) { - /* Avoid warning if the self parameter is not used. */ - Append(f->code, "(void)self;\n"); - } - - if (!builtin || !in_class || tuple_arguments > 0 || builtin_ctor) { - if (!allow_kwargs) { - Append(parse_args, " if (!PyArg_ParseTuple(args, \""); - } else { - Append(parse_args, " if (!PyArg_ParseTupleAndKeywords(args, kwargs, \""); - Append(arglist, ", kwnames"); - } - } - - bool over_varargs = emit_isvarargs_function(n); - - int funpack = fastunpack && !varargs && !over_varargs && !allow_kwargs; - int noargs = funpack && (tuple_required == 0 && tuple_arguments == 0); - int onearg = funpack && (tuple_required == 1 && tuple_arguments == 1); - - if (builtin && funpack && !overname && !builtin_ctor) { - int compactdefargs = ParmList_is_compactdefargs(l); - if (!(compactdefargs && (tuple_arguments > tuple_required || varargs))) { - String *argattr = NewStringf("%d", tuple_arguments); - Setattr(n, "python:argcount", argattr); - Delete(argattr); - } - } - - /* Generate code for argument marshalling */ - if (funpack) { - if (num_arguments > (builtin_self && !constructor ? 1 : 0) && !overname) { - sprintf(source, "PyObject *swig_obj[%d]", num_arguments); - Wrapper_add_localv(f, "swig_obj", source, NIL); - } - } - - - if (constructor && num_arguments == 1 && num_required == 1) { - if (Cmp(storage, "explicit") == 0) { - if (GetFlag(parent, "feature:implicitconv")) { - String *desc = NewStringf("SWIGTYPE%s", SwigType_manglestr(Getattr(n, "type"))); - Printf(f->code, "if (SWIG_CheckImplicit(%s)) SWIG_fail;\n", desc); - Delete(desc); - } - } - } - - if (builtin_ctor && checkAttribute(n, "access", "protected")) { - String *tmp_none_comparison = Copy(none_comparison); - Replaceall(tmp_none_comparison, "$arg", "self"); - Printf(self_parse, "if (!(%s)) {\n", tmp_none_comparison); - Printv(self_parse, " SWIG_SetErrorMsg(PyExc_RuntimeError, \"accessing abstract class or protected constructor\");\n SWIG_fail;\n}\n", NIL); - Delete(tmp_none_comparison); - } - - int use_parse = 0; - Append(kwargs, "{"); - for (i = 0, p = l; i < num_arguments; i++) { - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *ln = Getattr(p, "lname"); - bool parse_from_tuple = (i > 0 || !add_self); - if (SwigType_type(pt) == T_VARARGS) { - parse_from_tuple = false; - num_fixed_arguments -= atoi(Char(Getattr(p, "tmap:in:numinputs"))); - } - if (!parse_from_tuple) - sprintf(source, "self"); - else if (funpack) - sprintf(source, "swig_obj[%d]", add_self && !overname ? i - 1 : i); - else - sprintf(source, "obj%d", builtin_ctor ? i + 1 : i); - - if (parse_from_tuple) { - Printf(arglist, ", "); - if (i == num_required) - Putc('|', parse_args); /* Optional argument separator */ - } - - /* Keyword argument handling */ - if (allow_kwargs && parse_from_tuple) { - String *name = makeParameterName(n, p, i + 1); - Printf(kwargs, " (char *)\"%s\", ", name); - Delete(name); - } - - /* Look for an input typemap */ - if ((tm = Getattr(p, "tmap:in"))) { - String *parse = Getattr(p, "tmap:in:parse"); - if (!parse) { - if (builtin_self) { - Replaceall(tm, "$self", "self"); - } else if (funpack) { - Replaceall(tm, "$self", "swig_obj[0]"); - } else { - Replaceall(tm, "$self", "obj0"); - } - Replaceall(tm, "$input", source); - Setattr(p, "emit:input", source); /* Save the location of the object */ - - if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - - if (Getattr(p, "tmap:in:implicitconv")) { - const char *convflag = "0"; - if (!Getattr(p, "hidden")) { - SwigType *ptype = Getattr(p, "type"); - convflag = get_implicitconv_flag(classLookup(ptype)); - } - Replaceall(tm, "$implicitconv", convflag); - Setattr(p, "implicitconv", convflag); - } - - if (parse_from_tuple) - Putc('O', parse_args); - if (!funpack && parse_from_tuple) { - Wrapper_add_localv(f, source, "PyObject *", source, "= 0", NIL); - Printf(arglist, "&%s", source); - } - if (i >= num_required) - Printv(get_pointers, "if (", source, ") {\n", NIL); - Printv(get_pointers, tm, "\n", NIL); - if (i >= num_required) - Printv(get_pointers, "}\n", NIL); - - } else { - use_parse = 1; - Append(parse_args, parse); - if (parse_from_tuple) - Printf(arglist, "&%s", ln); - } - p = Getattr(p, "tmap:in:next"); - continue; - } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); - break; - } - } - - /* finish argument marshalling */ - Append(kwargs, " NULL }"); - if (allow_kwargs) { - Printv(f->locals, " char * kwnames[] = ", kwargs, ";\n", NIL); - } - - if (use_parse || allow_kwargs) { - Printf(parse_args, ":%s\"", iname); - Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL); - funpack = 0; - } else { - Clear(parse_args); - - if (funpack) { - Clear(f->def); - if (overname) { - if (noargs) { - Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL); - } else { - Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {", NIL); - } - /* Avoid warning if the self parameter is not used. */ - Append(f->def, "(void)self;\n"); - Printf(parse_args, "if ((nobjs < %d) || (nobjs > %d)) SWIG_fail;\n", num_required, num_arguments); - } else { - int is_tp_call = Equal(Getattr(n, "feature:python:slot"), "tp_call"); - Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL); - /* Avoid warning if the self parameter is not used. */ - Append(f->def, "(void)self;\n"); - if (builtin_ctor) - Printf(parse_args, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", iname); - if (onearg && !builtin_ctor && !is_tp_call) { - Printf(parse_args, "if (!args) SWIG_fail;\n"); - Append(parse_args, "swig_obj[0] = args;\n"); - } else if (!noargs) { - Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args, \"%s\", %d, %d, swig_obj)) SWIG_fail;\n", iname, num_fixed_arguments, tuple_arguments); - } else if (noargs) { - Printf(parse_args, "if (!SWIG_Python_UnpackTuple(args, \"%s\", %d, %d, 0)) SWIG_fail;\n", iname, num_fixed_arguments, tuple_arguments); - } - } - } else { - if (builtin_ctor) - Printf(parse_args, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", iname); - if (builtin && in_class && tuple_arguments == 0) { - Printf(parse_args, " if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, \"%s takes no arguments\");\n", iname); - } else { - Printf(parse_args, "if (!PyArg_UnpackTuple(args, \"%s\", %d, %d", iname, num_fixed_arguments, tuple_arguments); - Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL); - } - } - } - - /* Now piece together the first part of the wrapper function */ - Printv(f->code, self_parse, parse_args, get_pointers, NIL); - - /* Check for trailing varargs */ - if (varargs) { - if (p && (tm = Getattr(p, "tmap:in"))) { - Replaceall(tm, "$input", "varargs"); - Printv(f->code, tm, "\n", NIL); - } - } - - /* Insert constraint checking code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert cleanup code */ - for (p = l; p;) { - if (!Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) { - if (Getattr(p, "tmap:freearg:implicitconv")) { - const char *convflag = "0"; - if (!Getattr(p, "hidden")) { - SwigType *ptype = Getattr(p, "type"); - convflag = get_implicitconv_flag(classLookup(ptype)); - } - if (strcmp(convflag, "0") == 0) { - tm = 0; - } - } - if (tm && (Len(tm) != 0)) { - Printv(cleanup, tm, "\n", NIL); - } - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert argument output code */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - Replaceall(tm, "$arg", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - /* if the object is a director, and the method call originated from its - * underlying python object, resolve the call by going up the c++ - * inheritance chain. otherwise try to resolve the method in python. - * without this check an infinite loop is set up between the director and - * shadow class method calls. - */ - - // NOTE: this code should only be inserted if this class is the - // base class of a director class. however, in general we haven't - // yet analyzed all classes derived from this one to see if they are - // directors. furthermore, this class may be used as the base of - // a director class defined in a completely different module at a - // later time, so this test must be included whether or not directorbase - // is true. we do skip this code if directors have not been enabled - // at the command line to preserve source-level compatibility with - // non-polymorphic swig. also, if this wrapper is for a smart-pointer - // method, there is no need to perform the test since the calling object - // (the smart-pointer) and the director object (the "pointee") are - // distinct. - - director_method = is_member_director(n) && !is_smart_pointer() && !destructor; - if (director_method) { - Wrapper_add_local(f, "director", "Swig::Director *director = 0"); - Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n"); - if (dirprot_mode() && !is_public(n)) { - Printf(f->code, "if (!director || !(director->swig_get_inner(\"%s\"))) {\n", name); - Printf(f->code, "SWIG_SetErrorMsg(PyExc_RuntimeError,\"accessing protected member %s\");\n", name); - Append(f->code, "SWIG_fail;\n"); - Append(f->code, "}\n"); - } - Wrapper_add_local(f, "upcall", "bool upcall = false"); - if (funpack) { - const char *self_parm = builtin_self ? "self" : "swig_obj[0]"; - Printf(f->code, "upcall = (director && (director->swig_get_self()==%s));\n", self_parm); - } else { - const char *self_parm = builtin_self ? "self" : "obj0"; - Printf(f->code, "upcall = (director && (director->swig_get_self()==%s));\n", self_parm); - } - } - - /* Emit the function call */ - if (director_method) { - Append(f->code, "try {\n"); - } else { - if (allow_thread) { - String *preaction = NewString(""); - thread_begin_allow(n, preaction); - Setattr(n, "wrap:preaction", preaction); - - String *postaction = NewString(""); - thread_end_allow(n, postaction); - Setattr(n, "wrap:postaction", postaction); - } - } - - Setattr(n, "wrap:name", wname); - - Swig_director_emit_dynamic_cast(n, f); - String *actioncode = emit_action(n); - - if (director_method) { - Append(actioncode, "} catch (Swig::DirectorException&) {\n"); - Append(actioncode, " SWIG_fail;\n"); - Append(actioncode, "}\n"); - } - - /* This part below still needs cleanup */ - - /* Return the function value */ - tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode); - - if (tm) { - if (builtin_self) { - Replaceall(tm, "$self", "self"); - } else if (funpack) { - Replaceall(tm, "$self", "swig_obj[0]"); - } else { - Replaceall(tm, "$self", "obj0"); - } - Replaceall(tm, "$result", "resultobj"); - if (builtin_ctor) { - Replaceall(tm, "$owner", "SWIG_BUILTIN_INIT"); - } else if (handled_as_init) { - Replaceall(tm, "$owner", "SWIG_POINTER_NEW"); - } else { - if (GetFlag(n, "feature:new")) { - Replaceall(tm, "$owner", "SWIG_POINTER_OWN"); - } else { - Replaceall(tm, "$owner", "0"); - } - } - - // Unwrap return values that are director classes so that the original Python object is returned instead. - if (!constructor && Swig_director_can_unwrap(n)) { - Wrapper_add_local(f, "director", "Swig::Director *director = 0"); - Printf(f->code, "director = SWIG_DIRECTOR_CAST(%s);\n", Swig_cresult_name()); - Append(f->code, "if (director) {\n"); - Append(f->code, " resultobj = director->swig_get_self();\n"); - Append(f->code, " Py_INCREF(resultobj);\n"); - Append(f->code, "} else {\n"); - Printf(f->code, "%s\n", tm); - Append(f->code, "}\n"); - } else { - Printf(f->code, "%s\n", tm); - } - - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name); - } - emit_return_variable(n, d, f); - - /* Output argument output code */ - Printv(f->code, outarg, NIL); - - /* Output cleanup code */ - int need_cleanup = Len(cleanup) != 0; - if (need_cleanup) { - Printv(f->code, cleanup, NIL); - } - - /* Look to see if there is any newfree cleanup code */ - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - Delete(tm); - } - } - - /* See if there is any return cleanup code */ - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - Delete(tm); - } - - if (director_method) { - if ((tm = Swig_typemap_lookup("directorfree", n, Swig_cresult_name(), 0))) { - Replaceall(tm, "$input", Swig_cresult_name()); - Replaceall(tm, "$result", "resultobj"); - Printf(f->code, "%s\n", tm); - Delete(tm); - } - } - - if (builtin_ctor) - Append(f->code, " return resultobj == Py_None ? -1 : 0;\n"); - else - Append(f->code, " return resultobj;\n"); - - /* Error handling code */ - - Append(f->code, "fail:\n"); - if (need_cleanup) { - Printv(f->code, cleanup, NIL); - } - if (builtin_ctor) { - Printv(f->code, " return -1;\n", NIL); - } else { - if (GetFlag(n, "feature:python:maybecall")) { - Append(f->code, " PyErr_Clear();\n"); - Append(f->code, " Py_INCREF(Py_NotImplemented);\n"); - Append(f->code, " return Py_NotImplemented;\n"); - } else { - Printv(f->code, " return NULL;\n", NIL); - } - } - - Append(f->code, "}\n"); - - /* Substitute the cleanup code */ - Replaceall(f->code, "$cleanup", cleanup); - - /* Substitute the function name */ - Replaceall(f->code, "$symname", iname); - Replaceall(f->code, "$result", "resultobj"); - - if (builtin_self) { - Replaceall(f->code, "$self", "self"); - } else if (funpack) { - Replaceall(f->code, "$self", "swig_obj[0]"); - } else { - Replaceall(f->code, "$self", "obj0"); - } - - /* Dump the function out */ - Wrapper_print(f, f_wrappers); - - /* If varargs. Need to emit a varargs stub */ - if (varargs) { - DelWrapper(f); - f = NewWrapper(); - if (funpack) { - // Note: funpack is currently always false for varargs - Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {", NIL); - } else { - Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL); - } - Wrapper_add_local(f, "resultobj", builtin_ctor ? "int resultobj" : "PyObject *resultobj"); - Wrapper_add_local(f, "varargs", "PyObject *varargs"); - Wrapper_add_local(f, "newargs", "PyObject *newargs"); - if (funpack) { - Wrapper_add_local(f, "i", "int i"); - Printf(f->code, "newargs = PyTuple_New(%d);\n", num_fixed_arguments); - Printf(f->code, "for (i = 0; i < %d; ++i) {\n", num_fixed_arguments); - Printf(f->code, " PyTuple_SET_ITEM(newargs, i, swig_obj[i]);\n"); - Printf(f->code, " Py_XINCREF(swig_obj[i]);\n"); - Printf(f->code, "}\n"); - Printf(f->code, "varargs = PyTuple_New(nobjs > %d ? nobjs - %d : 0);\n", num_fixed_arguments, num_fixed_arguments); - Printf(f->code, "for (i = 0; i < nobjs - %d; ++i) {\n", num_fixed_arguments); - Printf(f->code, " PyTuple_SET_ITEM(newargs, i, swig_obj[i + %d]);\n", num_fixed_arguments); - Printf(f->code, " Py_XINCREF(swig_obj[i + %d]);\n", num_fixed_arguments); - Printf(f->code, "}\n"); - } else { - Printf(f->code, "newargs = PyTuple_GetSlice(args, 0, %d);\n", num_fixed_arguments); - Printf(f->code, "varargs = PyTuple_GetSlice(args, %d, PyTuple_Size(args));\n", num_fixed_arguments); - } - Printf(f->code, "resultobj = %s__varargs__(%s, newargs, varargs%s);\n", wname, builtin ? "self" : "NULL", strlen(builtin_kwargs) == 0 ? "" : ", kwargs"); - Append(f->code, "Py_XDECREF(newargs);\n"); - Append(f->code, "Py_XDECREF(varargs);\n"); - Append(f->code, "return resultobj;\n"); - Append(f->code, "}\n"); - Wrapper_print(f, f_wrappers); - } - - bool use_static_method = flat_static_method || !Swig_storage_isstatic_custom(n, "staticmemberfunctionHandler:storage"); - /* Now register the function with the interpreter. */ - if (!Getattr(n, "sym:overloaded")) { - if (!builtin_self && (use_static_method || !builtin)) - add_method(iname, wname, allow_kwargs, n, funpack, num_required, num_arguments); - - /* Create a shadow for this function (if enabled and not in a member function) */ - if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) { - emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, iname, allow_kwargs); - } - - } else { - if (!Getattr(n, "sym:nextSibling")) { - dispatchFunction(n, linkage, funpack, builtin_self, builtin_ctor, director_class, use_static_method); - } - } - - // Put this in tp_init of the PyTypeObject - if (builtin_ctor) { - if ((director_method || !is_private(n)) && !Getattr(class_members, iname)) { - Setattr(class_members, iname, n); - if (!builtin_tp_init) - builtin_tp_init = Swig_name_wrapper(iname); - } - } - - /* If this is a builtin type, create a PyGetSetDef entry for this member variable. */ - if (builtin) { - const char *memname = "__dict__"; - Hash *h = Getattr(builtin_getset, memname); - if (!h) { - h = NewHash(); - Setattr(builtin_getset, memname, h); - Delete(h); - } - Setattr(h, "getter", "SwigPyObject_get___dict__"); - if (!Getattr(h, "doc")) { - Setattr(n, "doc:high:name", Getattr(n, "name")); - Setattr(h, "doc", cdocstring(n, AUTODOC_VAR)); - } - } - - if (builtin_getter) { - String *memname = Getattr(n, "membervariableHandler:sym:name"); - if (!memname) - memname = iname; - Hash *h = Getattr(builtin_getset, memname); - if (!h) { - h = NewHash(); - Setattr(builtin_getset, memname, h); - Delete(h); - } - Setattr(h, "getter", wrapper_name); - Delattr(n, "memberget"); - if (!Getattr(h, "doc")) { - Setattr(n, "doc:high:name", Getattr(n, "name")); - String *ds = cdocstring(n, AUTODOC_VAR); - Setattr(h, "doc", ds); - Delete(ds); - } - } - if (builtin_setter) { - String *memname = Getattr(n, "membervariableHandler:sym:name"); - if (!memname) - memname = iname; - Hash *h = Getattr(builtin_getset, memname); - if (!h) { - h = NewHash(); - Setattr(builtin_getset, memname, h); - Delete(h); - } - Setattr(h, "setter", wrapper_name); - Delattr(n, "memberset"); - if (!Getattr(h, "doc")) { - Setattr(n, "doc:high:name", Getattr(n, "name")); - String *ds = cdocstring(n, AUTODOC_VAR); - Setattr(h, "doc", ds); - Delete(ds); - } - } - - if (in_class && builtin) { - /* Handle operator overloads for builtin types */ - String *slot = Getattr(n, "feature:python:slot"); - if (slot) { - String *func_type = Getattr(n, "feature:python:slot:functype"); - String *closure_decl = getClosure(func_type, wrapper_name, overname ? 0 : funpack); - String *feature_name = NewStringf("feature:python:%s", slot); - String *closure_name = 0; - if (closure_decl) { - closure_name = NewStringf("%s_%s_closure", wrapper_name, func_type); - if (!GetFlag(builtin_closures, closure_name)) - Printf(builtin_closures_code, "%s /* defines %s */\n\n", closure_decl, closure_name); - SetFlag(builtin_closures, closure_name); - Delete(closure_decl); - } else { - closure_name = Copy(wrapper_name); - } - if (func_type) { - String *s = NewStringf("%s", closure_name); - Delete(closure_name); - closure_name = s; - } - Setattr(parent, feature_name, closure_name); - Delete(feature_name); - Delete(closure_name); - } - - /* Handle comparison operators for builtin types */ - String *compare = Getattr(n, "feature:python:compare"); - if (compare) { - Hash *richcompare = Getattr(parent, "python:richcompare"); - assert(richcompare); - Setattr(richcompare, compare, wrapper_name); - } - } - - Delete(self_parse); - Delete(parse_args); - Delete(linkage); - Delete(arglist); - Delete(get_pointers); - Delete(cleanup); - Delete(outarg); - Delete(kwargs); - Delete(wname); - DelWrapper(f); - Delete(wrapper_name); - return SWIG_OK; - } - - - - /* ------------------------------------------------------------ - * variableWrapper() - * ------------------------------------------------------------ */ - - virtual int variableWrapper(Node *n) { - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - - static int have_globals = 0; - String *tm; - Wrapper *getf, *setf; - - if (!addSymbol(iname, n)) - return SWIG_ERROR; - - getf = NewWrapper(); - setf = NewWrapper(); - - /* If this is our first call, add the globals variable to the - Python dictionary. */ - - if (!have_globals) { - Printf(f_init, "\t globals = SWIG_globals();\n"); - Printf(f_init, "\t if (!globals) {\n"); - Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Failure to create SWIG globals.\");\n"); - Printf(f_init, "#if PY_VERSION_HEX >= 0x03000000\n"); - Printf(f_init, "\t return NULL;\n"); - Printf(f_init, "#else\n"); - Printf(f_init, "\t return;\n"); - Printf(f_init, "#endif\n"); - Printf(f_init, "\t }\n"); - Printf(f_init, "\t PyDict_SetItemString(md, \"%s\", globals);\n", global_name); - if (builtin) - Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", global_name); - have_globals = 1; - if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) { - Printf(f_shadow_stubs, "%s = %s.%s\n", global_name, module, global_name); - } - } - int assignable = is_assignable(n); - - if (!builtin && shadow && !assignable && !in_class) - Printf(f_shadow_stubs, "%s = %s.%s\n", iname, global_name, iname); - - String *getname = Swig_name_get(NSPACE_TODO, iname); - String *setname = Swig_name_set(NSPACE_TODO, iname); - String *vargetname = NewStringf("Swig_var_%s", getname); - String *varsetname = NewStringf("Swig_var_%s", setname); - - /* Create a function for setting the value of the variable */ - if (assignable) { - Setattr(n, "wrap:name", varsetname); - if (builtin && in_class) { - String *set_wrapper = Swig_name_wrapper(setname); - Setattr(n, "pybuiltin:setter", set_wrapper); - Delete(set_wrapper); - } - Printf(setf->def, "SWIGINTERN int %s(PyObject *_val) {", varsetname); - if ((tm = Swig_typemap_lookup("varin", n, name, 0))) { - Replaceall(tm, "$input", "_val"); - if (Getattr(n, "tmap:varin:implicitconv")) { - Replaceall(tm, "$implicitconv", get_implicitconv_flag(n)); - } - emit_action_code(n, setf->code, tm); - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0)); - } - Printv(setf->code, " return 0;\n", NULL); - Append(setf->code, "fail:\n"); - Printv(setf->code, " return 1;\n", NULL); - } else { - /* Is a readonly variable. Issue an error */ - if (CPlusPlus) { - Printf(setf->def, "SWIGINTERN int %s(PyObject *) {", varsetname); - } else { - Printf(setf->def, "SWIGINTERN int %s(PyObject *_val SWIGUNUSED) {", varsetname); - } - Printv(setf->code, " SWIG_Error(SWIG_AttributeError,\"Variable ", iname, " is read-only.\");\n", " return 1;\n", NIL); - } - - Append(setf->code, "}\n"); - Wrapper_print(setf, f_wrappers); - - /* Create a function for getting the value of a variable */ - Setattr(n, "wrap:name", vargetname); - if (builtin && in_class) { - String *get_wrapper = Swig_name_wrapper(getname); - Setattr(n, "pybuiltin:getter", get_wrapper); - Delete(get_wrapper); - } - int addfail = 0; - Printf(getf->def, "SWIGINTERN PyObject *%s(void) {", vargetname); - Wrapper_add_local(getf, "pyobj", "PyObject *pyobj = 0"); - if (builtin) { - Wrapper_add_local(getf, "self", "PyObject *self = 0"); - Append(getf->code, " (void)self;\n"); - } - if ((tm = Swig_typemap_lookup("varout", n, name, 0))) { - Replaceall(tm, "$result", "pyobj"); - addfail = emit_action_code(n, getf->code, tm); - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0)); - } - Append(getf->code, " return pyobj;\n"); - if (addfail) { - Append(getf->code, "fail:\n"); - Append(getf->code, " return NULL;\n"); - } - Append(getf->code, "}\n"); - - Wrapper_print(getf, f_wrappers); - - /* Now add this to the variable linking mechanism */ - Printf(f_init, "\t SWIG_addvarlink(globals, \"%s\", %s, %s);\n", iname, vargetname, varsetname); - if (builtin && shadow && !assignable && !in_class) { - Printf(f_init, "\t PyDict_SetItemString(md, \"%s\", PyObject_GetAttrString(globals, \"%s\"));\n", iname, iname); - Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", iname); - } - Delete(vargetname); - Delete(varsetname); - Delete(getname); - Delete(setname); - DelWrapper(setf); - DelWrapper(getf); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constantWrapper() - * ------------------------------------------------------------ */ - - /* Determine if the node requires the _swigconstant code to be generated */ - bool needs_swigconstant(Node *n) { - SwigType *type = Getattr(n, "type"); - SwigType *qtype = SwigType_typedef_resolve_all(type); - SwigType *uqtype = SwigType_strip_qualifiers(qtype); - bool result = false; - - /* Note, that we need special handling for function pointers, as - * SwigType_base(fptr) does not return the underlying pointer-to-function - * type but the return-type of function. */ - if (!SwigType_isfunction(uqtype) && !SwigType_isfunctionpointer(uqtype)) { - SwigType *basetype = SwigType_base(uqtype); - result = SwigType_isclass(basetype) != 0; - Delete(basetype); - } - - Delete(qtype); - Delete(uqtype); - - return result; - } - - virtual int constantWrapper(Node *n) { - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - String *rawval = Getattr(n, "rawval"); - String *value = rawval ? rawval : Getattr(n, "value"); - String *tm; - int have_tm = 0; - int have_builtin_symname = 0; - - if (!addSymbol(iname, n)) - return SWIG_ERROR; - - /* Special hook for member pointer */ - if (SwigType_type(type) == T_MPOINTER) { - String *wname = Swig_name_wrapper(iname); - String *str = SwigType_str(type, wname); - Printf(f_header, "static %s = %s;\n", str, value); - Delete(str); - value = wname; - } - - if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) { - Replaceall(tm, "$value", value); - Printf(const_code, "%s,\n", tm); - Delete(tm); - have_tm = 1; - } - - - if (builtin && in_class && Getattr(n, "pybuiltin:symname")) { - have_builtin_symname = 1; - Swig_require("builtin_constantWrapper", n, "*sym:name", "pybuiltin:symname", NIL); - Setattr(n, "sym:name", Getattr(n, "pybuiltin:symname")); - } - - if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) { - Replaceall(tm, "$value", value); - if (needs_swigconstant(n) && !builtin && shadow && !(shadow & PYSHADOW_MEMBER) && (!in_class || !Getattr(n, "feature:python:callback"))) { - // Generate `*_swigconstant()` method which registers the new constant. - // - // *_swigconstant methods are required for constants of class type. - // Class types are registered in shadow file (see *_swigregister). The - // instances of class must be created (registered) after the type is - // registered, so we can't let SWIG_init() to register constants of - // class type (the SWIG_init() is called before shadow classes are - // defined and registered). - Printf(f_wrappers, "SWIGINTERN PyObject *%s_swigconstant(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", iname); - Printf(f_wrappers, tab2 "PyObject *module;\n"); - Printf(f_wrappers, tab2 "PyObject *d;\n"); - Printf(f_wrappers, tab2 "if (!SWIG_Python_UnpackTuple(args, \"swigconstant\", 1, 1, &module)) return NULL;\n"); - Printf(f_wrappers, tab2 "d = PyModule_GetDict(module);\n"); - Printf(f_wrappers, tab2 "if (!d) return NULL;\n"); - Printf(f_wrappers, tab2 "%s\n", tm); - Printf(f_wrappers, tab2 "return SWIG_Py_Void();\n"); - Printf(f_wrappers, "}\n\n\n"); - - // Register the method in SwigMethods array - String *cname = NewStringf("%s_swigconstant", iname); - add_method(cname, cname, 0, 0, 1, 1, 1); - Delete(cname); - } else { - Printf(f_init, "%s\n", tm); - } - Delete(tm); - have_tm = 1; - } - - if (have_builtin_symname) - Swig_restore(n); - - if (!have_tm) { - Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); - return SWIG_NOWRAP; - } - - if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) { - String *f_s; - if (!in_class) { - f_s = f_shadow; - } else { - f_s = Getattr(n, "feature:python:callback") ? NIL : f_shadow_stubs; - } - - if (f_s) { - if (needs_swigconstant(n)) { - Printv(f_s, "\n",NIL); - Printv(f_s, module, ".", iname, "_swigconstant(",module,")\n", NIL); - } - Printv(f_s, iname, " = ", module, ".", iname, "\n", NIL); - if (have_docstring(n)) - Printv(f_s, docstring(n, AUTODOC_CONST, tab4), "\n", NIL); - } - } - return SWIG_OK; - } - - - /* ------------------------------------------------------------ - * nativeWrapper() - * ------------------------------------------------------------ */ - - virtual int nativeWrapper(Node *n) { - String *name = Getattr(n, "sym:name"); - String *wrapname = Getattr(n, "wrap:name"); - - if (!addSymbol(wrapname, n)) - return SWIG_ERROR; - - add_method(name, wrapname, 0); - if (!builtin && shadow) { - Printv(f_shadow_stubs, name, " = ", module, ".", name, "\n", NIL); - } - return SWIG_OK; - } - - - - /* ---------------------------------------------------------------------------- - * BEGIN C++ Director Class modifications - * ------------------------------------------------------------------------- */ - - /* C++/Python polymorphism demo code - * - * TODO - * - * Move some boilerplate code generation to Swig_...() functions. - * - */ - - /* --------------------------------------------------------------- - * classDirectorMethod() - * - * Emit a virtual director method to pass a method call on to the - * underlying Python object. - * ** Moved down due to gcc-2.96 internal error ** - * --------------------------------------------------------------- */ - - int classDirectorMethods(Node *n); - - int classDirectorMethod(Node *n, Node *parent, String *super); - - /* ------------------------------------------------------------ - * classDirectorConstructor() - * ------------------------------------------------------------ */ - - int classDirectorConstructor(Node *n) { - Node *parent = Getattr(n, "parentNode"); - String *sub = NewString(""); - String *decl = Getattr(n, "decl"); - String *supername = Swig_class_name(parent); - String *classname = NewString(""); - Printf(classname, "SwigDirector_%s", supername); - - /* insert self parameter */ - Parm *p; - ParmList *superparms = Getattr(n, "parms"); - ParmList *parms = CopyParmList(superparms); - String *type = NewString("PyObject"); - SwigType_add_pointer(type); - p = NewParm(type, NewString("self"), n); - set_nextSibling(p, parms); - parms = p; - - if (!Getattr(n, "defaultargs")) { - /* constructor */ - { - Wrapper *w = NewWrapper(); - String *call; - String *basetype = Getattr(parent, "classtype"); - String *target = Swig_method_decl(0, decl, classname, parms, 0); - call = Swig_csuperclass_call(0, basetype, superparms); - Printf(w->def, "%s::%s: %s, Swig::Director(self) { \n", classname, target, call); - Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype); - Append(w->def, "}\n"); - Delete(target); - Wrapper_print(w, f_directors); - Delete(call); - DelWrapper(w); - } - - /* constructor header */ - { - String *target = Swig_method_decl(0, decl, classname, parms, 1); - Printf(f_directors_h, " %s;\n", target); - Delete(target); - } - } - - Delete(sub); - Delete(classname); - Delete(supername); - Delete(parms); - return Language::classDirectorConstructor(n); - } - - /* ------------------------------------------------------------ - * classDirectorDefaultConstructor() - * ------------------------------------------------------------ */ - - int classDirectorDefaultConstructor(Node *n) { - String *classname = Swig_class_name(n); - { - Node *parent = Swig_methodclass(n); - String *basetype = Getattr(parent, "classtype"); - Wrapper *w = NewWrapper(); - Printf(w->def, "SwigDirector_%s::SwigDirector_%s(PyObject *self) : Swig::Director(self) { \n", classname, classname); - Printf(w->def, " SWIG_DIRECTOR_RGTR((%s *)this, this); \n", basetype); - Append(w->def, "}\n"); - Wrapper_print(w, f_directors); - DelWrapper(w); - } - Printf(f_directors_h, " SwigDirector_%s(PyObject *self);\n", classname); - Delete(classname); - return Language::classDirectorDefaultConstructor(n); - } - - - /* ------------------------------------------------------------ - * classDirectorInit() - * ------------------------------------------------------------ */ - - int classDirectorInit(Node *n) { - String *declaration = Swig_director_declaration(n); - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "%s\n", declaration); - Printf(f_directors_h, "public:\n"); - Delete(declaration); - return Language::classDirectorInit(n); - } - - /* ------------------------------------------------------------ - * classDirectorEnd() - * ------------------------------------------------------------ */ - - int classDirectorEnd(Node *n) { - String *classname = Swig_class_name(n); - - if (dirprot_mode()) { - /* - This implementation uses a std::map<std::string,int>. - - It should be possible to rewrite it using a more elegant way, - like copying the Java approach for the 'override' array. - - But for now, this seems to be the least intrusive way. - */ - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "/* Internal director utilities */\n"); - Printf(f_directors_h, "public:\n"); - Printf(f_directors_h, " bool swig_get_inner(const char *swig_protected_method_name) const {\n"); - Printf(f_directors_h, " std::map<std::string, bool>::const_iterator iv = swig_inner.find(swig_protected_method_name);\n"); - Printf(f_directors_h, " return (iv != swig_inner.end() ? iv->second : false);\n"); - Printf(f_directors_h, " }\n"); - - Printf(f_directors_h, " void swig_set_inner(const char *swig_protected_method_name, bool swig_val) const {\n"); - Printf(f_directors_h, " swig_inner[swig_protected_method_name] = swig_val;\n"); - Printf(f_directors_h, " }\n"); - Printf(f_directors_h, "private:\n"); - Printf(f_directors_h, " mutable std::map<std::string, bool> swig_inner;\n"); - - } - if (director_method_index) { - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n"); - Printf(f_directors_h, "/* VTable implementation */\n"); - Printf(f_directors_h, " PyObject *swig_get_method(size_t method_index, const char *method_name) const {\n"); - Printf(f_directors_h, " PyObject *method = vtable[method_index];\n"); - Printf(f_directors_h, " if (!method) {\n"); - Printf(f_directors_h, " swig::SwigVar_PyObject name = SWIG_Python_str_FromChar(method_name);\n"); - Printf(f_directors_h, " method = PyObject_GetAttr(swig_get_self(), name);\n"); - Printf(f_directors_h, " if (!method) {\n"); - Printf(f_directors_h, " std::string msg = \"Method in class %s doesn't exist, undefined \";\n", classname); - Printf(f_directors_h, " msg += method_name;\n"); - Printf(f_directors_h, " Swig::DirectorMethodException::raise(msg.c_str());\n"); - Printf(f_directors_h, " }\n"); - Printf(f_directors_h, " vtable[method_index] = method;\n"); - Printf(f_directors_h, " }\n"); - Printf(f_directors_h, " return method;\n"); - Printf(f_directors_h, " }\n"); - Printf(f_directors_h, "private:\n"); - Printf(f_directors_h, " mutable swig::SwigVar_PyObject vtable[%d];\n", director_method_index); - Printf(f_directors_h, "#endif\n\n"); - } - - Printf(f_directors_h, "};\n\n"); - return Language::classDirectorEnd(n); - } - - - /* ------------------------------------------------------------ - * classDirectorDisown() - * ------------------------------------------------------------ */ - - int classDirectorDisown(Node *n) { - int result; - int oldshadow = shadow; - /* disable shadowing */ - if (shadow) - shadow = shadow | PYSHADOW_MEMBER; - result = Language::classDirectorDisown(n); - shadow = oldshadow; - if (shadow) { - if (builtin) { - String *rname = SwigType_namestr(real_classname); - Printf(builtin_methods, " { \"__disown__\", Swig::Director::swig_pyobj_disown< %s >, METH_NOARGS, \"\" },\n", rname); - Delete(rname); - } else { - String *symname = Getattr(n, "sym:name"); - String *mrename = Swig_name_disown(NSPACE_TODO, symname); //Getattr(n, "name")); - Printv(f_shadow, tab4, "def __disown__(self):\n", NIL); - Printv(f_shadow, tab8, "self.this.disown()\n", NIL); - Printv(f_shadow, tab8, module, ".", mrename, "(self)\n", NIL); - Printv(f_shadow, tab8, "return weakref.proxy(self)\n", NIL); - Delete(mrename); - } - } - return result; - } - - /* ---------------------------------------------------------------------------- - * END of C++ Director Class modifications - * ------------------------------------------------------------------------- */ - - - /* ------------------------------------------------------------ - * classDeclaration() - * ------------------------------------------------------------ */ - - virtual int classDeclaration(Node *n) { - if (shadow && !Getattr(n, "feature:onlychildren")) { - Node *mod = Getattr(n, "module"); - if (mod) { - String *modname = Getattr(mod, "name"); - Node *options = Getattr(mod, "options"); - String *pkg = options ? Getattr(options, "package") : 0; - String *sym = Getattr(n, "sym:name"); - String *importname = import_name_string(package, mainmodule, pkg, modname, sym); - Setattr(n, "python:proxy", importname); - Delete(importname); - } - } - int result = Language::classDeclaration(n); - return result; - } - - /* ------------------------------------------------------------ - * classHandler() - * ------------------------------------------------------------ */ - - String *add_explicit_scope(String *s) { - if (!Strstr(s, "::")) { - String *ss = NewStringf("::%s", s); - Delete(s); - s = ss; - } - return s; - } - - void builtin_pre_decl(Node *n) { - String *name = Getattr(n, "name"); - String *rname = add_explicit_scope(SwigType_namestr(name)); - String *mname = SwigType_manglestr(rname); - - Printf(f_init, "\n/* type '%s' */\n", rname); - Printf(f_init, " builtin_pytype = (PyTypeObject *)&SwigPyBuiltin_%s_type;\n", mname); - Printf(f_init, " builtin_pytype->tp_dict = d = PyDict_New();\n"); - - Delete(rname); - Delete(mname); - } - - void builtin_post_decl(File *f, Node *n) { - String *name = Getattr(n, "name"); - String *pname = Copy(name); - SwigType_add_pointer(pname); - String *symname = Getattr(n, "sym:name"); - String *rname = add_explicit_scope(SwigType_namestr(name)); - String *mname = SwigType_manglestr(rname); - String *pmname = SwigType_manglestr(pname); - String *templ = NewStringf("SwigPyBuiltin_%s", mname); - int funpack = fastunpack; - static String *tp_new = NewString("PyType_GenericNew"); - - if (have_builtin_static_member_method_callback) { - Printf(f_init, " SWIG_Python_FixMethods(SwigPyBuiltin_%s_methods, swig_const_table, swig_types, swig_type_initial);\n", mname); - } - - Printv(f_init, " SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);\n", NIL); - - // We can’t statically initialize a structure member with a function defined in another C module - // So this is done in the initialization function instead, see https://docs.python.org/2/extending/newtypes.html - Printf(f_init, " builtin_pytype->tp_new = %s;\n", getSlot(n, "feature:python:tp_new", tp_new)); - - Printv(f_init, " builtin_base_count = 0;\n", NIL); - List *baselist = Getattr(n, "bases"); - if (baselist) { - int base_count = 0; - for (Iterator b = First(baselist); b.item; b = Next(b)) { - String *bname = Getattr(b.item, "name"); - if (!bname || GetFlag(b.item, "feature:ignore")) - continue; - base_count++; - String *base_name = Copy(bname); - SwigType_add_pointer(base_name); - String *base_mname = SwigType_manglestr(base_name); - Printf(f_init, " builtin_basetype = SWIG_MangledTypeQuery(\"%s\");\n", base_mname); - Printv(f_init, " if (builtin_basetype && builtin_basetype->clientdata && ((SwigPyClientData *) builtin_basetype->clientdata)->pytype) {\n", NIL); - Printv(f_init, " builtin_bases[builtin_base_count++] = ((SwigPyClientData *) builtin_basetype->clientdata)->pytype;\n", NIL); - Printv(f_init, " } else {\n", NIL); - Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Could not create type '%s' as base '%s' has not been initialized.\\n\");\n", symname, bname); - Printv(f_init, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - Printv(f_init, " return NULL;\n", NIL); - Printv(f_init, "#else\n", NIL); - Printv(f_init, " return;\n", NIL); - Printv(f_init, "#endif\n", NIL); - Printv(f_init, " }\n", NIL); - Delete(base_name); - Delete(base_mname); - } - if (base_count > max_bases) - max_bases = base_count; - } - Printv(f_init, " builtin_bases[builtin_base_count] = NULL;\n", NIL); - Printv(f_init, " SwigPyBuiltin_InitBases(builtin_pytype, builtin_bases);\n", NIL); - builtin_bases_needed = 1; - - // Check for non-public destructor, in which case tp_dealloc will issue - // a warning and allow the memory to leak. Any class that doesn't explicitly - // have a private/protected destructor has an implicit public destructor. - static String *tp_dealloc_bad = NewString("SwigPyBuiltin_BadDealloc"); - - String *getset_name = NewStringf("%s_getset", templ); - String *methods_name = NewStringf("%s_methods", templ); - String *getset_def = NewString(""); - Printf(getset_def, "SWIGINTERN PyGetSetDef %s[] = {\n", getset_name); - - // All objects have 'this' and 'thisown' attributes - Printv(f_init, "PyDict_SetItemString(d, \"this\", this_descr);\n", NIL); - Printv(f_init, "PyDict_SetItemString(d, \"thisown\", thisown_descr);\n", NIL); - - // Now, the rest of the attributes - for (Iterator member_iter = First(builtin_getset); member_iter.item; member_iter = Next(member_iter)) { - String *memname = member_iter.key; - Hash *mgetset = member_iter.item; - String *getter = Getattr(mgetset, "getter"); - String *setter = Getattr(mgetset, "setter"); - const char *getter_closure = getter ? funpack ? "SwigPyBuiltin_FunpackGetterClosure" : "SwigPyBuiltin_GetterClosure" : "0"; - const char *setter_closure = setter ? funpack ? "SwigPyBuiltin_FunpackSetterClosure" : "SwigPyBuiltin_SetterClosure" : "0"; - String *gspair = NewStringf("%s_%s_getset", symname, memname); - Printf(f, "static SwigPyGetSet %s = { %s, %s };\n", gspair, getter ? getter : "0", setter ? setter : "0"); - String *doc = Getattr(mgetset, "doc"); - if (!doc) - doc = NewStringf("%s.%s", name, memname); - String *entry = NewStringf("{ (char *)\"%s\", %s, %s, (char *)\"%s\", &%s }", memname, getter_closure, setter_closure, doc, gspair); - if (GetFlag(mgetset, "static")) { - Printf(f, "static PyGetSetDef %s_def = %s;\n", gspair, entry); - Printf(f_init, "static_getset = SwigPyStaticVar_new_getset(metatype, &%s_def);\n", gspair); - Printf(f_init, "PyDict_SetItemString(d, static_getset->d_getset->name, (PyObject *) static_getset);\n"); - Printf(f_init, "Py_DECREF(static_getset);\n"); - } else { - Printf(getset_def, " %s,\n", entry); - } - Delete(gspair); - Delete(entry); - } - Printv(f, getset_def, " { NULL, NULL, NULL, NULL, NULL } /* Sentinel */\n", "};\n\n", NIL); - - // Rich compare function - Hash *richcompare = Getattr(n, "python:richcompare"); - String *richcompare_func = NewStringf("%s_richcompare", templ); - assert(richcompare); - Printf(f, "SWIGINTERN PyObject *\n"); - Printf(f, "%s(PyObject *self, PyObject *other, int op) {\n", richcompare_func); - Printf(f, " PyObject *result = NULL;\n"); - if (!funpack) { - Printf(f, " PyObject *tuple = PyTuple_New(1);\n"); - Printf(f, " assert(tuple);\n"); - Printf(f, " PyTuple_SET_ITEM(tuple, 0, other);\n"); - Printf(f, " Py_XINCREF(other);\n"); - } - List *richcompare_list = SortedKeys(richcompare, 0); - Iterator rich_iter = First(richcompare_list); - if (rich_iter.item) { - Printf(f, " switch (op) {\n"); - for (; rich_iter.item; rich_iter = Next(rich_iter)) - Printf(f, " case %s : result = %s(self, %s); break;\n", rich_iter.item, Getattr(richcompare, rich_iter.item), funpack ? "other" : "tuple"); - Printv(f, " default : break;\n", NIL); - Printf(f, " }\n"); - } - Delete(richcompare_list); - Printv(f, " if (!result) {\n", NIL); - Printv(f, " if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {\n", NIL); - Printv(f, " result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);\n", NIL); - Printv(f, " } else {\n", NIL); - Printv(f, " result = Py_NotImplemented;\n", NIL); - Printv(f, " Py_INCREF(result);\n", NIL); - Printv(f, " }\n", NIL); - Printv(f, " }\n", NIL); - if (!funpack) - Printf(f, " Py_DECREF(tuple);\n"); - Printf(f, " return result;\n"); - Printf(f, "}\n\n"); - - // Methods - Printf(f, "SWIGINTERN PyMethodDef %s_methods[] = {\n", templ); - Dump(builtin_methods, f); - Printf(f, " { NULL, NULL, 0, NULL } /* Sentinel */\n};\n\n"); - - // No instance dict for nondynamic objects - if (GetFlag(n, "feature:python:nondynamic")) - Setattr(n, "feature:python:tp_setattro", "SWIG_Python_NonDynamicSetAttr"); - - Node *mod = Getattr(n, "module"); - String *modname = mod ? Getattr(mod, "name") : 0; - String *quoted_symname; - if (package) { - if (modname) - quoted_symname = NewStringf("\"%s.%s.%s\"", package, modname, symname); - else - quoted_symname = NewStringf("\"%s.%s\"", package, symname); - } else { - if (modname) - quoted_symname = NewStringf("\"%s.%s\"", modname, symname); - else - quoted_symname = NewStringf("\"%s\"", symname); - } - String *quoted_tp_doc_str = NewStringf("\"%s\"", getSlot(n, "feature:python:tp_doc")); - String *tp_init = NewString(builtin_tp_init ? Char(builtin_tp_init) : Swig_directorclass(n) ? "0" : "SwigPyBuiltin_BadInit"); - String *tp_flags = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_CHECKTYPES"); - String *tp_flags_py3 = NewString("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE"); - - static String *tp_basicsize = NewStringf("sizeof(SwigPyObject)"); - static String *tp_dictoffset_default = NewString("offsetof(SwigPyObject, dict)"); - static String *tp_hash = NewString("SwigPyObject_hash"); - String *tp_as_number = NewStringf("&%s_type.as_number", templ); - String *tp_as_sequence = NewStringf("&%s_type.as_sequence", templ); - String *tp_as_mapping = NewStringf("&%s_type.as_mapping", templ); - String *tp_as_buffer = NewStringf("&%s_type.as_buffer", templ); - - Printf(f, "static PyHeapTypeObject %s_type = {\n", templ); - - // PyTypeObject ht_type - Printf(f, " {\n"); - Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - Printv(f, " PyVarObject_HEAD_INIT(NULL, 0)\n", NIL); - Printv(f, "#else\n", NIL); - Printf(f, " PyObject_HEAD_INIT(NULL)\n"); - printSlot(f, getSlot(), "ob_size"); - Printv(f, "#endif\n", NIL); - printSlot(f, quoted_symname, "tp_name"); - printSlot(f, getSlot(n, "feature:python:tp_basicsize", tp_basicsize), "tp_basicsize"); - printSlot(f, getSlot(n, "feature:python:tp_itemsize"), "tp_itemsize"); - printSlot(f, getSlot(n, "feature:python:tp_dealloc", tp_dealloc_bad), "tp_dealloc", "destructor"); - Printv(f, "#if PY_VERSION_HEX < 0x030800b4\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_print"), "tp_print", "printfunc"); - Printv(f, "#else\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_vectorcall_offset"), "tp_vectorcall_offset", "Py_ssize_t"); - Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_getattr"), "tp_getattr", "getattrfunc"); - printSlot(f, getSlot(n, "feature:python:tp_setattr"), "tp_setattr", "setattrfunc"); - Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_compare"), "tp_compare"); - Printv(f, "#else\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_compare"), "tp_compare", "cmpfunc"); - Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_repr"), "tp_repr", "reprfunc"); - printSlot(f, getSlot(n, "feature:python:tp_as_number", tp_as_number), "tp_as_number"); - printSlot(f, getSlot(n, "feature:python:tp_as_sequence", tp_as_sequence), "tp_as_sequence"); - printSlot(f, getSlot(n, "feature:python:tp_as_mapping", tp_as_mapping), "tp_as_mapping"); - printSlot(f, getSlot(n, "feature:python:tp_hash", tp_hash), "tp_hash", "hashfunc"); - printSlot(f, getSlot(n, "feature:python:tp_call"), "tp_call", "ternaryfunc"); - printSlot(f, getSlot(n, "feature:python:tp_str"), "tp_str", "reprfunc"); - printSlot(f, getSlot(n, "feature:python:tp_getattro"), "tp_getattro", "getattrofunc"); - printSlot(f, getSlot(n, "feature:python:tp_setattro"), "tp_setattro", "setattrofunc"); - printSlot(f, getSlot(n, "feature:python:tp_as_buffer", tp_as_buffer), "tp_as_buffer"); - Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_flags", tp_flags_py3), "tp_flags"); - Printv(f, "#else\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_flags", tp_flags), "tp_flags"); - Printv(f, "#endif\n", NIL); - if (have_docstring(n)) { - String *ds = cdocstring(n, AUTODOC_CLASS); - String *tp_doc = NewString(""); - Printf(tp_doc, "\"%s\"", ds); - Delete(ds); - printSlot(f, tp_doc, "tp_doc"); - Delete(tp_doc); - } else { - printSlot(f, quoted_tp_doc_str, "tp_doc"); - } - printSlot(f, getSlot(n, "feature:python:tp_traverse"), "tp_traverse", "traverseproc"); - printSlot(f, getSlot(n, "feature:python:tp_clear"), "tp_clear", "inquiry"); - printSlot(f, getSlot(n, "feature:python:tp_richcompare", richcompare_func), "tp_richcompare", "richcmpfunc"); - printSlot(f, getSlot(n, "feature:python:tp_weaklistoffset"), "tp_weaklistoffset"); - printSlot(f, getSlot(n, "feature:python:tp_iter"), "tp_iter", "getiterfunc"); - printSlot(f, getSlot(n, "feature:python:tp_iternext"), "tp_iternext", "iternextfunc"); - printSlot(f, getSlot(n, "feature:python:tp_methods", methods_name), "tp_methods"); - printSlot(f, getSlot(n, "feature:python:tp_members"), "tp_members"); - printSlot(f, getSlot(n, "feature:python:tp_getset", getset_name), "tp_getset"); - printSlot(f, getSlot(n, "feature:python:tp_base"), "tp_base"); - printSlot(f, getSlot(n, "feature:python:tp_dict"), "tp_dict"); - printSlot(f, getSlot(n, "feature:python:tp_descr_get"), "tp_descr_get", "descrgetfunc"); - printSlot(f, getSlot(n, "feature:python:tp_descr_set"), "tp_descr_set", "descrsetfunc"); - printSlot(f, getSlot(n, "feature:python:tp_dictoffset", tp_dictoffset_default), "tp_dictoffset", "Py_ssize_t"); - printSlot(f, getSlot(n, "feature:python:tp_init", tp_init), "tp_init", "initproc"); - printSlot(f, getSlot(n, "feature:python:tp_alloc"), "tp_alloc", "allocfunc"); - printSlot(f, getSlot(), "tp_new", "newfunc"); - printSlot(f, getSlot(n, "feature:python:tp_free"), "tp_free", "freefunc"); - printSlot(f, getSlot(n, "feature:python:tp_is_gc"), "tp_is_gc", "inquiry"); - printSlot(f, getSlot(n, "feature:python:tp_bases"), "tp_bases", "PyObject *"); - printSlot(f, getSlot(n, "feature:python:tp_mro"), "tp_mro", "PyObject *"); - printSlot(f, getSlot(n, "feature:python:tp_cache"), "tp_cache", "PyObject *"); - printSlot(f, getSlot(n, "feature:python:tp_subclasses"), "tp_subclasses", "PyObject *"); - printSlot(f, getSlot(n, "feature:python:tp_weaklist"), "tp_weaklist", "PyObject *"); - printSlot(f, getSlot(n, "feature:python:tp_del"), "tp_del", "destructor"); - printSlot(f, getSlot(n, "feature:python:tp_version_tag"), "tp_version_tag", "int"); - Printv(f, "#if PY_VERSION_HEX >= 0x03040000\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_finalize"), "tp_finalize", "destructor"); - Printv(f, "#endif\n", NIL); - Printv(f, "#if PY_VERSION_HEX >= 0x03080000\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_vectorcall"), "tp_vectorcall", "vectorcallfunc"); - Printv(f, "#endif\n", NIL); - Printv(f, "#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)\n", NIL); - printSlot(f, getSlot(), "tp_print"); - Printv(f, "#endif\n", NIL); - - Printv(f, "#ifdef COUNT_ALLOCS\n", NIL); - printSlot(f, getSlot(n, "feature:python:tp_allocs"), "tp_allocs", "Py_ssize_t"); - printSlot(f, getSlot(n, "feature:python:tp_frees"), "tp_frees", "Py_ssize_t"); - printSlot(f, getSlot(n, "feature:python:tp_maxalloc"), "tp_maxalloc", "Py_ssize_t"); - printSlot(f, getSlot(n, "feature:python:tp_prev"), "tp_prev"); - printSlot(f, getSlot(n, "feature:python:tp_next"), "tp_next"); - Printv(f, "#endif\n", NIL); - Printf(f, " },\n"); - - // PyAsyncMethods as_async - Printv(f, "#if PY_VERSION_HEX >= 0x03050000\n", NIL); - Printf(f, " {\n"); - printSlot(f, getSlot(n, "feature:python:am_await"), "am_await", "unaryfunc"); - printSlot(f, getSlot(n, "feature:python:am_aiter"), "am_aiter", "unaryfunc"); - printSlot(f, getSlot(n, "feature:python:am_anext"), "am_anext", "unaryfunc"); - Printv(f, "# if PY_VERSION_HEX >= 0x030a0000\n", NIL); - printSlot(f, getSlot(n, "feature:python:am_send"), "am_send", "sendfunc"); - Printv(f, "# endif\n", NIL); - Printf(f, " },\n"); - Printv(f, "#endif\n", NIL); - - // PyNumberMethods as_number - Printf(f, " {\n"); - printSlot(f, getSlot(n, "feature:python:nb_add"), "nb_add", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_subtract"), "nb_subtract", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_multiply"), "nb_multiply", "binaryfunc"); - Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_divide"), "nb_divide", "binaryfunc"); - Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_remainder"), "nb_remainder", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_divmod"), "nb_divmod", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_power"), "nb_power", "ternaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_negative"), "nb_negative", "unaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_positive"), "nb_positive", "unaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_absolute"), "nb_absolute", "unaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_nonzero"), "nb_nonzero", "inquiry"); - printSlot(f, getSlot(n, "feature:python:nb_invert"), "nb_invert", "unaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_lshift"), "nb_lshift", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_rshift"), "nb_rshift", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_and"), "nb_and", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_xor"), "nb_xor", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_or"), "nb_or", "binaryfunc"); - Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_coerce"), "nb_coerce", "coercion"); - Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_int"), "nb_int", "unaryfunc"); - Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_reserved"), "nb_reserved", "void *"); - Printv(f, "#else\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_long"), "nb_long", "unaryfunc"); - Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_float"), "nb_float", "unaryfunc"); - Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_oct"), "nb_oct", "unaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_hex"), "nb_hex", "unaryfunc"); - Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_inplace_add"), "nb_inplace_add", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_subtract"), "nb_inplace_subtract", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_multiply"), "nb_inplace_multiply", "binaryfunc"); - Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_inplace_divide"), "nb_inplace_divide", "binaryfunc"); - Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_inplace_remainder"), "nb_inplace_remainder", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_power"), "nb_inplace_power", "ternaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_lshift"), "nb_inplace_lshift", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_rshift"), "nb_inplace_rshift", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_and"), "nb_inplace_and", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_xor"), "nb_inplace_xor", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_or"), "nb_inplace_or", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_floor_divide"), "nb_floor_divide", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_divide"), "nb_true_divide", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_floor_divide"), "nb_inplace_floor_divide", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_divide"), "nb_inplace_true_divide", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_index"), "nb_index", "unaryfunc"); - Printv(f, "#if PY_VERSION_HEX >= 0x03050000\n", NIL); - printSlot(f, getSlot(n, "feature:python:nb_matrix_multiply"), "nb_matrix_multiply", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:nb_inplace_matrix_multiply"), "nb_inplace_matrix_multiply", "binaryfunc"); - Printv(f, "#endif\n", NIL); - Printf(f, " },\n"); - - // PyMappingMethods as_mapping; - Printf(f, " {\n"); - printSlot(f, getSlot(n, "feature:python:mp_length"), "mp_length", "lenfunc"); - printSlot(f, getSlot(n, "feature:python:mp_subscript"), "mp_subscript", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:mp_ass_subscript"), "mp_ass_subscript", "objobjargproc"); - Printf(f, " },\n"); - - // PySequenceMethods as_sequence; - Printf(f, " {\n"); - printSlot(f, getSlot(n, "feature:python:sq_length"), "sq_length", "lenfunc"); - printSlot(f, getSlot(n, "feature:python:sq_concat"), "sq_concat", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:sq_repeat"), "sq_repeat", "ssizeargfunc"); - printSlot(f, getSlot(n, "feature:python:sq_item"), "sq_item", "ssizeargfunc"); - Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:was_sq_slice"), "was_sq_slice", "void *"); - Printv(f, "#else\n", NIL); - printSlot(f, getSlot(n, "feature:python:sq_slice"), "sq_slice", "ssizessizeargfunc"); - Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:sq_ass_item"), "sq_ass_item", "ssizeobjargproc"); - Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:was_sq_ass_slice"), "was_sq_ass_slice", "void *"); - Printv(f, "#else\n", NIL); - printSlot(f, getSlot(n, "feature:python:sq_ass_slice"), "sq_ass_slice", "ssizessizeobjargproc"); - Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:sq_contains"), "sq_contains", "objobjproc"); - printSlot(f, getSlot(n, "feature:python:sq_inplace_concat"), "sq_inplace_concat", "binaryfunc"); - printSlot(f, getSlot(n, "feature:python:sq_inplace_repeat"), "sq_inplace_repeat", "ssizeargfunc"); - Printf(f, " },\n"); - - // PyBufferProcs as_buffer; - Printf(f, " {\n"); - Printv(f, "#if PY_VERSION_HEX < 0x03000000\n", NIL); - printSlot(f, getSlot(n, "feature:python:bf_getreadbuffer"), "bf_getreadbuffer", "readbufferproc"); - printSlot(f, getSlot(n, "feature:python:bf_getwritebuffer"), "bf_getwritebuffer", "writebufferproc"); - printSlot(f, getSlot(n, "feature:python:bf_getsegcount"), "bf_getsegcount", "segcountproc"); - printSlot(f, getSlot(n, "feature:python:bf_getcharbuffer"), "bf_getcharbuffer", "charbufferproc"); - Printv(f, "#endif\n", NIL); - printSlot(f, getSlot(n, "feature:python:bf_getbuffer"), "bf_getbuffer", "getbufferproc"); - printSlot(f, getSlot(n, "feature:python:bf_releasebuffer"), "bf_releasebuffer", "releasebufferproc"); - Printf(f, " },\n"); - - // PyObject *ht_name, *ht_slots, *ht_qualname; - printSlot(f, getSlot(n, "feature:python:ht_name"), "ht_name", "PyObject *"); - printSlot(f, getSlot(n, "feature:python:ht_slots"), "ht_slots", "PyObject *"); - Printv(f, "#if PY_VERSION_HEX >= 0x03030000\n", NIL); - printSlot(f, getSlot(n, "feature:python:ht_qualname"), "ht_qualname", "PyObject *"); - - // struct _dictkeysobject *ht_cached_keys; - printSlot(f, getSlot(n, "feature:python:ht_cached_keys"), "ht_cached_keys"); - Printv(f, "#endif\n", NIL); - - // PyObject *ht_module; - Printv(f, "#if PY_VERSION_HEX >= 0x03090000\n", NIL); - printSlot(f, getSlot(n, "feature:python:ht_module"), "ht_module", "PyObject *"); - Printv(f, "#endif\n", NIL); - - // char *_ht_tpname; - Printv(f, "#if PY_VERSION_HEX >= 0x030b0000\n", NIL); - printSlot(f, getSlot(n, "feature:python:_ht_tpname"), "_ht_tpname", "char *"); - - // struct _specialization_cache _spec_cache; - Printf(f, " {\n"); - printSlot(f, getSlot(n, "feature:python:getitem"), "getitem", "PyObject *"); - Printf(f, " }\n"); - Printv(f, "#endif\n", NIL); - Printf(f, "};\n\n"); - - String *clientdata = NewString(""); - Printf(clientdata, "&%s_clientdata", templ); - SwigType_remember_mangleddata(pmname, clientdata); - - SwigType *smart = Swig_cparse_smartptr(n); - if (smart) { - SwigType_add_pointer(smart); - String *smart_pmname = SwigType_manglestr(smart); - SwigType_remember_mangleddata(smart_pmname, clientdata); - Delete(smart_pmname); - } - - String *clientdata_klass = NewString("0"); - if (GetFlag(n, "feature:implicitconv")) { - Clear(clientdata_klass); - Printf(clientdata_klass, "(PyObject *) &%s_type", templ); - } - - Printf(f, "SWIGINTERN SwigPyClientData %s_clientdata = {%s, 0, 0, 0, 0, 0, (PyTypeObject *)&%s_type};\n\n", templ, clientdata_klass, templ); - - Printv(f_init, " if (PyType_Ready(builtin_pytype) < 0) {\n", NIL); - Printf(f_init, " PyErr_SetString(PyExc_TypeError, \"Could not create type '%s'.\");\n", symname); - Printv(f_init, "#if PY_VERSION_HEX >= 0x03000000\n", NIL); - Printv(f_init, " return NULL;\n", NIL); - Printv(f_init, "#else\n", NIL); - Printv(f_init, " return;\n", NIL); - Printv(f_init, "#endif\n", NIL); - Printv(f_init, " }\n", NIL); - Printv(f_init, " Py_INCREF(builtin_pytype);\n", NIL); - Printf(f_init, " PyModule_AddObject(m, \"%s\", (PyObject *)builtin_pytype);\n", symname); - Printf(f_init, " SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", symname); - Printv(f_init, " d = md;\n", NIL); - - Delete(clientdata); - Delete(smart); - Delete(rname); - Delete(pname); - Delete(mname); - Delete(pmname); - Delete(templ); - Delete(tp_flags); - Delete(tp_flags_py3); - Delete(tp_as_buffer); - Delete(tp_as_mapping); - Delete(tp_as_sequence); - Delete(tp_as_number); - Delete(quoted_symname); - Delete(quoted_tp_doc_str); - Delete(tp_init); - Delete(clientdata_klass); - Delete(richcompare_func); - Delete(getset_name); - Delete(methods_name); - } - - virtual int classHandler(Node *n) { - File *f_shadow_file = f_shadow; - Node *base_node = NULL; - - if (shadow) { - - /* Create new strings for building up a wrapper function */ - have_constructor = 0; - have_repr = 0; - have_builtin_static_member_method_callback = false; - - class_name = Getattr(n, "sym:name"); - real_classname = Getattr(n, "name"); - - if (!addSymbol(class_name, n)) - return SWIG_ERROR; - - if (builtin) { - List *baselist = Getattr(n, "bases"); - if (baselist && Len(baselist) > 0) { - Iterator b = First(baselist); - base_node = b.item; - } - } - - shadow_indent = (String *) tab4; - - /* Handle inheritance */ - String *base_class = NewString(""); - List *baselist = Getattr(n, "bases"); - if (baselist && Len(baselist)) { - Iterator b; - b = First(baselist); - while (b.item) { - String *bname = Getattr(b.item, "python:proxy"); - bool ignore = GetFlag(b.item, "feature:ignore") ? true : false; - if (!bname || ignore) { - if (!bname && !ignore) { - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(n), Getline(n), - "Base class '%s' ignored - unknown module name for base. Either import the appropriate module interface file or specify the name of the module in the %%import directive.\n", - SwigType_namestr(Getattr(b.item, "name"))); - } - b = Next(b); - continue; - } - Printv(base_class, bname, NIL); - b = Next(b); - if (b.item) { - Printv(base_class, ", ", NIL); - } - } - } - - if (builtin) { - Hash *base_richcompare = NULL; - Hash *richcompare = NULL; - if (base_node) - base_richcompare = Getattr(base_node, "python:richcompare"); - if (base_richcompare) - richcompare = Copy(base_richcompare); - else - richcompare = NewHash(); - Setattr(n, "python:richcompare", richcompare); - } - - /* dealing with abstract base class */ - String *abcs = Getattr(n, "feature:python:abc"); - if (abcs) { - if (Len(base_class) > 0) - Printv(base_class, ", ", NIL); - Printv(base_class, abcs, NIL); - } - - if (builtin) { - if (have_docstring(n)) { - String *ds = cdocstring(n, AUTODOC_CLASS); - Setattr(n, "feature:python:tp_doc", ds); - Delete(ds); - } else { - String *name = Getattr(n, "name"); - String *rname = add_explicit_scope(SwigType_namestr(name)); - Setattr(n, "feature:python:tp_doc", rname); - Delete(rname); - } - } else { - if (GetFlag(n, "feature:python:nondynamic")) - Printv(f_shadow, "@_swig_add_metaclass(_SwigNonDynamicMeta)\n", NIL); - Printv(f_shadow, "class ", class_name, NIL); - - if (Len(base_class)) { - Printf(f_shadow, "(%s)", base_class); - } else { - if (GetFlag(n, "feature:exceptionclass")) { - Printf(f_shadow, "(Exception)"); - } else { - Printf(f_shadow, "(object"); - /* Replace @_swig_add_metaclass above with below when support for python 2.7 is dropped - if (GetFlag(n, "feature:python:nondynamic")) { - Printf(f_shadow, ", metaclass=_SwigNonDynamicMeta"); - } - */ - Printf(f_shadow, ")"); - } - } - - Printf(f_shadow, ":\n"); - - // write docstrings if requested - if (have_docstring(n)) { - String *str = docstring(n, AUTODOC_CLASS, tab4); - if (str && Len(str)) - Printv(f_shadow, tab4, str, "\n\n", NIL); - } - - Printv(f_shadow, tab4, "thisown = property(lambda x: x.this.own(), ", "lambda x, v: x.this.own(v), doc=\"The membership flag\")\n", NIL); - /* Add static attribute */ - if (GetFlag(n, "feature:python:nondynamic")) { - Printv(f_shadow_file, tab4, "__setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n", NIL); - } - } - } - - /* Emit all of the members */ - - in_class = 1; - if (builtin) - builtin_pre_decl(n); - - /* Override the shadow file so we can capture its methods */ - f_shadow = NewString(""); - - // Set up type check for director class constructor - Clear(none_comparison); - if (builtin && Swig_directorclass(n)) { - String *p_real_classname = Copy(real_classname); - SwigType_add_pointer(p_real_classname); - String *mangle = SwigType_manglestr(p_real_classname); - String *descriptor = NewStringf("SWIGTYPE%s", mangle); - Printv(none_comparison, "self->ob_type != ((SwigPyClientData *)(", descriptor, ")->clientdata)->pytype", NIL); - Delete(descriptor); - Delete(mangle); - Delete(p_real_classname); - } else { - Printv(none_comparison, "$arg != Py_None", NIL); - } - - Language::classHandler(n); - - in_class = 0; - - /* Complete the class */ - if (shadow) { - /* Generate a class registration function */ - // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers) - SwigType *smart = Swig_cparse_smartptr(n); - SwigType *ct = Copy(smart ? smart : real_classname); - SwigType_add_pointer(ct); - SwigType *realct = Copy(real_classname); - SwigType_add_pointer(realct); - SwigType_remember(realct); - if (builtin) { - Printv(f_wrappers, builtin_closures_code, NIL); - Delete(builtin_closures_code); - builtin_closures_code = NewString(""); - Clear(builtin_closures); - } else { - Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL); - Printv(f_wrappers, " PyObject *obj;\n", NIL); - Printv(f_wrappers, " if (!SWIG_Python_UnpackTuple(args, \"swigregister\", 1, 1, &obj)) return NULL;\n", NIL); - - Printv(f_wrappers, - " SWIG_TypeNewClientData(SWIGTYPE", SwigType_manglestr(ct), ", SWIG_NewClientData(obj));\n", " return SWIG_Py_Void();\n", "}\n\n", NIL); - String *cname = NewStringf("%s_swigregister", class_name); - add_method(cname, cname, 0, 0, 1, 1, 1); - Delete(cname); - } - Delete(smart); - Delete(ct); - Delete(realct); - if (!have_constructor) { - if (!builtin) - Printv(f_shadow_file, "\n", tab4, "def __init__(self, *args, **kwargs):\n", tab8, "raise AttributeError(\"", "No constructor defined", - (Getattr(n, "abstracts") ? " - class is abstract" : ""), "\")\n", NIL); - } else if (!builtin) { - - Printv(f_wrappers, "SWIGINTERN PyObject *", class_name, "_swiginit(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", NIL); - Printv(f_wrappers, " return SWIG_Python_InitShadowInstance(args);\n", "}\n\n", NIL); - String *cname = NewStringf("%s_swiginit", class_name); - add_method(cname, cname, 0); - Delete(cname); - } - if (!have_repr && !builtin) { - /* Supply a repr method for this class */ - String *rname = SwigType_namestr(real_classname); - Printv(f_shadow_file, tab4, "__repr__ = _swig_repr\n", NIL); - Delete(rname); - } - - if (builtin) - builtin_post_decl(f_builtins, n); - - if (builtin_tp_init) { - Delete(builtin_tp_init); - builtin_tp_init = 0; - } - - if (!builtin) { - /* Now emit methods */ - Printv(f_shadow_file, f_shadow, NIL); - Printf(f_shadow_file, "\n"); - Printf(f_shadow_file, "# Register %s in %s:\n", class_name, module); - Printf(f_shadow_file, "%s.%s_swigregister(%s)\n", module, class_name, class_name); - } - - shadow_indent = 0; - if (Len(f_shadow_stubs) > 0) - Printf(f_shadow_file, "%s\n", f_shadow_stubs); - Clear(f_shadow_stubs); - } - - if (builtin) { - Clear(class_members); - Clear(builtin_getset); - Clear(builtin_methods); - } - - /* Restore shadow file back to original version */ - Delete(f_shadow); - f_shadow = f_shadow_file; - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * functionHandler() - Mainly overloaded for callback handling - * ------------------------------------------------------------ */ - - virtual int functionHandler(Node *n) { - String *pcb = GetFlagAttr(n, "feature:python:callback"); - if (pcb) { - if (Strcmp(pcb, "1") == 0) { - SetFlagAttr(n, "feature:callback", "%s_cb_ptr"); - } else { - SetFlagAttr(n, "feature:callback", pcb); - } - autodoc_l dlevel = autodoc_level(Getattr(n, "feature:autodoc")); - if (dlevel != NO_AUTODOC && dlevel > TYPES_AUTODOC) { - Setattr(n, "feature:autodoc", "1"); - } - } - return Language::functionHandler(n); - } - - /* ------------------------------------------------------------ - * memberfunctionHandler() - * ------------------------------------------------------------ */ - - virtual int memberfunctionHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - int oldshadow; - - if (builtin) - Swig_save("builtin_memberfunc", n, "python:argcount", NIL); - - /* Create the default member function */ - oldshadow = shadow; /* Disable shadowing when wrapping member functions */ - if (shadow) - shadow = shadow | PYSHADOW_MEMBER; - Language::memberfunctionHandler(n); - shadow = oldshadow; - - if (builtin && in_class) { - // Can't use checkAttribute(n, "access", "public") because - // "access" attr isn't set on %extend methods - if (!checkAttribute(n, "access", "private") && strncmp(Char(symname), "operator ", 9) && !Getattr(class_members, symname)) { - String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname); - String *wname = Swig_name_wrapper(fullname); - Setattr(class_members, symname, n); - int argcount = Getattr(n, "python:argcount") ? atoi(Char(Getattr(n, "python:argcount"))) : 2; - String *ds = have_docstring(n) ? cdocstring(n, AUTODOC_METHOD) : NewString(""); - if (check_kwargs(n)) { - // Cast via void(*)(void) to suppress GCC -Wcast-function-type - // warning. Python should always call the function correctly, but - // the Python C API requires us to store it in function pointer of a - // different type. - Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, METH_VARARGS|METH_KEYWORDS, \"%s\" },\n", symname, wname, ds); - } else if (argcount == 0) { - Printf(builtin_methods, " { \"%s\", %s, METH_NOARGS, \"%s\" },\n", symname, wname, ds); - } else if (argcount == 1) { - Printf(builtin_methods, " { \"%s\", %s, METH_O, \"%s\" },\n", symname, wname, ds); - } else { - Printf(builtin_methods, " { \"%s\", %s, METH_VARARGS, \"%s\" },\n", symname, wname, ds); - } - Delete(fullname); - Delete(wname); - Delete(ds); - } - } - - if (builtin) - Swig_restore(n); - - if (!Getattr(n, "sym:nextSibling")) { - if (shadow && !builtin) { - int fproxy = fastproxy; - String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname); - if (Strcmp(symname, "__repr__") == 0) { - have_repr = 1; - } - if (Getattr(n, "feature:shadow")) { - String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")"); - String *pyaction = NewStringf("%s.%s", module, fullname); - Replaceall(pycode, "$action", pyaction); - Delete(pyaction); - Printv(f_shadow, pycode, "\n", NIL); - Delete(pycode); - fproxy = 0; - } else { - int allow_kwargs = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0; - String *parms = make_pyParmList(n, true, false, allow_kwargs); - String *callParms = make_pyParmList(n, true, true, allow_kwargs); - if (!have_addtofunc(n)) { - if (!fastproxy || olddefs) { - Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); - if (have_docstring(n)) - Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, tab8), "\n", NIL); - Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n", NIL); - } - } else { - Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); - if (have_docstring(n)) - Printv(f_shadow, tab8, docstring(n, AUTODOC_METHOD, tab8), "\n", NIL); - if (have_pythonprepend(n)) { - fproxy = 0; - Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL); - } - if (have_pythonappend(n)) { - fproxy = 0; - Printv(f_shadow, tab8, "val = ", funcCall(fullname, callParms), "\n", NIL); - Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL); - Printv(f_shadow, tab8, "return val\n\n", NIL); - } else { - Printv(f_shadow, tab8, "return ", funcCall(fullname, callParms), "\n\n", NIL); - } - } - } - if (fproxy) { - Printf(f_shadow, tab4); - Printf(f_shadow, "%s = _swig_new_instance_method(%s.%s)\n", symname, module, Swig_name_member(NSPACE_TODO, class_name, symname)); - } - Delete(fullname); - } - } - return SWIG_OK; - } - - - /* ------------------------------------------------------------ - * staticmemberfunctionHandler() - * ------------------------------------------------------------ */ - - virtual int staticmemberfunctionHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - if (builtin && in_class) { - Swig_save("builtin_memberconstantHandler", n, "pybuiltin:symname", NIL); - Setattr(n, "pybuiltin:symname", symname); - } - Language::staticmemberfunctionHandler(n); - if (builtin && in_class) { - Swig_restore(n); - } - - int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0; - if (builtin && in_class) { - if ((GetFlagAttr(n, "feature:extend") || checkAttribute(n, "access", "public")) - && !Getattr(class_members, symname)) { - String *fullname = Swig_name_member(NSPACE_TODO, class_name, symname); - String *wname = Swig_name_wrapper(fullname); - Setattr(class_members, symname, n); - int funpack = fastunpack && !Getattr(n, "sym:overloaded"); - String *pyflags = NewString("METH_STATIC|"); - int argcount = Getattr(n, "python:argcount") ? atoi(Char(Getattr(n, "python:argcount"))) : 2; - if (funpack && argcount == 0) - Append(pyflags, "METH_NOARGS"); - else if (funpack && argcount == 1) - Append(pyflags, "METH_O"); - else - Append(pyflags, kw ? "METH_VARARGS|METH_KEYWORDS" : "METH_VARARGS"); - // Cast via void(*)(void) to suppress GCC -Wcast-function-type warning. - // Python should always call the function correctly, but the Python C - // API requires us to store it in function pointer of a different type. - if (have_docstring(n)) { - String *ds = cdocstring(n, AUTODOC_STATICFUNC); - Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"%s\" },\n", symname, wname, pyflags, ds); - Delete(ds); - } else if (Getattr(n, "feature:callback")) { - String *ds = NewStringf("swig_ptr: %s", Getattr(n, "feature:callback:name")); - Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"%s\" },\n", symname, wname, pyflags, ds); - Delete(ds); - have_builtin_static_member_method_callback = true; - } else { - Printf(builtin_methods, " { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"\" },\n", symname, wname, pyflags); - } - Delete(fullname); - Delete(wname); - Delete(pyflags); - } - return SWIG_OK; - } - - if (Getattr(n, "sym:nextSibling")) { - return SWIG_OK; - } - - if (shadow) { - String *staticfunc_name = NewString(fastproxy ? "_swig_new_static_method" : "staticmethod"); - bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback"); - if (!fast || olddefs) { - String *parms = make_pyParmList(n, false, false, kw); - String *callParms = make_pyParmList(n, false, true, kw); - Printv(f_shadow, "\n", tab4, "@staticmethod", NIL); - Printv(f_shadow, "\n", tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); - if (have_docstring(n)) - Printv(f_shadow, tab8, docstring(n, AUTODOC_STATICFUNC, tab8), "\n", NIL); - if (have_pythonprepend(n)) - Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL); - if (have_pythonappend(n)) { - Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL); - Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL); - Printv(f_shadow, tab8, "return val\n", NIL); - } else { - Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL); - } - } - - // Below may result in a 2nd definition of the method when -olddefs is used. The Python interpreter will use the second definition as it overwrites the first. - if (fast) { - Printv(f_shadow, tab4, symname, " = ", staticfunc_name, "(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), - ")\n", NIL); - } - Delete(staticfunc_name); - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constructorDeclaration() - * ------------------------------------------------------------ */ - - virtual int constructorHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - int oldshadow = shadow; - int use_director = Swig_directorclass(n); - - /* - * If we're wrapping the constructor of a C++ director class, prepend a new parameter - * to receive the scripting language object (e.g. 'self') - * - */ - Swig_save("python:constructorHandler", n, "parms", NIL); - if (use_director) { - Parm *parms = Getattr(n, "parms"); - Parm *self; - String *name = NewString("self"); - String *type = NewString("PyObject"); - SwigType_add_pointer(type); - self = NewParm(type, name, n); - Delete(type); - Delete(name); - Setattr(self, "lname", "O"); - if (parms) - set_nextSibling(self, parms); - Setattr(n, "parms", self); - Setattr(n, "wrap:self", "1"); - Setattr(n, "hidden", "1"); - Delete(self); - } - - if (shadow) - shadow = shadow | PYSHADOW_MEMBER; - Language::constructorHandler(n); - shadow = oldshadow; - - Delattr(n, "wrap:self"); - Swig_restore(n); - - if (!Getattr(n, "sym:nextSibling")) { - if (shadow) { - int allow_kwargs = (check_kwargs(n) && (!Getattr(n, "sym:overloaded"))) ? 1 : 0; - int handled_as_init = 0; - if (!have_constructor) { - String *nname = Getattr(n, "sym:name"); - String *sname = Getattr(getCurrentClass(), "sym:name"); - String *cname = Swig_name_construct(NSPACE_TODO, sname); - handled_as_init = (Strcmp(nname, sname) == 0) || (Strcmp(nname, cname) == 0); - Delete(cname); - } - - String *subfunc = Swig_name_construct(NSPACE_TODO, symname); - if (!have_constructor && handled_as_init) { - if (!builtin) { - if (Getattr(n, "feature:shadow")) { - String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")"); - String *pyaction = NewStringf("%s.%s", module, subfunc); - Replaceall(pycode, "$action", pyaction); - Delete(pyaction); - Printv(f_shadow, pycode, "\n", NIL); - Delete(pycode); - } else { - String *pass_self = NewString(""); - Node *parent = Swig_methodclass(n); - String *classname = Swig_class_name(parent); - String *rclassname = Swig_class_name(getCurrentClass()); - assert(rclassname); - (void)rclassname; - - String *parms = make_pyParmList(n, true, false, allow_kwargs); - /* Pass 'self' only if using director */ - String *callParms = make_pyParmList(n, false, true, allow_kwargs, true); - - if (use_director) { - Insert(callParms, 0, "_self, "); - Printv(pass_self, tab8, NIL); - Printf(pass_self, "if self.__class__ == %s:\n", classname); - //Printv(pass_self, tab8, tab4, "args = (None,) + args\n", tab8, "else:\n", tab8, tab4, "args = (self,) + args\n", NIL); - Printv(pass_self, tab8, tab4, "_self = None\n", tab8, "else:\n", tab8, tab4, "_self = self\n", NIL); - } - - Printv(f_shadow, "\n", tab4, "def __init__(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); - if (have_docstring(n)) - Printv(f_shadow, tab8, docstring(n, AUTODOC_CTOR, tab8), "\n", NIL); - if (have_pythonprepend(n)) - Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL); - Printv(f_shadow, pass_self, NIL); - Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self, ", funcCall(subfunc, callParms), ")\n", NIL); - if (have_pythonappend(n)) - Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n\n", NIL); - Delete(pass_self); - } - have_constructor = 1; - } - } else { - /* Hmmm. We seem to be creating a different constructor. We're just going to create a - function for it. */ - if (!builtin) { - if (Getattr(n, "feature:shadow")) { - String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), "", Getfile(n), Getline(n), "%feature(\"shadow\")"); - String *pyaction = NewStringf("%s.%s", module, subfunc); - Replaceall(pycode, "$action", pyaction); - Delete(pyaction); - Printv(f_shadow_stubs, pycode, "\n", NIL); - Delete(pycode); - } else { - String *parms = make_pyParmList(n, false, false, allow_kwargs); - String *callParms = make_pyParmList(n, false, true, allow_kwargs); - - Printv(f_shadow_stubs, "\ndef ", symname, "(", parms, ")", returnTypeAnnotation(n), ":\n", NIL); - if (have_docstring(n)) - Printv(f_shadow_stubs, tab4, docstring(n, AUTODOC_CTOR, tab4), "\n", NIL); - if (have_pythonprepend(n)) - Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL); - Printv(f_shadow_stubs, tab4, "val = ", funcCall(subfunc, callParms), "\n", NIL); - if (have_pythonappend(n)) - Printv(f_shadow_stubs, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL); - Printv(f_shadow_stubs, tab4, "return val\n", NIL); - } - } else { - Printf(f_shadow_stubs, "%s = %s\n", symname, subfunc); - } - } - Delete(subfunc); - } - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * destructorHandler() - * ------------------------------------------------------------ */ - - virtual int destructorHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - int oldshadow = shadow; - - if (builtin && in_class) { - Node *cls = Swig_methodclass(n); - // Use the destructor for the tp_dealloc slot unless a user overrides it with another method - if (!Getattr(cls, "feature:python:tp_dealloc")) { - Setattr(n, "feature:python:slot", "tp_dealloc"); - Setattr(n, "feature:python:slot:functype", "destructor"); - } - } - - if (shadow) - shadow = shadow | PYSHADOW_MEMBER; - //Setattr(n,"emit:dealloc","1"); - Language::destructorHandler(n); - shadow = oldshadow; - - if (shadow) { - if (Getattr(n, "feature:shadow")) { - String *pycode = indent_pythoncode(Getattr(n, "feature:shadow"), tab4, Getfile(n), Getline(n), "%feature(\"shadow\")"); - String *pyaction = NewStringf("%s.%s", module, Swig_name_destroy(NSPACE_TODO, symname)); - Replaceall(pycode, "$action", pyaction); - Delete(pyaction); - Printv(f_shadow, pycode, "\n", NIL); - Delete(pycode); - } else { - Printv(f_shadow, tab4, "__swig_destroy__ = ", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "\n", NIL); - if (!have_pythonprepend(n) && !have_pythonappend(n)) { - return SWIG_OK; - } - Printv(f_shadow, tab4, "def __del__(self):\n", NIL); - if (have_docstring(n)) - Printv(f_shadow, tab8, docstring(n, AUTODOC_DTOR, tab8), "\n", NIL); - if (have_pythonprepend(n)) - Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL); - if (have_pythonappend(n)) - Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL); - Printv(f_shadow, tab8, "pass\n", NIL); - Printv(f_shadow, "\n", NIL); - } - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * membervariableHandler() - * ------------------------------------------------------------ */ - - virtual int membervariableHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - - int oldshadow = shadow; - if (shadow) - shadow = shadow | PYSHADOW_MEMBER; - Language::membervariableHandler(n); - shadow = oldshadow; - - if (shadow && !builtin) { - String *mname = Swig_name_member(NSPACE_TODO, class_name, symname); - String *setname = Swig_name_set(NSPACE_TODO, mname); - String *getname = Swig_name_get(NSPACE_TODO, mname); - int assignable = is_assignable(n); - String *variable_annotation = variableAnnotation(n); - Printv(f_shadow, tab4, symname, variable_annotation, " = property(", module, ".", getname, NIL); - if (assignable) - Printv(f_shadow, ", ", module, ".", setname, NIL); - if (have_docstring(n)) { - String *s = docstring(n, AUTODOC_VAR, tab4); - if (Len(s)) - Printv(f_shadow, ", doc=", s, NIL); - } - Printv(f_shadow, ")\n", NIL); - Delete(variable_annotation); - Delete(mname); - Delete(setname); - Delete(getname); - } - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * staticmembervariableHandler() - * ------------------------------------------------------------ */ - - virtual int staticmembervariableHandler(Node *n) { - Swig_save("builtin_staticmembervariableHandler", n, "builtin_symname", NIL); - Language::staticmembervariableHandler(n); - Swig_restore(n); - - if (GetFlag(n, "wrappedasconstant")) - return SWIG_OK; - - String *symname = Getattr(n, "sym:name"); - - if (shadow) { - if (!builtin && GetFlag(n, "hasconsttype")) { - String *mname = Swig_name_member(NSPACE_TODO, class_name, symname); - Printf(f_shadow_stubs, "%s.%s = %s.%s.%s\n", class_name, symname, module, global_name, mname); - Delete(mname); - } else { - String *mname = Swig_name_member(NSPACE_TODO, class_name, symname); - String *getname = Swig_name_get(NSPACE_TODO, mname); - String *wrapgetname = Swig_name_wrapper(getname); - String *vargetname = NewStringf("Swig_var_%s", getname); - String *setname = Swig_name_set(NSPACE_TODO, mname); - String *wrapsetname = Swig_name_wrapper(setname); - String *varsetname = NewStringf("Swig_var_%s", setname); - - Wrapper *f = NewWrapper(); - Printv(f->def, "SWIGINTERN PyObject *", wrapgetname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *SWIGUNUSEDPARM(args)) {", NIL); - Printv(f->code, " return ", vargetname, "();\n", NIL); - Append(f->code, "}\n"); - add_method(getname, wrapgetname, 0); - Wrapper_print(f, f_wrappers); - DelWrapper(f); - int assignable = is_assignable(n); - if (assignable) { - int funpack = fastunpack; - Wrapper *f = NewWrapper(); - Printv(f->def, "SWIGINTERN PyObject *", wrapsetname, "(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {", NIL); - Wrapper_add_local(f, "res", "int res"); - if (!funpack) { - Wrapper_add_local(f, "value", "PyObject *value"); - Append(f->code, "if (!PyArg_ParseTuple(args, \"O:set\", &value)) return NULL;\n"); - } - Printf(f->code, "res = %s(%s);\n", varsetname, funpack ? "args" : "value"); - Append(f->code, "return !res ? SWIG_Py_Void() : NULL;\n"); - Append(f->code, "}\n"); - Wrapper_print(f, f_wrappers); - add_method(setname, wrapsetname, 0, 0, funpack, 1, 1); - DelWrapper(f); - } - if (!builtin) { - Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL); - if (assignable) - Printv(f_shadow, ", ", module, ".", setname, NIL); - if (have_docstring(n)) { - String *s = docstring(n, AUTODOC_VAR, tab4); - if (Len(s)) - Printv(f_shadow, ", doc=", s, NIL); - } - Printv(f_shadow, ")\n", NIL); - } - String *getter = Getattr(n, "pybuiltin:getter"); - String *setter = Getattr(n, "pybuiltin:setter"); - Hash *h = NULL; - if (getter || setter) { - h = Getattr(builtin_getset, symname); - if (!h) { - h = NewHash(); - Setattr(h, "static", "1"); - Setattr(builtin_getset, symname, h); - } - } - if (getter) - Setattr(h, "getter", getter); - if (setter) - Setattr(h, "setter", setter); - if (h) - Delete(h); - Delete(mname); - Delete(getname); - Delete(wrapgetname); - Delete(vargetname); - Delete(setname); - Delete(wrapsetname); - Delete(varsetname); - } - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * memberconstantHandler() - * ------------------------------------------------------------ */ - - virtual int memberconstantHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - if (builtin && in_class) { - Swig_save("builtin_memberconstantHandler", n, "pybuiltin:symname", NIL); - Setattr(n, "pybuiltin:symname", symname); - } - int oldshadow = shadow; - if (shadow) - shadow = shadow | PYSHADOW_MEMBER; - Language::memberconstantHandler(n); - shadow = oldshadow; - - if (builtin && in_class) { - Swig_restore(n); - } else if (shadow) { - Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), "\n", NIL); - if (have_docstring(n)) - Printv(f_shadow, tab4, docstring(n, AUTODOC_CONST, tab4), "\n", NIL); - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * insertDirective() - * - * Hook for %insert directive. We're going to look for special %shadow inserts - * as a special case so we can do indenting correctly - * ------------------------------------------------------------ */ - - virtual int insertDirective(Node *n) { - String *code = Getattr(n, "code"); - String *section = Getattr(n, "section"); - - if (!ImportMode && (Cmp(section, "python") == 0 || Cmp(section, "shadow") == 0)) { - if (shadow) { - String *pycode = indent_pythoncode(code, shadow_indent, Getfile(n), Getline(n), "%pythoncode or %insert(\"python\") block"); - Printv(f_shadow, pycode, NIL); - Delete(pycode); - } - } else if (!ImportMode && (Cmp(section, "pythonbegin") == 0)) { - if (shadow) { - String *pycode = indent_pythoncode(code, "", Getfile(n), Getline(n), "%pythonbegin or %insert(\"pythonbegin\") block"); - Printv(f_shadow_begin, pycode, NIL); - Delete(pycode); - } - } else { - Language::insertDirective(n); - } - return SWIG_OK; - } - - virtual String *runtimeCode() { - String *s = NewString(""); - String *shead = Swig_include_sys("pyhead.swg"); - if (!shead) { - Printf(stderr, "*** Unable to open 'pyhead.swg'\n"); - } else { - Append(s, shead); - Delete(shead); - } - String *serrors = Swig_include_sys("pyerrors.swg"); - if (!serrors) { - Printf(stderr, "*** Unable to open 'pyerrors.swg'\n"); - } else { - Append(s, serrors); - Delete(serrors); - } - String *sthread = Swig_include_sys("pythreads.swg"); - if (!sthread) { - Printf(stderr, "*** Unable to open 'pythreads.swg'\n"); - } else { - Append(s, sthread); - Delete(sthread); - } - String *sapi = Swig_include_sys("pyapi.swg"); - if (!sapi) { - Printf(stderr, "*** Unable to open 'pyapi.swg'\n"); - } else { - Append(s, sapi); - Delete(sapi); - } - String *srun = Swig_include_sys("pyrun.swg"); - if (!srun) { - Printf(stderr, "*** Unable to open 'pyrun.swg'\n"); - } else { - Append(s, srun); - Delete(srun); - } - return s; - } - - virtual String *defaultExternalRuntimeFilename() { - return NewString("swigpyrun.h"); - } - - /*---------------------------------------------------------------------- - * kwargsSupport() - *--------------------------------------------------------------------*/ - - bool kwargsSupport() const { - return true; - } -}; - -/* --------------------------------------------------------------- - * classDirectorMethod() - * - * Emit a virtual director method to pass a method call on to the - * underlying Python object. - * - * ** Moved it here due to internal error on gcc-2.96 ** - * --------------------------------------------------------------- */ -int PYTHON::classDirectorMethods(Node *n) { - director_method_index = 0; - return Language::classDirectorMethods(n); -} - - -int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { - int is_void = 0; - int is_pointer = 0; - String *decl = Getattr(n, "decl"); - String *name = Getattr(n, "name"); - String *classname = Getattr(parent, "sym:name"); - String *c_classname = Getattr(parent, "name"); - String *symname = Getattr(n, "sym:name"); - String *declaration = NewString(""); - ParmList *l = Getattr(n, "parms"); - Wrapper *w = NewWrapper(); - String *tm; - String *wrap_args = NewString(""); - String *returntype = Getattr(n, "type"); - String *value = Getattr(n, "value"); - String *storage = Getattr(n, "storage"); - bool pure_virtual = false; - int status = SWIG_OK; - int idx; - bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; - - if (builtin) { - // Rename any wrapped parameters called 'self' as the generated code contains a variable with same name - Parm *p; - for (p = l; p; p = nextSibling(p)) { - String *arg = Getattr(p, "name"); - if (arg && Cmp(arg, "self") == 0) - Delattr(p, "name"); - } - } - - if (Cmp(storage, "virtual") == 0) { - if (Cmp(value, "0") == 0) { - pure_virtual = true; - } - } - - /* determine if the method returns a pointer */ - is_pointer = SwigType_ispointer_return(decl); - is_void = (!Cmp(returntype, "void") && !is_pointer); - - /* virtual method definition */ - String *target; - String *pclassname = NewStringf("SwigDirector_%s", classname); - String *qualified_name = NewStringf("%s::%s", pclassname, name); - SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type"); - target = Swig_method_decl(rtype, decl, qualified_name, l, 0); - Printf(w->def, "%s", target); - Delete(qualified_name); - Delete(target); - /* header declaration */ - target = Swig_method_decl(rtype, decl, name, l, 1); - Printf(declaration, " virtual %s", target); - Delete(target); - - // Get any exception classes in the throws typemap - if (Getattr(n, "noexcept")) { - Append(w->def, " noexcept"); - Append(declaration, " noexcept"); - } - ParmList *throw_parm_list = 0; - if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { - Parm *p; - int gencomma = 0; - - Append(w->def, " throw("); - Append(declaration, " throw("); - - if (throw_parm_list) - Swig_typemap_attach_parms("throws", throw_parm_list, 0); - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - if (gencomma++) { - Append(w->def, ", "); - Append(declaration, ", "); - } - String *str = SwigType_str(Getattr(p, "type"), 0); - Append(w->def, str); - Append(declaration, str); - Delete(str); - } - } - - Append(w->def, ")"); - Append(declaration, ")"); - } - - Append(w->def, " {"); - Append(declaration, ";\n"); - - /* declare method return value - * if the return value is a reference or const reference, a specialized typemap must - * handle it, including declaration of c_result ($result). - */ - if (!is_void && (!ignored_method || pure_virtual)) { - if (!SwigType_isclass(returntype)) { - if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { - String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); - Delete(construct_result); - } else { - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); - } - } else { - String *cres = SwigType_lstr(returntype, "c_result"); - Printf(w->code, "%s;\n", cres); - Delete(cres); - } - } - - if (builtin) { - Printv(w->code, "PyObject *self = NULL;\n", NIL); - Printv(w->code, "(void)self;\n", NIL); - } - - if (ignored_method) { - if (!pure_virtual) { - if (!is_void) - Printf(w->code, "return "); - String *super_call = Swig_method_call(super, l); - Printf(w->code, "%s;\n", super_call); - Delete(super_call); - } else { - Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname), - SwigType_namestr(name)); - } - } else { - /* attach typemaps to arguments (C/C++ -> Python) */ - String *arglist = NewString(""); - String *parse_args = NewString(""); - - Swig_director_parms_fixup(l); - - /* remove the wrapper 'w' since it was producing spurious temps */ - Swig_typemap_attach_parms("in", l, 0); - Swig_typemap_attach_parms("directorin", l, w); - Swig_typemap_attach_parms("directorargout", l, w); - - Parm *p; - char source[256]; - - int outputs = 0; - if (!is_void) - outputs++; - - /* build argument list and type conversion string */ - idx = 0; - p = l; - int use_parse = 0; - while (p) { - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - continue; - } - - /* old style? caused segfaults without the p!=0 check - in the for() condition, and seems dangerous in the - while loop as well. - while (Getattr(p, "tmap:ignore")) { - p = Getattr(p, "tmap:ignore:next"); - } - */ - - if (Getattr(p, "tmap:directorargout") != 0) - outputs++; - - String *pname = Getattr(p, "name"); - String *ptype = Getattr(p, "type"); - - Putc(',', arglist); - if ((tm = Getattr(p, "tmap:directorin")) != 0) { - String *parse = Getattr(p, "tmap:directorin:parse"); - if (!parse) { - sprintf(source, "obj%d", idx++); - String *input = NewString(source); - Setattr(p, "emit:directorinput", input); - Replaceall(tm, "$input", input); - Delete(input); - Replaceall(tm, "$owner", "0"); - /* Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL); */ - Printv(wrap_args, "swig::SwigVar_PyObject ", source, ";\n", NIL); - - Printv(wrap_args, tm, "\n", NIL); - Printv(arglist, "(PyObject *)", source, NIL); - Putc('O', parse_args); - } else { - use_parse = 1; - Append(parse_args, parse); - Setattr(p, "emit:directorinput", pname); - Replaceall(tm, "$input", pname); - Replaceall(tm, "$owner", "0"); - if (Len(tm) == 0) - Append(tm, pname); - Append(arglist, tm); - } - p = Getattr(p, "tmap:directorin:next"); - continue; - } else if (Cmp(ptype, "void")) { - /* special handling for pointers to other C++ director classes. - * ideally this would be left to a typemap, but there is currently no - * way to selectively apply the dynamic_cast<> to classes that have - * directors. in other words, the type "SwigDirector_$1_lname" only exists - * for classes with directors. we avoid the problem here by checking - * module.wrap::directormap, but it's not clear how to get a typemap to - * do something similar. perhaps a new default typemap (in addition - * to SWIGTYPE) called DIRECTORTYPE? - */ - if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) { - Node *module = Getattr(parent, "module"); - Node *target = Swig_directormap(module, ptype); - sprintf(source, "obj%d", idx++); - String *nonconst = 0; - /* strip pointer/reference --- should move to Swig/stype.c */ - String *nptype = NewString(Char(ptype) + 2); - /* name as pointer */ - String *ppname = Copy(pname); - if (SwigType_isreference(ptype)) { - Insert(ppname, 0, "&"); - } - /* if necessary, cast away const since Python doesn't support it! */ - if (SwigType_isconst(nptype)) { - nonconst = NewStringf("nc_tmp_%s", pname); - String *nonconst_i = NewStringf("= const_cast< %s >(%s)", SwigType_lstr(ptype, 0), ppname); - Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL); - Delete(nonconst_i); - Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number, - "Target language argument '%s' discards const in director method %s::%s.\n", - SwigType_str(ptype, pname), SwigType_namestr(c_classname), SwigType_namestr(name)); - } else { - nonconst = Copy(ppname); - } - Delete(nptype); - Delete(ppname); - String *mangle = SwigType_manglestr(ptype); - if (target) { - String *director = NewStringf("director_%s", mangle); - Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL); - Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL); - Printf(wrap_args, "%s = SWIG_DIRECTOR_CAST(%s);\n", director, nonconst); - Printf(wrap_args, "if (!%s) {\n", director); - Printf(wrap_args, "%s = SWIG_InternalNewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); - Append(wrap_args, "} else {\n"); - Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director); - Printf(wrap_args, "Py_INCREF((PyObject *)%s);\n", source); - Append(wrap_args, "}\n"); - Delete(director); - Printv(arglist, source, NIL); - } else { - Wrapper_add_localv(w, source, "swig::SwigVar_PyObject", source, "= 0", NIL); - Printf(wrap_args, "%s = SWIG_InternalNewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); - //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n", - // source, nonconst, base); - Printv(arglist, source, NIL); - } - Putc('O', parse_args); - Delete(mangle); - Delete(nonconst); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, - "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), - SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_NOWRAP; - break; - } - } - p = nextSibling(p); - } - - /* add the method name as a PyString */ - String *pyname = Getattr(n, "sym:name"); - - int allow_thread = threads_enable(n); - - if (allow_thread) { - thread_begin_block(n, w->code); - Append(w->code, "{\n"); - } - - /* wrap complex arguments to PyObjects */ - Printv(w->code, wrap_args, NIL); - - /* pass the method call on to the Python object */ - if (dirprot_mode() && !is_public(n)) { - Printf(w->code, "swig_set_inner(\"%s\", true);\n", name); - } - - - Append(w->code, "if (!swig_get_self()) {\n"); - Printf(w->code, " Swig::DirectorException::raise(\"'self' uninitialized, maybe you forgot to call %s.__init__.\");\n", classname); - Append(w->code, "}\n"); - Append(w->code, "#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n"); - Printf(w->code, "const size_t swig_method_index = %d;\n", director_method_index++); - Printf(w->code, "const char *const swig_method_name = \"%s\";\n", pyname); - - Append(w->code, "PyObject *method = swig_get_method(swig_method_index, swig_method_name);\n"); - if (Len(parse_args) > 0) { - if (use_parse) { - Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", Swig_cresult_name(), parse_args, arglist); - } else { - Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallFunctionObjArgs(method %s, NULL);\n", Swig_cresult_name(), arglist); - } - } else { - Append(w->code, "swig::SwigVar_PyObject args = PyTuple_New(0);\n"); - Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_Call(method, (PyObject *) args, NULL);\n", Swig_cresult_name()); - } - Append(w->code, "#else\n"); - if (Len(parse_args) > 0) { - if (use_parse) { - Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", (char *)\"(%s)\" %s);\n", Swig_cresult_name(), pyname, parse_args, arglist); - } else { - Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar(\"%s\");\n", pyname); - Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name %s, NULL);\n", Swig_cresult_name(), arglist); - } - } else { - Printf(w->code, "swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar(\"%s\");\n", pyname); - Printf(w->code, "swig::SwigVar_PyObject %s = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n", Swig_cresult_name()); - } - Append(w->code, "#endif\n"); - - if (dirprot_mode() && !is_public(n)) - Printf(w->code, "swig_set_inner(\"%s\", false);\n", name); - - /* exception handling */ - tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0); - if (!tm) { - tm = Getattr(n, "feature:director:except"); - if (tm) - tm = Copy(tm); - } - Printf(w->code, "if (!%s) {\n", Swig_cresult_name()); - Append(w->code, " PyObject *error = PyErr_Occurred();\n"); - if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { - Replaceall(tm, "$error", "error"); - Printv(w->code, Str(tm), "\n", NIL); - } else { - Append(w->code, " if (error) {\n"); - Printf(w->code, " Swig::DirectorMethodException::raise(\"Error detected when calling '%s.%s'\");\n", classname, pyname); - Append(w->code, " }\n"); - } - Append(w->code, "}\n"); - Delete(tm); - - /* - * Python method may return a simple object, or a tuple. - * for in/out arguments, we have to extract the appropriate PyObjects from the tuple, - * then marshal everything back to C/C++ (return value and output arguments). - * - */ - - /* marshal return value and other outputs (if any) from PyObject to C/C++ type */ - - String *cleanup = NewString(""); - String *outarg = NewString(""); - - if (outputs > 1) { - Wrapper_add_local(w, "output", "PyObject *output"); - Printf(w->code, "if (!PyTuple_Check(%s)) {\n", Swig_cresult_name()); - Printf(w->code, " Swig::DirectorTypeMismatchException::raise(\"Python method %s.%sfailed to return a tuple.\");\n", classname, pyname); - Append(w->code, "}\n"); - } - - idx = 0; - - /* marshal return value */ - if (!is_void) { - tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w); - if (tm != 0) { - if (outputs > 1) { - Printf(w->code, "output = PyTuple_GetItem(%s, %d);\n", Swig_cresult_name(), idx++); - Replaceall(tm, "$input", "output"); - } else { - Replaceall(tm, "$input", Swig_cresult_name()); - } - char temp[24]; - sprintf(temp, "%d", idx); - Replaceall(tm, "$argnum", temp); - - /* TODO check this */ - if (Getattr(n, "wrap:disown")) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - if (Getattr(n, "tmap:directorout:implicitconv")) { - Replaceall(tm, "$implicitconv", get_implicitconv_flag(n)); - } - Replaceall(tm, "$result", "c_result"); - Printv(w->code, tm, "\n", NIL); - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, - "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0), SwigType_namestr(c_classname), - SwigType_namestr(name)); - status = SWIG_ERROR; - } - } - - /* marshal outputs */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:directorargout")) != 0) { - if (outputs > 1) { - Printf(w->code, "output = PyTuple_GetItem(%s, %d);\n", Swig_cresult_name(), idx++); - Replaceall(tm, "$result", "output"); - } else { - Replaceall(tm, "$result", Swig_cresult_name()); - } - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NIL); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } - } - - /* any existing helper functions to handle this? */ - if (allow_thread) { - Append(w->code, "}\n"); - thread_end_block(n, w->code); - } - - Delete(parse_args); - Delete(arglist); - Delete(cleanup); - Delete(outarg); - } - - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { - String *rettype = SwigType_str(returntype, 0); - if (!SwigType_isreference(returntype)) { - Printf(w->code, "return (%s) c_result;\n", rettype); - } else { - Printf(w->code, "return (%s) *c_result;\n", rettype); - } - Delete(rettype); - } - } - - Append(w->code, "}\n"); - - // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method - String *inline_extra_method = NewString(""); - if (dirprot_mode() && !is_public(n) && !pure_virtual) { - Printv(inline_extra_method, declaration, NIL); - String *extra_method_name = NewStringf("%sSwigPublic", name); - Replaceall(inline_extra_method, name, extra_method_name); - Replaceall(inline_extra_method, ";\n", " {\n "); - if (!is_void) - Printf(inline_extra_method, "return "); - String *methodcall = Swig_method_call(super, l); - Printv(inline_extra_method, methodcall, ";\n }\n", NIL); - Delete(methodcall); - Delete(extra_method_name); - } - - /* emit the director method */ - if (status == SWIG_OK) { - if (!Getattr(n, "defaultargs")) { - Replaceall(w->code, "$symname", symname); - Wrapper_print(w, f_directors); - Printv(f_directors_h, declaration, NIL); - Printv(f_directors_h, inline_extra_method, NIL); - } - } - - /* clean up */ - Delete(wrap_args); - Delete(pclassname); - DelWrapper(w); - return status; -} - -/* ----------------------------------------------------------------------------- - * swig_python() - Instantiate module - * ----------------------------------------------------------------------------- */ - -static Language *new_swig_python() { - return new PYTHON(); -} -extern "C" Language *swig_python(void) { - return new_swig_python(); -} diff --git a/contrib/tools/swig/Source/Modules/r.cxx b/contrib/tools/swig/Source/Modules/r.cxx deleted file mode 100644 index 9b465a5716e..00000000000 --- a/contrib/tools/swig/Source/Modules/r.cxx +++ /dev/null @@ -1,2889 +0,0 @@ - -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * r.cxx - * - * R language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" - -static String* replaceInitialDash(const String *name) -{ - String *retval; - if (!Strncmp(name, "_", 1)) { - retval = Copy(name); - Insert(retval, 0, "s"); - } else { - retval = Copy(name); - } - return retval; -} - -static String * getRTypeName(SwigType *t, int *outCount = NULL) { - String *b = SwigType_base(t); - List *els = SwigType_split(t); - int count = 0; - int i; - - if(Strncmp(b, "struct ", 7) == 0) - Replace(b, "struct ", "", DOH_REPLACE_FIRST); - - for(i = 0; i < Len(els); i++) { - String *el = Getitem(els, i); - if(Strcmp(el, "p.") == 0 || Strncmp(el, "a(", 2) == 0) { - count++; - Append(b, "Ref"); - } - } - if(outCount) - *outCount = count; - - String *tmp = NewString(""); - char *retName = Char(SwigType_manglestr(t)); - Insert(tmp, 0, retName); - return tmp; - -} - -/* -------------------------------------------------------------- - * Tries to get the resolved name, with options of adding - * or removing a layer of references. Take care not - * to request both - * --------------------------------------------------------------*/ - -static String *getRClassName(String *retType, int deRef=0, int upRef=0) { - SwigType *resolved = SwigType_typedef_resolve_all(retType); - int ispointer = SwigType_ispointer(resolved); - int isreference = SwigType_isreference(resolved); - if (upRef) { - SwigType_add_pointer(resolved); - } - if (deRef) { - if (ispointer) { - SwigType_del_pointer(resolved); - } - if (isreference) { - SwigType_del_reference(resolved); - } - } - String *tmp = NewString(""); - Insert(tmp, 0, Char(SwigType_manglestr(resolved))); - return(tmp); -} - -/* -------------------------------------------------------------- - * Tries to get the name of the R class corresponding to the given type - * e.g. struct A * is ARef, struct A** is ARefRef. - * Now handles arrays, i.e. struct A[2] - * --------------------------------------------------------------*/ - - -static String * getRClassNameCopyStruct(String *retType, int addRef) { - String *tmp = NewString(""); - - List *l = SwigType_split(retType); - int n = Len(l); - if(!l || n == 0) { -#ifdef R_SWIG_VERBOSE - Printf(stdout, "SwigType_split return an empty list for %s\n", retType); -#endif - return(tmp); - } - - - String *el = Getitem(l, n-1); - char *ptr = Char(el); - if(strncmp(ptr, "struct ", 7) == 0) - ptr += 7; - - Printf(tmp, "%s", ptr); - - if(addRef) { - for(int i = 0; i < n; i++) { - if(Strcmp(Getitem(l, i), "p.") == 0 || - Strncmp(Getitem(l, i), "a(", 2) == 0) - Printf(tmp, "Ref"); - } - } - - return tmp; -} - - -/* ------------------------------------------------------------- - * Write the elements of a list to the File*, one element per line. - * If quote is true, surround the element with "element". - * This takes care of inserting a tab in front of each line and also - * a comma after each element, except the last one. - * --------------------------------------------------------------*/ - - -static void writeListByLine(List *l, File *out, bool quote = 0) { - int i, n = Len(l); - for(i = 0; i < n; i++) - Printf(out, "%s%s%s%s%s\n", tab8, - quote ? "\"" :"", - Getitem(l, i), - quote ? "\"" :"", i < n-1 ? "," : ""); -} - - -static const char *usage = "\ -R Options (available with -r)\n\ - -copystruct - Emit R code to copy C structs (on by default)\n\ - -debug - Output debug\n\ - -dll <name> - Name of the DLL (without the .dll or .so suffix).\n\ - Default is the module name.\n\ - -gc - Aggressive garbage collection\n\ - -memoryprof - Add memory profile\n\ - -namespace - Output NAMESPACE file\n\ - -no-init-code - Turn off the generation of the R_init_<pkgname> code\n\ - (registration information still generated)\n\ - -package <name> - Package name for the PACKAGE argument of the R .Call()\n\ - invocations. Default is the module name.\n\ -"; - - - -/* ------------------------------------------------------------- - * Display the help for this module on the screen/console. - * --------------------------------------------------------------*/ - -static void showUsage() { - fputs(usage, stdout); -} - -static bool expandTypedef(SwigType *t) { - if (SwigType_isenum(t)) return false; - String *prefix = SwigType_prefix(t); - if (Strncmp(prefix, "f", 1)) return false; - if (Strncmp(prefix, "p.f", 3)) return false; - return true; -} - - -/* ------------------------------------------------------------- - * Determine whether we should add a .copy argument to the S function - * that wraps/interfaces to the routine that returns the given type. - * --------------------------------------------------------------*/ - -static int addCopyParameter(SwigType *type) { - int ok = 0; - ok = Strncmp(type, "struct ", 7) == 0 || Strncmp(type, "p.struct ", 9) == 0; - if(!ok) { - ok = Strncmp(type, "p.", 2); - } - - return(ok); -} - -static void replaceRClass(String *tm, SwigType *type) { - String *tmp = getRClassName(type, 0, 0); - String *tmp_base = getRClassName(type, 1, 0); - String *tmp_ref = getRClassName(type, 0, 1); - Replaceall(tm, "$R_class", tmp); - Replaceall(tm, "$*R_class", tmp_base); - Replaceall(tm, "$&R_class", tmp_ref); - Delete(tmp); Delete(tmp_base); Delete(tmp_ref); -} - -class R : public Language { -public: - R(); - void registerClass(Node *n); - void main(int argc, char *argv[]); - int top(Node *n); - - void dispatchFunction(Node *n); - int functionWrapper(Node *n); - int constantWrapper(Node *n); - int variableWrapper(Node *n); - - int classDeclaration(Node *n); - int enumDeclaration(Node *n); - String *enumValue(Node *n); - virtual int enumvalueDeclaration(Node *n); - int membervariableHandler(Node *n); - - int typedefHandler(Node *n); - - static List *Swig_overload_rank(Node *n, bool script_lang_wrapping); - - int memberfunctionHandler(Node *n) { - if (debugMode) - Printf(stdout, "<memberfunctionHandler> %s %s\n", - Getattr(n, "name"), - Getattr(n, "type")); - member_name = Getattr(n, "sym:name"); - processing_class_member_function = 1; - int status = Language::memberfunctionHandler(n); - processing_class_member_function = 0; - return status; - } - - /* Grab the name of the current class being processed so that we can - deal with members of that class. */ - int classHandler(Node *n){ - if(!ClassMemberTable) - ClassMemberTable = NewHash(); - - class_name = Getattr(n, "name"); - int status = Language::classHandler(n); - - class_name = NULL; - return status; - } - - String *runtimeCode(); - void replaceSpecialVariables(String *method, String *tm, Parm *parm); - -protected: - int addRegistrationRoutine(String *rname, int nargs); - int outputRegistrationRoutines(File *out); - - int outputCommandLineArguments(File *out); - int generateCopyRoutines(Node *n); - int DumpCode(Node *n); - - int OutputMemberReferenceMethod(String *className, int isSet, List *memberList, List *nameList, List *typeList, File *out); - int defineArrayAccessors(SwigType *type); - - void addNamespaceFunction(String *name) { - if(!namespaceFunctions) - namespaceFunctions = NewList(); - Append(namespaceFunctions, name); - } - - void addNamespaceMethod(String *name) { - if(!namespaceMethods) - namespaceMethods = NewList(); - Append(namespaceMethods, name); - } - - String* processType(SwigType *t, Node *n, int *nargs = NULL); - String *createFunctionPointerHandler(SwigType *t, Node *n, int *nargs); - int addFunctionPointerProxy(String *name, Node *n, SwigType *t, String *s_paramTypes) { - /*XXX Do we need to put the t in there to get the return type later. */ - if(!functionPointerProxyTable) - functionPointerProxyTable = NewHash(); - - Setattr(functionPointerProxyTable, name, n); - - Setattr(SClassDefs, name, name); - Printv(s_classes, "setClass('", - name, - "',\n", tab8, - "prototype = list(parameterTypes = c(", s_paramTypes, "),\n", - tab8, tab8, tab8, - "returnType = '", SwigType_manglestr(t), "'),\n", tab8, - "contains = 'CRoutinePointer')\n\n##\n", NIL); - - return SWIG_OK; - } - - - void addSMethodInfo(String *name, - String *argType, int nargs); - // Simple initialization such as constant strings that can be reused. - void init(); - - - void addAccessor(String *memberName, Wrapper *f, - String *name, String *methodSetGet); - - static int getFunctionPointerNumArgs(Node *n, SwigType *tt); - - // filtering of class member lists by function type. Used in constructing accessors - // are we allowed to use stl style functors to customise this? - List* filterMemberList(List *class_member_function_types, List *class_member_other, String *R_MEMBER, bool equal); - -protected: - bool copyStruct; - bool memoryProfile; - bool aggressiveGc; - - // Strings into which we cumulate the generated code that is to be written - //vto the files. - String *enum_values; - String *enum_def_calls; - String *sfile; - String *f_init; - String *s_classes; - String *f_begin; - String *f_runtime; - String *f_wrapper; - String *s_header; - String *f_wrappers; - String *s_init; - String *s_init_routine; - String *s_namespace; - - // State variables that carry information across calls to functionWrapper() - // from member accessors and class declarations. - String *opaqueClassDeclaration; - int processing_variable; - int processing_member_access_function; - String *member_name; - String *class_name; - - String *R_MEMBER_NORMAL; - String *R_MEMBER_SET; - String *R_MEMBER_GET; - - int processing_class_member_function; - // Spread out the lists so that they are simpler to process - // by storing the type of the method (i.e. set, get or nothing) - // and having separate lists for name, membername and wrapper - List *class_member_function_types; - List *class_member_function_names; - List *class_member_function_membernames; - List *class_member_function_wrappernames; - /* */ - Hash *ClassMemberTable; - Hash *ClassMethodsTable; - Hash *SClassDefs; - Hash *SMethodInfo; - - // Information about routines that are generated and to be registered with - // R for dynamic lookup. - Hash *registrationTable; - Hash *functionPointerProxyTable; - - List *namespaceFunctions; - List *namespaceMethods; - List *namespaceClasses; // Probably can do this from ClassMemberTable. - - - // Store a copy of the command line. - // Need only keep a string that has it formatted. - char **Argv; - int Argc; - bool inCPlusMode; - - // State variables that we remember from the command line settings - // potentially that govern the code we generate. - String *DllName; - String *Rpackage; - bool noInitializationCode; - bool outputNamespaceInfo; - - String *UnProtectWrapupCode; - - // Static members - static bool debugMode; -}; - -R::R() : - copyStruct(false), - memoryProfile(false), - aggressiveGc(false), - enum_values(0), - enum_def_calls(0), - sfile(0), - f_init(0), - s_classes(0), - f_begin(0), - f_runtime(0), - f_wrapper(0), - s_header(0), - f_wrappers(0), - s_init(0), - s_init_routine(0), - s_namespace(0), - opaqueClassDeclaration(0), - processing_variable(0), - processing_member_access_function(0), - member_name(0), - class_name(0), - R_MEMBER_NORMAL(NewString("normal")), - R_MEMBER_SET(NewString("set")), - R_MEMBER_GET(NewString("get")), - processing_class_member_function(0), - class_member_function_types(0), - class_member_function_names(0), - class_member_function_membernames(0), - class_member_function_wrappernames(0), - ClassMemberTable(0), - ClassMethodsTable(0), - SClassDefs(0), - SMethodInfo(0), - registrationTable(0), - functionPointerProxyTable(0), - namespaceFunctions(0), - namespaceMethods(0), - namespaceClasses(0), - Argv(0), - Argc(0), - inCPlusMode(false), - DllName(0), - Rpackage(0), - noInitializationCode(false), - outputNamespaceInfo(false), - UnProtectWrapupCode(0) { -} - -bool R::debugMode = false; - -int R::getFunctionPointerNumArgs(Node *n, SwigType *tt) { - (void) tt; - n = Getattr(n, "type"); - if (debugMode) - Printf(stdout, "type: %s\n", n); - - ParmList *parms = Getattr(n, "parms"); - if (debugMode) - Printf(stdout, "parms = %p\n", parms); - return ParmList_len(parms); -} - - -void R::addSMethodInfo(String *name, String *argType, int nargs) { - (void) argType; - - if(!SMethodInfo) - SMethodInfo = NewHash(); - if (debugMode) - Printf(stdout, "[addMethodInfo] %s\n", name); - - Hash *tb = Getattr(SMethodInfo, name); - - if(!tb) { - tb = NewHash(); - Setattr(SMethodInfo, name, tb); - } - - String *str = Getattr(tb, "max"); - int max = -1; - if(str) - max = atoi(Char(str)); - if(max < nargs) { - if(str) Delete(str); - str = NewStringf("%d", max); - Setattr(tb, "max", str); - } -} - -/* ---------------------------------------- - * Returns the name of the new routine. - * ------------------------------------------ */ - -String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) { - String *funName = SwigType_manglestr(t); - - /* See if we have already processed this one. */ - if(functionPointerProxyTable && Getattr(functionPointerProxyTable, funName)) - return funName; - - if (debugMode) - Printf(stdout, "<createFunctionPointerHandler> Defining %s\n", t); - - SwigType *rettype = Copy(Getattr(n, "type")); - SwigType *funcparams = SwigType_functionpointer_decompose(rettype); - String *rtype = SwigType_str(rettype, 0); - - // ParmList *parms = Getattr(n, "parms"); - // memory leak - ParmList *parms = SwigType_function_parms(SwigType_del_pointer(Copy(t)), n); - - - if (debugMode) { - Printf(stdout, "Type: %s\n", t); - Printf(stdout, "Return type: %s\n", SwigType_base(t)); - } - - bool isVoidType = Strcmp(rettype, "void") == 0; - if (debugMode) - Printf(stdout, "%s is void ? %s (%s)\n", funName, isVoidType ? "yes" : "no", rettype); - - Wrapper *f = NewWrapper(); - - /* Go through argument list, attach lnames for arguments */ - int i = 0; - Parm *p = parms; - for (i = 0; p; p = nextSibling(p), ++i) { - String *arg = Getattr(p, "name"); - String *lname; - if (!arg && Cmp(Getattr(p, "type"), "void")) { - lname = NewStringf("arg%d", i+1); - Setattr(p, "name", lname); - } else - lname = arg; - - Setattr(p, "lname", lname); - } - - Swig_typemap_attach_parms("out", parms, f); - Swig_typemap_attach_parms("scoerceout", parms, f); - Swig_typemap_attach_parms("scheck", parms, f); - - Printf(f->def, "%s %s(", rtype, funName); - - emit_parameter_variables(parms, f); - emit_return_variable(n, rettype, f); - // emit_attach_parmmaps(parms,f); - - /* Using weird name and struct to avoid potential conflicts. */ - Wrapper_add_local(f, "r_swig_cb_data", "RCallbackFunctionData *r_swig_cb_data = R_SWIG_getCallbackFunctionData()"); - String *lvar = NewString("r_swig_cb_data"); - - Wrapper_add_local(f, "r_tmp", "SEXP r_tmp"); // for use in converting arguments to R objects for call. - Wrapper_add_local(f, "r_nprotect", "int r_nprotect = 0"); // for use in converting arguments to R objects for call. - Wrapper_add_local(f, "r_vmax", "char * r_vmax= 0"); // for use in converting arguments to R objects for call. - - // Add local for error code in return value. This is not in emit_return_variable because that assumes an out typemap - // whereas the type makes are reverse - Wrapper_add_local(f, "ecode", "int ecode = 0"); - - p = parms; - int nargs = ParmList_len(parms); - if(numArgs) { - *numArgs = nargs; - if (debugMode) - Printf(stdout, "Setting number of parameters to %d\n", *numArgs); - } - String *setExprElements = NewString(""); - - String *s_paramTypes = NewString(""); - for(i = 0; p; i++) { - SwigType *tt = Getattr(p, "type"); - SwigType *name = Getattr(p, "name"); - SwigType *swig_parm_name = NewStringf("swigarg_%s", name); - String *tm = Getattr(p, "tmap:out"); - bool isVoidParm = Strcmp(tt, "void") == 0; - if (isVoidParm) - Printf(f->def, "%s", SwigType_str(tt, 0)); - else - Printf(f->def, "%s %s", SwigType_str(tt, 0), swig_parm_name); - if (tm) { - String *lstr = SwigType_lstr(tt, 0); - if (SwigType_isreference(tt) || SwigType_isrvalue_reference(tt)) { - Printf(f->code, "%s = (%s) &%s;\n", Getattr(p, "lname"), lstr, swig_parm_name); - } else if (!isVoidParm) { - Printf(f->code, "%s = (%s) %s;\n", Getattr(p, "lname"), lstr, swig_parm_name); - } - Replaceall(tm, "$1", name); - Replaceall(tm, "$result", "r_tmp"); - if (debugMode) { - Printf(stdout, "Calling Replace A: %s\n", Getattr(p,"type")); - } - replaceRClass(tm, Getattr(p,"type")); - Replaceall(tm,"$owner", "0"); - Delete(lstr); - } - - Printf(setExprElements, "%s\n", tm); - Printf(setExprElements, "SETCAR(r_swig_cb_data->el, %s);\n", "r_tmp"); - Printf(setExprElements, "r_swig_cb_data->el = CDR(r_swig_cb_data->el);\n\n"); - - Printf(s_paramTypes, "'%s'", SwigType_manglestr(tt)); - - - p = nextSibling(p); - if(p) { - Printf(f->def, ", "); - Printf(s_paramTypes, ", "); - } - } - - Printf(f->def, ") {\n"); - - Printf(f->code, "Rf_protect(%s->expr = Rf_allocVector(LANGSXP, %d));\n", lvar, nargs + 1); - Printf(f->code, "r_nprotect++;\n"); - Printf(f->code, "r_swig_cb_data->el = r_swig_cb_data->expr;\n\n"); - - Printf(f->code, "SETCAR(r_swig_cb_data->el, r_swig_cb_data->fun);\n"); - Printf(f->code, "r_swig_cb_data->el = CDR(r_swig_cb_data->el);\n\n"); - - Printf(f->code, "%s\n\n", setExprElements); - - Printv(f->code, "r_swig_cb_data->retValue = R_tryEval(", - "r_swig_cb_data->expr,", - " R_GlobalEnv,", - " &r_swig_cb_data->errorOccurred", - ");\n", - NIL); - - Printv(f->code, "\n", - "if(r_swig_cb_data->errorOccurred) {\n", - "R_SWIG_popCallbackFunctionData(1);\n", - "Rf_error(\"error in calling R function as a function pointer (", - funName, - ")\");\n", - "}\n", - NIL); - - - - if(!isVoidType) { - /* Need to deal with the return type of the function pointer, not the function pointer itself. - So build a new node that has the relevant pieces. - XXX Have to be a little more clever so that we can deal with struct A * - the * is getting lost. - Is this still true? If so, will a SwigType_push() solve things? - */ - Parm *bbase = NewParmNode(rettype, n); - String *returnTM = Swig_typemap_lookup("in", bbase, Swig_cresult_name(), f); - if(returnTM) { - String *tm = returnTM; - Replaceall(tm,"$input", "r_swig_cb_data->retValue"); - replaceRClass(tm, rettype); - Replaceall(tm,"$owner", "0"); - Replaceall(tm,"$disown","0"); - Printf(f->code, "%s\n", tm); - } - Delete(bbase); - } - - Printv(f->code, "R_SWIG_popCallbackFunctionData(1);\n", NIL); - Printv(f->code, "\n", UnProtectWrapupCode, NIL); - - if (SwigType_isreference(rettype)) { - Printv(f->code, "return *", Swig_cresult_name(), ";\n", NIL); - } else if (SwigType_isrvalue_reference(rettype)) { - Printv(f->code, "return std::move(*", Swig_cresult_name(), ");\n", NIL); - } else if (!isVoidType) { - Printv(f->code, "return ", Swig_cresult_name(), ";\n", NIL); - } - - Printv(f->code, "\n}\n", NIL); - Replaceall(f->code, "SWIG_exception_fail", "SWIG_exception_noreturn"); - - /* To coerce correctly in S, we really want to have an extra/intermediate - function that handles the scoerceout. - We need to check if any of the argument types have an entry in - that map. If none do, the ignore and call the function straight. - Otherwise, generate a marshalling function. - Need to be able to find it in S. Or use an entirely generic one - that evaluates the expressions. - Handle errors in the evaluation of the function by restoring - the stack, if there is one in use for this function (i.e. no - userData). - */ - - Wrapper_print(f, f_wrapper); - - addFunctionPointerProxy(funName, n, t, s_paramTypes); - Delete(s_paramTypes); - Delete(rtype); - Delete(rettype); - Delete(funcparams); - DelWrapper(f); - - return funName; -} - -void R::init() { - UnProtectWrapupCode = - NewStringf("%s", "vmaxset(r_vmax);\nif(r_nprotect) Rf_unprotect(r_nprotect);\n\n"); - - SClassDefs = NewHash(); - - sfile = NewString(""); - f_init = NewString(""); - s_header = NewString(""); - f_begin = NewString(""); - f_runtime = NewString(""); - f_wrapper = NewString(""); - s_classes = NewString(""); - s_init = NewString(""); - s_init_routine = NewString(""); - enum_def_calls = NewString(""); -} - - -/* ------------------------------------------------------------- - * Method from Language that is called to start the entire - * processing off, i.e. the generation of the code. - * It is called after the input has been read and parsed. - * Here we open the output streams and generate the code. - * ------------------------------------------------------------- */ -int R::top(Node *n) { - String *module = Getattr(n, "name"); - - if (debugMode) { - Printf(stdout, "<Top> %s\n", module); - } - - if(!Rpackage) - Rpackage = Copy(module); - if(!DllName) - DllName = Copy(module); - - if(outputNamespaceInfo) { - s_namespace = NewString(""); - Swig_register_filebyname("snamespace", s_namespace); - Printf(s_namespace, "useDynLib(%s)\n", DllName); - } - // Register the naming functions - Swig_name_register("wrapper", "R_swig_%f"); - - /* Associate the different streams with names so that they can be used in %insert directives by the - typemap code. */ - Swig_register_filebyname("sinit", s_init); - Swig_register_filebyname("sinitroutine", s_init_routine); - - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", f_init); - Swig_register_filebyname("header", s_header); - Swig_register_filebyname("wrapper", f_wrapper); - Swig_register_filebyname("s", sfile); - Swig_register_filebyname("sclasses", s_classes); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "R"); - - Swig_banner_target_lang(s_init, "#"); - outputCommandLineArguments(s_init); - - Printf(f_wrapper, "#ifdef __cplusplus\n"); - Printf(f_wrapper, "extern \"C\" {\n"); - Printf(f_wrapper, "#endif\n\n"); - - Language::top(n); - - Printf(f_wrapper, "#ifdef __cplusplus\n"); - Printf(f_wrapper, "}\n"); - Printf(f_wrapper, "#endif\n"); - - String *type_table = NewString(""); - SwigType_emit_type_table(f_runtime,f_wrapper); - Delete(type_table); - - if(ClassMemberTable) { - //XXX OutputClassAccessInfo(ClassMemberTable, sfile); - Delete(ClassMemberTable); - ClassMemberTable = NULL; - } - - Printf(f_init,"}\n"); - if(registrationTable) - outputRegistrationRoutines(f_init); - - /* Now arrange to write the 2 files - .S and .c. */ - - DumpCode(n); - - Delete(sfile); - Delete(s_classes); - Delete(s_init); - Delete(f_wrapper); - Delete(f_init); - - Delete(s_header); - Delete(f_runtime); - Delete(f_begin); - - return SWIG_OK; -} - - -/* ------------------------------------------------------------- - * Write the generated code to the .S and the .c files. - * ------------------------------------------------------------- */ -int R::DumpCode(Node *n) { - String *output_filename = NewString(""); - - - /* The name of the file in which we will generate the S code. */ - Printf(output_filename, "%s%s.R", SWIG_output_directory(), Rpackage); - -#ifdef R_SWIG_VERBOSE - Printf(stdout, "Writing S code to %s\n", output_filename); -#endif - - File *scode = NewFile(output_filename, "w", SWIG_output_files()); - if (!scode) { - FileErrorDisplay(output_filename); - Exit(EXIT_FAILURE); - } - Delete(output_filename); - - - Printf(scode, "%s\n\n", s_init); - Printf(scode, "%s\n\n", s_classes); - Printf(scode, "%s\n", sfile); - Printf(scode, "%s\n", enum_def_calls); - - Delete(scode); - String *outfile = Getattr(n,"outfile"); - File *runtime = NewFile(outfile,"w", SWIG_output_files()); - if (!runtime) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - - Printf(runtime, "%s", f_begin); - Printf(runtime, "%s\n", f_runtime); - Printf(runtime, "%s\n", s_header); - Printf(runtime, "%s\n", f_wrapper); - Printf(runtime, "%s\n", f_init); - - Delete(runtime); - - if(outputNamespaceInfo) { - output_filename = NewString(""); - Printf(output_filename, "%sNAMESPACE", SWIG_output_directory()); - File *ns = NewFile(output_filename, "w", SWIG_output_files()); - if (!ns) { - FileErrorDisplay(output_filename); - Exit(EXIT_FAILURE); - } - Delete(output_filename); - - Printf(ns, "%s\n", s_namespace); - - Printf(ns, "\nexport(\n"); - writeListByLine(namespaceFunctions, ns); - Printf(ns, ")\n"); - Printf(ns, "\nexportMethods(\n"); - writeListByLine(namespaceMethods, ns, 1); - Printf(ns, ")\n"); - Delete(ns); - Delete(s_namespace); - } - - return SWIG_OK; -} - - -List *R::filterMemberList(List *class_member_types, - List *class_member_other, - String *R_MEMBER, bool equal) { - // filters class_member_other based on whether corresponding elements of - // class_member_function_types are equal or notequal to R_MEMBER - List *CM = NewList(); - Iterator ftype, other; - - for (ftype = First(class_member_types), other = First(class_member_other); - ftype.item; - ftype=Next(ftype), other=Next(other)) { - // verbose, clean up later if the overall structure works - if (equal) { - if (ftype.item == R_MEMBER) { - Append(CM, other.item); - } - } else { - if (ftype.item != R_MEMBER) { - Append(CM, other.item); - } - } - } - return(CM); -} - -# if 0 -// not called -/* ------------------------------------------------------------- - * We may need to do more.... so this is left as a - * stub for the moment. - * -------------------------------------------------------------*/ -int R::OutputClassAccessInfo(Hash *tb, File *out) { - int n = OutputClassMemberTable(tb, out); - OutputClassMethodsTable(out); - return n; -} - -/* ------------------------------------------------------------- - * Currently this just writes the information collected about the - * different methods of the C++ classes that have been processed - * to the console. - * This will be used later to define S4 generics and methods. - * --------------------------------------------------------------*/ - -int R::OutputClassMethodsTable(File *) { - Hash *tb = ClassMethodsTable; - - if(!tb) - return SWIG_OK; - - List *keys = Keys(tb); - String *key; - int i, n = Len(keys); - if (debugMode) { - for(i = 0; i < n ; i++ ) { - key = Getitem(keys, i); - Printf(stdout, "%d) %s\n", i, key); - List *els = Getattr(tb, key); - int nels = Len(els); - Printf(stdout, "\t"); - for(int j = 0; j < nels; j+=2) { - Printf(stdout, "%s%s", Getitem(els, j), j < nels - 1 ? ", " : ""); - Printf(stdout, "%s\n", Getitem(els, j+1)); - } - Printf(stdout, "\n"); - } - } - - return SWIG_OK; -} - - -/* -------------------------------------------------------------- - * Iterate over the <class name>_set and <>_get - * elements and generate the $ and $<- functions - * that provide constrained access to the member - * fields in these elements. - - * tb - a hash table that is built up in functionWrapper - * as we process each membervalueHandler. - * The entries are indexed by <class name>_set and - * <class_name>_get. Each entry is a List *. - - * out - the stream where the code is to be written. This is the S - * code stream as we generate only S code here. - * --------------------------------------------------------------*/ - -int R::OutputClassMemberTable(Hash *tb, File *out) { - List *keys = Keys(tb), *el; - - String *key; - int i, n = Len(keys); - /* Loop over all the <Class>_set and <Class>_get entries in the table. */ - /* This function checks for names ending in _set - perhaps it should */ - /* use attributes of some other form, as it potentially clashes with */ - /* methods ending in _set */ - - if(n && outputNamespaceInfo) { - Printf(s_namespace, "exportClasses("); - } - for(i = 0; i < n; i++) { - key = Getitem(keys, i); - el = Getattr(tb, key); - - String *className = Getitem(el, 0); - char *ptr = Char(key); - int klen = Len(key); - int isSet = 0; - if (klen > 4) { - ptr = &ptr[klen - 4]; - isSet = strcmp(ptr, "_set") == 0; - } - - if(outputNamespaceInfo) - Printf(s_namespace, "\"%s\"%s", className, i < n-1 ? "," : ""); - } - if(n && outputNamespaceInfo) { - Printf(s_namespace, ")\n"); - } - - return n; -} - -// end not used -#endif -/* -------------------------------------------------------------- - * Write the methods for $ or $<- for accessing a member field in an - * struct or union (or class). - * className - the name of the struct or union (e.g. Bar for struct Bar) - * isSet - a logical value indicating whether the method is for - * modifying ($<-) or accessing ($) the member field. - * el - a list of length 2 * # accessible member elements + 1. - * The first element is the name of the class. - * The other pairs are member name and the name of the R function to access it. - * out - the stream where we write the code. - * --------------------------------------------------------------*/ - -int R::OutputMemberReferenceMethod(String *className, int isSet, - List *memberList, List *nameList, - List *typeList, File *out) { - int numMems = Len(memberList), j; - int varaccessor = 0; - if (numMems == 0) - return SWIG_OK; - - Wrapper *f = NewWrapper(), *attr = NewWrapper(); - - Printf(f->def, "function(x, name%s)", isSet ? ", value" : ""); - Printf(attr->def, "function(x, i, j, ...%s)", isSet ? ", value" : ""); - - Printf(f->code, "{\n"); - Printf(f->code, "%saccessorFuns = list(", tab8); - - Node *itemList = NewHash(); - bool has_prev = false; - for(j = 0; j < numMems; j++) { - String *item = Getitem(memberList, j); - String *dup = Getitem(nameList, j); - String *setgetmethod = Getitem(typeList, j); - - if (setgetmethod == R_MEMBER_GET) - varaccessor++; - - if (Getattr(itemList, item)) - continue; - Setattr(itemList, item, "1"); - - String *pitem; - if (!Strcmp(item, "operator ()")) { - pitem = NewString("call"); - } else if (!Strcmp(item, "operator ->")) { - pitem = NewString("deref"); - } else if (!Strcmp(item, "operator +")) { - pitem = NewString("add"); - } else if (!Strcmp(item, "operator -")) { - pitem = NewString("sub"); - } else { - pitem = Copy(item); - } - if (has_prev) - Printf(f->code, ", "); - Printf(f->code, "'%s' = %s", pitem, dup); - has_prev = true; - Delete(pitem); - } - Delete(itemList); - Printf(f->code, ");\n"); - - if (!isSet && varaccessor > 0) { - Printf(f->code, "%svaccessors = c(", tab8); - bool first = true; - for(j = 0; j < numMems; j++) { - String *item = Getitem(memberList, j); - String *setgetmethod = Getitem(typeList, j); - - // Check the type here instead of the name - if (setgetmethod == R_MEMBER_GET) { - Printf(f->code, "%s'%s'", first ? "" : ", ", item); - first = false; - } - } - Printf(f->code, ");\n"); - } - - Printv(f->code, ";", tab8, - "idx = pmatch(name, names(accessorFuns));\n", - tab8, - "if(is.na(idx)) \n", - tab8, tab4, NIL); - Printf(f->code, "return(callNextMethod(x, name%s));\n", - isSet ? ", value" : ""); - Printv(f->code, tab8, "f = accessorFuns[[idx]];\n", NIL); - if(isSet) { - Printv(f->code, tab8, "f(x, value);\n", NIL); - Printv(f->code, tab8, "x;\n", NIL); // make certain to return the S value. - } else { - if (varaccessor) { - Printv(f->code, tab8, - "if (is.na(match(name, vaccessors))) function(...){f(x, ...)} else f(x);\n", NIL); - } else { - Printv(f->code, tab8, "function(...){f(x, ...)};\n", NIL); - } - } - Printf(f->code, "}\n"); - - String *classname_str = SwigType_namestr(className); - Printf(out, "# Start of accessor method for %s\n", classname_str); - Printf(out, "setMethod('$%s', '_p%s', ", - isSet ? "<-" : "", - getRClassName(className)); - Wrapper_print(f, out); - Printf(out, ");\n"); - - if(isSet) { - Printf(out, "setMethod('[[<-', c('_p%s', 'character'),", - getRClassName(className)); - Insert(f->code, 2, "name = i;\n"); - Printf(attr->code, "%s", f->code); - Wrapper_print(attr, out); - Printf(out, ");\n"); - } - - Printf(out, "# end of accessor method for %s\n", classname_str); - - Delete(classname_str); - DelWrapper(attr); - DelWrapper(f); - - return SWIG_OK; -} - -/* ------------------------------------------------------------- - * Called when a enumeration is to be processed. - * We want to call the R function defineEnumeration(). - * tdname is the typedef of the enumeration, i.e. giving its name. - * --------------------------------------------------------------*/ - -int R::enumDeclaration(Node *n) { - if (!ImportMode) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) - return SWIG_NOWRAP; - - String *symname = Getattr(n, "sym:name"); - - // TODO - deal with anonymous enumerations - // Previous enum code for R didn't wrap them - if (!symname || Getattr(n, "unnamedinstance")) - return SWIG_NOWRAP; - - // create mangled name for the enum - // This will have content if the %nspace feature is set on - // the input file - String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call - String *ename; - - String *name = Getattr(n, "name"); - ename = getRClassName(name); - if (debugMode) { - Node *current_class = getCurrentClass(); - String *cl = NewString(""); - if (current_class) { - cl = getEnumClassPrefix(); - } - Printf(stdout, "enumDeclaration: %s, %s, %s, %s, %s\n", name, symname, nspace, ename, cl); - } - Delete(name); - // set up a call to create the R enum structure. The list of - // individual elements will be built in enum_code - enum_values = 0; - // Emit each enum item - Language::enumDeclaration(n); - - Printf(enum_def_calls, "defineEnumeration(\"%s\",\n .values=c(%s))\n\n", ename, enum_values); - Delete(enum_values); - Delete(ename); - } - return SWIG_OK; -} - -/* ------------------------------------------------------------- -* --------------------------------------------------------------*/ - -int R::enumvalueDeclaration(Node *n) { - if (getCurrentClass() && (cplus_mode != PUBLIC)) { - Printf(stdout, "evd: Not public\n"); - return SWIG_NOWRAP; - } - - Swig_require("enumvalueDeclaration", n, "*name", "?value", NIL); - String *symname = Getattr(n, "sym:name"); - String *value = Getattr(n, "value"); - String *name = Getattr(n, "name"); - Node *parent = parentNode(n); - String *parent_name = Getattr(parent, "name"); - String *newsymname = 0; - String *tmpValue; - - // Strange hack from parent method - if (value) - tmpValue = NewString(value); - else - tmpValue = NewString(name); - // Note that this is used in enumValue() amongst other places - Setattr(n, "value", tmpValue); - - // Deal with enum values that are not int - int swigtype = SwigType_type(Getattr(n, "type")); - if (swigtype == T_BOOL) { - const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0"; - Setattr(n, "enumvalue", val); - } else if (swigtype == T_CHAR) { - String *val = NewStringf("'%s'", Getattr(n, "enumvalue")); - Setattr(n, "enumvalue", val); - Delete(val); - } - - if (GetFlag(parent, "scopedenum")) { - newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname); - symname = newsymname; - } - - { - // Wrap C/C++ enums with constant integers or use the typesafe enum pattern - SwigType *typemap_lookup_type = parent_name ? parent_name : NewString("enum "); - if (debugMode) { - Printf(stdout, "Setting type: %s\n", Copy(typemap_lookup_type)); - } - Setattr(n, "type", typemap_lookup_type); - - // Simple integer constants - // Note these are always generated for anonymous enums, no matter what enum_feature is specified - // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later - - String *value = enumValue(n); - if (enum_values) { - Printf(enum_values, ",\n\"%s\" = %s", name, value); - } else { - enum_values = NewString(""); - Printf(enum_values, "\"%s\" = %s", name, value); - } - - Delete(value); - } - - return SWIG_OK; -} - - -/* ------------------------------------------------------------- - * Create accessor functions for variables. - * Does not create equivalent wrappers for enumerations, - * which are handled differently - * --------------------------------------------------------------*/ - -int R::variableWrapper(Node *n) { - String *name = Getattr(n, "sym:name"); - if (debugMode) { - Printf(stdout, "variableWrapper %s\n", n); - } - processing_variable = 1; - Language::variableWrapper(n); // Force the emission of the _set and _get function wrappers. - processing_variable = 0; - - - SwigType *ty = Getattr(n, "type"); - String *nodeType = nodeType(n); - int addCopyParam = addCopyParameter(ty); - - //XXX - processType(ty, n); - - if (nodeType && !Strcmp(nodeType, "enumitem")) { - /* special wrapper for enums - don't want the R _set, _get functions*/ - if (debugMode) { - Printf(stdout, "variableWrapper enum branch\n"); - } - } else if(!SwigType_isconst(ty)) { - Wrapper *f = NewWrapper(); - Printf(f->def, "%s = \nfunction(value%s)\n{\n", - name, addCopyParam ? ", .copy = FALSE" : ""); - Printv(f->code, "if(missing(value)) {\n", - name, "_get(", addCopyParam ? ".copy" : "", ")\n}", NIL); - Printv(f->code, " else {\n", - name, "_set(value)\n}\n}", NIL); - - Wrapper_print(f, sfile); - DelWrapper(f); - } else { - Printf(sfile, "%s = %s_get\n", name, name); - } - - return SWIG_OK; -} - -/* ------------------------------------------------------------- - * Creates accessor functions for class members. - - * ToDo - this version depends on naming conventions and needs - * to be replaced. - * --------------------------------------------------------------*/ - -void R::addAccessor(String *memberName, Wrapper *wrapper, String *name, - String *methodSetGet) { - - if (!class_member_function_names) { - class_member_function_names = NewList(); - class_member_function_membernames = NewList(); - class_member_function_wrappernames = NewList(); - class_member_function_types = NewList(); - } - Append(class_member_function_types, methodSetGet); - Append(class_member_function_names, name); - Append(class_member_function_membernames, memberName); - - String *tmp = NewString(""); - Wrapper_print(wrapper, tmp); - Append(class_member_function_wrappernames, tmp); - // if we could put the wrapper in directly: Append(l, Copy(sfun)); - if (debugMode) - Printf(stdout, "Adding accessor: %s (%s) => %s\n", memberName, name, tmp); -} - -#define MAX_OVERLOAD 256 - -namespace { -struct Overloaded { - Node *n; /* Node */ - int argc; /* Argument count */ - ParmList *parms; /* Parameters used for overload check */ - int error; /* Ambiguity error */ -}; -} - -List * R::Swig_overload_rank(Node *n, - bool script_lang_wrapping) { - Overloaded nodes[MAX_OVERLOAD]; - int nnodes = 0; - Node *o = Getattr(n,"sym:overloaded"); - - - if (!o) return 0; - - Node *c = o; - while (c) { - if (Getattr(c,"error")) { - c = Getattr(c,"sym:nextSibling"); - continue; - } - /* Make a list of all the declarations (methods) that are overloaded with - * this one particular method name */ - - if (Getattr(c,"wrap:name")) { - nodes[nnodes].n = c; - nodes[nnodes].parms = Getattr(c,"wrap:parms"); - nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms); - nodes[nnodes].error = 0; - nnodes++; - } - c = Getattr(c,"sym:nextSibling"); - } - - /* Sort the declarations by required argument count */ - { - int i,j; - for (i = 0; i < nnodes; i++) { - for (j = i+1; j < nnodes; j++) { - if (nodes[i].argc > nodes[j].argc) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - } - } - } - - /* Sort the declarations by argument types */ - { - int i,j; - for (i = 0; i < nnodes-1; i++) { - if (nodes[i].argc == nodes[i+1].argc) { - for (j = i+1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) { - Parm *p1 = nodes[i].parms; - Parm *p2 = nodes[j].parms; - int differ = 0; - int num_checked = 0; - while (p1 && p2 && (num_checked < nodes[i].argc)) { - if (debugMode) { - Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type")); - } - if (checkAttribute(p1,"tmap:in:numinputs","0")) { - p1 = Getattr(p1,"tmap:in:next"); - continue; - } - if (checkAttribute(p2,"tmap:in:numinputs","0")) { - p2 = Getattr(p2,"tmap:in:next"); - continue; - } - String *t1 = Getattr(p1,"tmap:typecheck:precedence"); - String *t2 = Getattr(p2,"tmap:typecheck:precedence"); - if (debugMode) { - Printf(stdout,"t1 = '%s', t2 = '%s'\n", t1, t2); - } - if ((!t1) && (!nodes[i].error)) { - Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n), - "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n", - Swig_name_decl(nodes[i].n), SwigType_str(Getattr(p1, "type"), 0)); - nodes[i].error = 1; - } else if ((!t2) && (!nodes[j].error)) { - Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s not supported (incomplete type checking rule - no precedence level in typecheck typemap for '%s').\n", - Swig_name_decl(nodes[j].n), SwigType_str(Getattr(p2, "type"), 0)); - nodes[j].error = 1; - } - if (t1 && t2) { - int t1v, t2v; - t1v = atoi(Char(t1)); - t2v = atoi(Char(t2)); - differ = t1v-t2v; - } - else if (!t1 && t2) differ = 1; - else if (t1 && !t2) differ = -1; - else if (!t1 && !t2) differ = -1; - num_checked++; - if (differ > 0) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - break; - } else if ((differ == 0) && (Strcmp(t1,"0") == 0)) { - t1 = Getattr(p1,"ltype"); - if (!t1) { - t1 = SwigType_ltype(Getattr(p1,"type")); - if (Getattr(p1,"tmap:typecheck:SWIGTYPE")) { - SwigType_add_pointer(t1); - } - Setattr(p1,"ltype",t1); - } - t2 = Getattr(p2,"ltype"); - if (!t2) { - t2 = SwigType_ltype(Getattr(p2,"type")); - if (Getattr(p2,"tmap:typecheck:SWIGTYPE")) { - SwigType_add_pointer(t2); - } - Setattr(p2,"ltype",t2); - } - - /* Need subtype check here. If t2 is a subtype of t1, then we need to change the - order */ - - if (SwigType_issubtype(t2,t1)) { - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - - if (Strcmp(t1,t2) != 0) { - differ = 1; - break; - } - } else if (differ) { - break; - } - if (Getattr(p1,"tmap:in:next")) { - p1 = Getattr(p1,"tmap:in:next"); - } else { - p1 = nextSibling(p1); - } - if (Getattr(p2,"tmap:in:next")) { - p2 = Getattr(p2,"tmap:in:next"); - } else { - p2 = nextSibling(p2); - } - } - if (!differ) { - /* See if declarations differ by const only */ - String *d1 = Getattr(nodes[i].n, "decl"); - String *d2 = Getattr(nodes[j].n, "decl"); - if (d1 && d2) { - String *dq1 = Copy(d1); - String *dq2 = Copy(d2); - if (SwigType_isconst(d1)) { - Delete(SwigType_pop(dq1)); - } - if (SwigType_isconst(d2)) { - Delete(SwigType_pop(dq2)); - } - if (Strcmp(dq1, dq2) == 0) { - - if (SwigType_isconst(d1) && !SwigType_isconst(d2)) { - if (script_lang_wrapping) { - // Swap nodes so that the const method gets ignored (shadowed by the non-const method) - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } - differ = 1; - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), - "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - } - nodes[j].error = 1; - } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) { - differ = 1; - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), - "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - } - nodes[j].error = 1; - } - } - Delete(dq1); - Delete(dq2); - } - } - if (!differ) { - if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n), - "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) { - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), - "using %s instead.\n", Swig_name_decl(nodes[i].n)); - } - } - nodes[j].error = 1; - } - } - } - } - } - } - List *result = NewList(); - { - int i; - for (i = 0; i < nnodes; i++) { - if (nodes[i].error) - Setattr(nodes[i].n, "overload:ignore", "1"); - Append(result,nodes[i].n); - } - } - return result; -} - -void R::dispatchFunction(Node *n) { - Wrapper *f = NewWrapper(); - String *symname = Getattr(n, "sym:name"); - String *nodeType = Getattr(n, "nodeType"); - bool constructor = (!Cmp(nodeType, "constructor")); - - String *sfname = NewString(symname); - - if (constructor) - Replace(sfname, "new_", "", DOH_REPLACE_FIRST); - - Printf(f->def, - "`%s` <- function(...) {", sfname); - if (debugMode) { - Swig_print_node(n); - } - List *dispatch = Swig_overload_rank(n, true); - int nfunc = Len(dispatch); - Printv(f->code, - "argtypes <- mapply(class, list(...));\n", - "argv <- list(...);\n", - "argc <- length(argtypes);\n", - "f <- NULL;\n", NIL); - - Printf(f->code, "# dispatch functions %d\n", nfunc); - int cur_args = -1; - bool first_compare = true; - for (int i=0; i < nfunc; i++) { - Node *ni = Getitem(dispatch,i); - Parm *pi = Getattr(ni,"wrap:parms"); - int num_arguments = emit_num_arguments(pi); - - String *overname = Getattr(ni,"sym:overname"); - if (cur_args != num_arguments) { - if (cur_args != -1) { - Printv(f->code, "} else ", NIL); - } - Printf(f->code, "if (argc == %d) {", num_arguments); - cur_args = num_arguments; - first_compare = true; - } - Parm *p; - int j; - if (num_arguments > 0) { - if (!first_compare) { - Printv(f->code, " else ", NIL); - } else { - first_compare = false; - } - Printv(f->code, "if (", NIL); - for (p = pi, j = 0 ; j < num_arguments ; j++) { - if (debugMode) { - Swig_print_node(p); - } - String *tm = Swig_typemap_lookup("rtype", p, "", 0); - if (tm) { - replaceRClass(tm, Getattr(p, "type")); - } - - String *tmcheck = Swig_typemap_lookup("rtypecheck", p, "", 0); - if (tmcheck) { - String *tmp_argtype = NewStringf("argtypes[%d]", j+1); - Replaceall(tmcheck, "$argtype", tmp_argtype); - String *tmp_arg = NewStringf("argv[[%d]]", j+1); - Replaceall(tmcheck, "$arg", tmp_arg); - replaceRClass(tmcheck, Getattr(p, "type")); - if (debugMode) { - Printf(stdout, "<rtypecheck>%s\n", tmcheck); - } - if (num_arguments == 1) { - Printf(f->code, "%s", tmcheck); - } else { - Printf(f->code, "%s(%s)", j == 0 ? "" : " && ", tmcheck); - } - p = Getattr(p, "tmap:in:next"); - Delete(tmp_arg); - Delete(tmp_argtype); - continue; - } - // Below should be migrated into rtypecheck typemaps - // Preparation for this has started by warning in swig-4.1.1 for "numeric", "integer", "character" typemaps - // For swig-4.2: remove the code block below and uncomment typemaps marked 'Replacement rtypecheck typemaps' in rtype.swg. - // There is a slight difference in output as the typemap approach fixes some bugs due to a missing type resolution below - if (tm) { - String *tmcode = NULL; - Printf(f->code, "%s", j == 0 ? "" : " && "); - if (num_arguments != 1) - Printf(f->code, "("); - Printf(f->code, " "); - if (Strcmp(tm, "numeric") == 0) { - tmcode = NewString("is.numeric($arg)"); - } else if (Strcmp(tm, "integer") == 0) { - tmcode = NewString("(is.integer($arg) || is.numeric($arg))"); - } else if (Strcmp(tm, "character") == 0) { - tmcode = NewString("is.character($arg)"); - } else { - if (SwigType_ispointer(Getattr(p, "type"))) - Printf(f->code, "extends(argtypes[%d], '%s') || is.null(argv[[%d]])", j+1, tm, j+1); - else - Printf(f->code, "extends(argtypes[%d], '%s') && length(argv[[%d]]) == 1", j+1, tm, j+1); - } - if (tmcode) { - if (!SwigType_ispointer(Getattr(p, "type"))) - Printf(tmcode, " && length($arg) == 1"); - Swig_warning(WARN_R_MISSING_RTYPECHECK_TYPEMAP, input_file, line_number, - "Optional rtypecheck code is deprecated. Add the following typemap to fix as the next version of SWIG will not work without it: %%typemap(\"rtypecheck\") %s %%{ %s %%}\n", - SwigType_str(Getattr(p, "type"), 0), tmcode); - String *tmp_arg = NewStringf("argv[[%d]]", j+1); - Replaceall(tmcode, "$arg", tmp_arg); - Printv(f->code, tmcode, NIL); - Delete(tmp_arg); - } - Printf(f->code, " "); - if (num_arguments != 1) - Printf(f->code, ")"); - Delete(tmcode); - } - p = Getattr(p, "tmap:in:next"); - } - Printf(f->code, ") { f <- %s%s; }\n", sfname, overname); - } else { - Printf(f->code, "f <- %s%s; ", sfname, overname); - } - } - if (cur_args != -1) { - Printf(f->code, "};\n"); - } - Printf(f->code, "if (is.null(f)) {\n" - "stop(\"cannot find overloaded function for %s with argtypes (\"," - "toString(argtypes),\")\");\n" - "}", sfname); - Printv(f->code, ";\nf(...)", NIL); - Printv(f->code, ";\n}", NIL); - Wrapper_print(f, sfile); - Printv(sfile, "# Dispatch function\n", NIL); - DelWrapper(f); -} - -/*-------------------------------------------------------------- - -* --------------------------------------------------------------*/ - -int R::functionWrapper(Node *n) { - String *fname = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - String *type = Getattr(n, "type"); - - if (debugMode) { - Printf(stdout, - "<functionWrapper> %s %s %s\n", fname, iname, type); - } - String *overname = 0; - String *nodeType = Getattr(n, "nodeType"); - bool constructor = (!Cmp(nodeType, "constructor")); - bool destructor = (!Cmp(nodeType, "destructor")); - - String *sfname = NewString(iname); - - if (constructor) - Replace(sfname, "new_", "", DOH_REPLACE_FIRST); - - if (Getattr(n,"sym:overloaded")) { - overname = Getattr(n,"sym:overname"); - Append(sfname, overname); - } - - if (debugMode) - Printf(stdout, - "<functionWrapper> processing parameters\n"); - - - ParmList *l = Getattr(n, "parms"); - Parm *p; - String *tm; - - p = l; - while(p) { - SwigType *resultType = Getattr(p, "type"); - if (expandTypedef(resultType) && - SwigType_istypedef(resultType)) { - SwigType *resolved = - SwigType_typedef_resolve_all(resultType); - if (expandTypedef(resolved)) { - if (debugMode) { - Printf(stdout, "Setting type: %s\n", resolved); - } - Setattr(p, "type", Copy(resolved)); - } - } - p = nextSibling(p); - } - - String *unresolved_return_type = - Copy(type); - if (expandTypedef(type) && - SwigType_istypedef(type)) { - SwigType *resolved = - SwigType_typedef_resolve_all(type); - if (debugMode) - Printf(stdout, "<functionWrapper> resolved %s\n", Copy(unresolved_return_type)); - if (expandTypedef(resolved)) { - type = Copy(resolved); - Setattr(n, "type", type); - } - } - if (debugMode) - Printf(stdout, "<functionWrapper> unresolved_return_type %s\n", unresolved_return_type); - if(processing_member_access_function) { - if (debugMode) - Printf(stdout, "<functionWrapper memberAccess> '%s' '%s' '%s' '%s'\n", fname, iname, member_name, class_name); - - if(opaqueClassDeclaration) - return SWIG_OK; - - - /* Add the name of this member to a list for this class_name. - We will dump all these at the end. */ - - bool isSet = GetFlag(n, "memberset") ? true : false; - - String *tmp = NewString(isSet ? Swig_name_set(NSPACE_TODO, class_name) : Swig_name_get(NSPACE_TODO, class_name)); - - List *memList = Getattr(ClassMemberTable, tmp); - if(!memList) { - memList = NewList(); - Append(memList, class_name); - Setattr(ClassMemberTable, tmp, memList); - } - Delete(tmp); - Append(memList, member_name); - Append(memList, iname); - } - - int i; - int nargs; - - String *wname = Swig_name_wrapper(iname); - - if(overname) - Append(wname, overname); - Setattr(n,"wrap:name", wname); - - Wrapper *f = NewWrapper(); - Wrapper *sfun = NewWrapper(); - - int isVoidReturnType = (Strcmp(type, "void") == 0); - // Need to use the unresolved return type since - // typedef resolution removes the const which causes a - // mismatch with the function action - emit_return_variable(n, unresolved_return_type, f); - - SwigType *rtype = Getattr(n, "type"); - int addCopyParam = 0; - - if(!isVoidReturnType) - addCopyParam = addCopyParameter(rtype); - - if (debugMode) - Printf(stdout, "Adding a .copy argument to %s for %s = %s\n", - iname, type, addCopyParam ? "yes" : "no"); - - Printv(f->def, "SWIGEXPORT SEXP\n", wname, " ( ", NIL); - - Printf(sfun->def, "# Start of %s\n", iname); - Printv(sfun->def, "\n`", sfname, "` = function(", NIL); - - if(outputNamespaceInfo) {//XXX Need to be a little more discriminating - if (constructor) { - String *niname = Copy(iname); - Replace(niname, "new_", "", DOH_REPLACE_FIRST); - addNamespaceFunction(niname); - Delete(niname); - } else { - addNamespaceFunction(iname); - } - } - - Swig_typemap_attach_parms("scoercein", l, f); - Swig_typemap_attach_parms("scoerceout", l, f); - Swig_typemap_attach_parms("scheck", l, f); - - emit_parameter_variables(l, f); - emit_attach_parmmaps(l,f); - Setattr(n,"wrap:parms",l); - - nargs = emit_num_arguments(l); - - Wrapper_add_local(f, "r_nprotect", "unsigned int r_nprotect = 0"); - Wrapper_add_localv(f, "r_ans", "SEXP", "r_ans = R_NilValue", NIL); - Wrapper_add_localv(f, "r_vmax", "VMAXTYPE", "r_vmax = vmaxget()", NIL); - - String *sargs = NewString(""); - - - String *s_inputTypes = NewString(""); - String *s_inputMap = NewString(""); - bool inFirstArg = true; - bool inFirstType = true; - Parm *curP; - for (p =l, i = 0 ; i < nargs ; i++) { - - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *tt = Getattr(p, "type"); - int nargs = -1; - String *funcptr_name = processType(tt, p, &nargs); - - // SwigType *tp = Getattr(p, "type"); - String *name = Getattr(p,"name"); - String *lname = Getattr(p,"lname"); - - // R keyword renaming - if (name) { - if (Swig_name_warning(p, 0, name, 0)) { - name = 0; - } else { - /* If we have a :: in the parameter name because we are accessing a static member of a class, say, then - we need to remove that prefix. */ - while (Strstr(name, "::")) { - //XXX need to free. - name = NewStringf("%s", Strchr(name, ':') + 2); - if (debugMode) - Printf(stdout, "+++ parameter name with :: in it %s\n", name); - } - } - } - if (!name || Len(name) == 0) - name = NewStringf("s_arg%d", i+1); - - name = replaceInitialDash(name); - - if (!Strncmp(name, "arg", 3)) { - name = Copy(name); - Insert(name, 0, "s_"); - } - - if(processing_variable) { - name = Copy(name); - Insert(name, 0, "s_"); - } - - if(!Strcmp(name, fname)) { - name = Copy(name); - Insert(name, 0, "s_"); - } - - Printf(sargs, "%s, ", name); - - String *tm; - if((tm = Getattr(p, "tmap:scoercein"))) { - Replaceall(tm, "$input", name); - replaceRClass(tm, Getattr(p, "type")); - - if(funcptr_name) { - //XXX need to get this to return non-zero - if(nargs == -1) - nargs = getFunctionPointerNumArgs(p, tt); - - String *snargs = NewStringf("%d", nargs); - Printv(sfun->code, "if(is.function(", name, ")) {", "\n", - "assert('...' %in% names(formals(", name, - ")) || length(formals(", name, ")) >= ", snargs, ");\n} ", NIL); - Delete(snargs); - - Printv(sfun->code, "else {\n", - "if(is.character(", name, ")) {\n", - name, " = getNativeSymbolInfo(", name, ");", - "\n};\n", - "if(is(", name, ", \"NativeSymbolInfo\")) {\n", - name, " = ", name, "$address", ";\n};\n", - "if(is(", name, ", \"ExternalReference\")) {\n", - name, " = ", name, "@ref;\n}\n", - "}; \n", - NIL); - } else { - Printf(sfun->code, "%s\n", tm); - } - } - - Printv(sfun->def, inFirstArg ? "" : ", ", name, NIL); - - if ((tm = Getattr(p,"tmap:scheck"))) { - - Replaceall(tm,"$input", name); - replaceRClass(tm, Getattr(p, "type")); - Printf(sfun->code,"%s\n",tm); - } - - - - curP = p; - if ((tm = Getattr(p,"tmap:in"))) { - - Replaceall(tm,"$input", name); - - if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) { - Replaceall(tm,"$disown","SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm,"$disown","0"); - } - - if(funcptr_name) { - /* have us a function pointer */ - Printf(f->code, "if(TYPEOF(%s) != CLOSXP) {\n", name); - Replaceall(tm,"$R_class", ""); - } else { - replaceRClass(tm, Getattr(p, "type")); - } - - - Printf(f->code,"%s\n",tm); - if(funcptr_name) - Printf(f->code, "} else {\n%s = %s;\nR_SWIG_pushCallbackFunctionData(%s, NULL);\n}\n", - lname, funcptr_name, name); - Printv(f->def, inFirstArg ? "" : ", ", "SEXP ", name, NIL); - if (Len(name) != 0) - inFirstArg = false; - p = Getattr(p,"tmap:in:next"); - - } else { - p = nextSibling(p); - } - - - tm = Swig_typemap_lookup("rtype", curP, "", 0); - if(tm) { - replaceRClass(tm, Getattr(curP, "type")); - } - Printf(s_inputTypes, "%s'%s'", inFirstType ? "" : ", ", tm); - Printf(s_inputMap, "%s%s='%s'", inFirstType ? "" : ", ", name, tm); - inFirstType = false; - - if(funcptr_name) - Delete(funcptr_name); - } /* end of looping over parameters. */ - - if(addCopyParam) { - Printf(sfun->def, "%s.copy = FALSE", nargs > 0 ? ", " : ""); - Printf(f->def, "%sSEXP s_swig_copy", nargs > 0 ? ", " : ""); - - Printf(sargs, "as.logical(.copy), "); - } - - Printv(f->def, ")\n{\n", NIL); - // SWIG_fail in R leads to a call to Rf_error() which calls longjmp() - // which means the destructors of any live function-local C++ objects won't - // get run. To avoid this happening, we wrap almost everything in the - // function in a block, and end that right before Rf_error() at which - // point those destructors will get called. - if (CPlusPlus) Append(f->def, "{\n"); - - Printv(sfun->def, ")\n{\n", NIL); - - - /* Insert cleanup code */ - String *cleanup = NewString(""); - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:freearg"))) { - if (tm && (Len(tm) != 0)) { - Printv(cleanup, tm, "\n", NIL); - } - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - String *outargs = NewString(""); - int numOutArgs = isVoidReturnType ? -1 : 0; - for(p = l, i = 0; p; i++) { - if((tm = Getattr(p, "tmap:argout"))) { - // String *lname = Getattr(p, "lname"); - numOutArgs++; - String *pos = NewStringf("%d", numOutArgs); - Replaceall(tm,"$result", "r_ans"); - Replaceall(tm,"$n", pos); // The position into which to store the answer. - Replaceall(tm,"$arg", Getattr(p, "emit:input")); - Replaceall(tm,"$input", Getattr(p, "emit:input")); - Replaceall(tm,"$owner", "0"); - - - Printf(outargs, "%s\n", tm); - p = Getattr(p,"tmap:argout:next"); - } else - p = nextSibling(p); - } - - String *actioncode = emit_action(n); - - /* Deal with the explicit return value. */ - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { - SwigType *retType = Getattr(n, "type"); - - Replaceall(tm,"$1", Swig_cresult_name()); - Replaceall(tm,"$result", "r_ans"); - if (debugMode){ - Printf(stdout, "Calling replace D: %s, %s, %s\n", retType, n, tm); - } - replaceRClass(tm, retType); - - if (GetFlag(n,"feature:new")) { - Replaceall(tm, "$owner", "SWIG_POINTER_OWN"); - } else { - Replaceall(tm,"$owner", "0"); - } - - Printf(f->code, "%s\n", tm); - - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, - "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), fname); - } - - - if(Len(outargs)) { - Wrapper_add_local(f, "R_OutputValues", "SEXP R_OutputValues"); - - String *tmp = NewString(""); - if(!isVoidReturnType) - Printf(tmp, "Rf_protect(r_ans);\n"); - - Printf(tmp, "Rf_protect(R_OutputValues = Rf_allocVector(VECSXP,%d));\nr_nprotect += %d;\n", - numOutArgs + !isVoidReturnType, - isVoidReturnType ? 1 : 2); - - if(!isVoidReturnType) - Printf(tmp, "SET_VECTOR_ELT(R_OutputValues, 0, r_ans);\n"); - Printf(tmp, "r_ans = R_OutputValues;\n"); - - Insert(outargs, 0, tmp); - Delete(tmp); - - - - Printv(f->code, outargs, NIL); - Delete(outargs); - - } - - /* Output cleanup code */ - int need_cleanup = Len(cleanup) != 0; - if (need_cleanup) { - Printv(f->code, cleanup, NIL); - } - - /* Look to see if there is any newfree cleanup code */ - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - } - } - - /* See if there is any return cleanup code */ - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - Delete(tm); - } - - Printv(f->code, UnProtectWrapupCode, NIL); - - /*If the user gave us something to convert the result in */ - if ((tm = Swig_typemap_lookup("scoerceout", n, Swig_cresult_name(), sfun))) { - Replaceall(tm,"$result","ans"); - if (debugMode) { - Printf(stdout, "Calling replace B: %s, %s, %s\n", Getattr(n, "type"), Getattr(n, "sym:name"), getNSpace()); - } - replaceRClass(tm, Getattr(n, "type")); - Chop(tm); - } - - - Printv(sfun->code, ";", (Len(tm) ? "ans = " : ""), ".Call('", wname, - "', ", sargs, "PACKAGE='", Rpackage, "');\n", NIL); - if(Len(tm)) - { - Printf(sfun->code, "%s\n\n", tm); - if (constructor) - { - String *finalizer = NewString(iname); - Replace(finalizer, "new_", "", DOH_REPLACE_FIRST); - Printf(sfun->code, "reg.finalizer(ans@ref, delete_%s);\n", finalizer); - } - Printf(sfun->code, "ans\n"); - } - - if (destructor) - Printv(f->code, "R_ClearExternalPtr(self);\n", NIL); - - Printv(f->code, "return r_ans;\n", NIL); - - /* Error handling code */ - Printv(f->code, "fail: SWIGUNUSED;\n", NIL); - if (need_cleanup) { - Printv(f->code, cleanup, NIL); - } - if (CPlusPlus) Append(f->code, "}\n"); - Printv(f->code, " Rf_error(\"%s %s\", SWIG_ErrorType(SWIG_lasterror_code), SWIG_lasterror_msg);\n", NIL); - Printv(f->code, " return R_NilValue;\n", NIL); - Delete(cleanup); - - Printv(f->code, "}\n", NIL); - Printv(sfun->code, "\n}", NIL); - - /* Substitute the function name */ - Replaceall(f->code,"$symname",iname); - - Wrapper_print(f, f_wrapper); - Wrapper_print(sfun, sfile); - - Printf(sfun->code, "\n# End of %s\n", iname); - tm = Swig_typemap_lookup("rtype", n, "", 0); - if(tm) { - SwigType *retType = Getattr(n, "type"); - if (debugMode) { - Printf(stdout, "Calling replace C: %s\n", Copy(retType)); - } - replaceRClass(tm, retType); - } - - Printv(sfile, "attr(`", sfname, "`, 'returnType') = '", - isVoidReturnType ? "void" : (tm ? tm : ""), - "'\n", NIL); - - if(nargs > 0) - Printv(sfile, "attr(`", sfname, "`, \"inputTypes\") = c(", - s_inputTypes, ")\n", NIL); - Printv(sfile, "class(`", sfname, "`) = c(\"SWIGFunction\", class('", - sfname, "'))\n\n", NIL); - - if (memoryProfile) { - Printv(sfile, "memory.profile()\n", NIL); - } - if (aggressiveGc) { - Printv(sfile, "gc()\n", NIL); - } - - // Printv(sfile, "setMethod('", name, "', '", name, "', ", iname, ")\n\n\n"); - - - - /* If we are dealing with a method in an C++ class, then - add the name of the R function and its definition. - XXX need to figure out how to store the Wrapper if possible in the hash/list. - Would like to be able to do this so that we can potentially insert - */ - if(processing_member_access_function || processing_class_member_function) { - String *method_type = R_MEMBER_NORMAL; - if (GetFlag(n, "memberset")) { - method_type = R_MEMBER_SET; - } else if (GetFlag(n, "memberget")) { - method_type = R_MEMBER_GET; - } - addAccessor(member_name, sfun, iname, method_type); - } - - if (Getattr(n, "sym:overloaded") && - !Getattr(n, "sym:nextSibling")) { - dispatchFunction(n); - } - - addRegistrationRoutine(wname, addCopyParam ? nargs +1 : nargs); - - DelWrapper(f); - DelWrapper(sfun); - - Delete(sargs); - Delete(sfname); - return SWIG_OK; -} - -/* ---------------------------------------------------------------------- - * R::constantWrapper() - * ---------------------------------------------------------------------- */ - -int R::constantWrapper(Node *n) { - (void) n; - // TODO - return SWIG_OK; -} - -/*-------------------------------------------------------------- - * Add the specified routine name to the collection of - * generated routines that are called from R functions. - * This is used to register the routines with R for - * resolving symbols. - - * rname - the name of the routine - * nargs - the number of arguments it expects. - * --------------------------------------------------------------*/ - -int R::addRegistrationRoutine(String *rname, int nargs) { - if(!registrationTable) - registrationTable = NewHash(); - - String *el = - NewStringf("{\"%s\", (DL_FUNC) &%s, %d}", rname, rname, nargs); - - Setattr(registrationTable, rname, el); - - return SWIG_OK; -} - -/* ------------------------------------------------------------- - * Write the registration information to an array and - * create the initialization routine for registering - * these. - * --------------------------------------------------------------*/ - -int R::outputRegistrationRoutines(File *out) { - int i, n; - if(!registrationTable) - return(0); - if(inCPlusMode) - Printf(out, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"); - - Printf(out, "#include <R_ext/Rdynload.h>\n\n"); - if(inCPlusMode) - Printf(out, "#ifdef __cplusplus\n}\n#endif\n\n"); - - Printf(out, "SWIGINTERN R_CallMethodDef CallEntries[] = {\n"); - - List *keys = Keys(registrationTable); - n = Len(keys); - for(i = 0; i < n; i++) - Printf(out, " %s,\n", Getattr(registrationTable, Getitem(keys, i))); - - Printf(out, " {NULL, NULL, 0}\n};\n\n"); - - if(!noInitializationCode) { - if (inCPlusMode) - Printv(out, "extern \"C\" ", NIL); - { /* R allows pckage names to have '.' in the name, which is not allowed in C++ var names - we simply replace all occurrences of '.' with '_' to construct the var name */ - String * Rpackage_sane = Copy(Rpackage); - Replace(Rpackage_sane, ".", "_", DOH_REPLACE_ANY); - Printf(out, "SWIGEXPORT void R_init_%s(DllInfo *dll) {\n", Rpackage_sane); - Delete(Rpackage_sane); - } - Printf(out, "%sR_registerRoutines(dll, NULL, CallEntries, NULL, NULL);\n", tab4); - if(Len(s_init_routine)) { - Printf(out, "\n%s\n", s_init_routine); - } - Printf(out, "}\n"); - } - - return n; -} - - - -/* ------------------------------------------------------------- - * Process a struct, union or class declaration in the source code, - * or an anonymous typedef struct - * --------------------------------------------------------------*/ - -//XXX What do we need to do here - -// Define an S4 class to refer to this. - -void R::registerClass(Node *n) { - String *name = Getattr(n, "name"); - - if (debugMode) - Swig_print_node(n); - String *sname = NewStringf("_p%s", SwigType_manglestr(name)); - if(!Getattr(SClassDefs, sname)) { - Setattr(SClassDefs, sname, sname); - String *base; - - if (CPlusPlus && (Strcmp(nodeType(n), "class") == 0)) { - base = NewString(""); - List *l = Getattr(n, "bases"); - if(Len(l)) { - Printf(base, "c("); - for(int i = 0; i < Len(l); i++) { - registerClass(Getitem(l, i)); - Printf(base, "'_p%s'%s", - SwigType_manglestr(Getattr(Getitem(l, i), "name")), - i < Len(l)-1 ? ", " : ""); - } - Printf(base, ")"); - } else { - base = NewString("'C++Reference'"); - } - } else - base = NewString("'ExternalReference'"); - - Printf(s_classes, "setClass('%s', contains = %s)\n", sname, base); - Delete(base); - } -} - -int R::classDeclaration(Node *n) { - - String *name = Getattr(n, "name"); - String *kind = Getattr(n, "kind"); - - if (debugMode) - Swig_print_node(n); - registerClass(n); - - - /* If we have a typedef union { ... } U, then we never get to see the typedef - via a regular call to typedefHandler. Instead, */ - if(Getattr(n, "unnamed") && Getattr(n, "storage") && Strcmp(Getattr(n, "storage"), "typedef") == 0 - && Getattr(n, "tdname") && Strcmp(Getattr(n, "tdname"), name) == 0) { - if (debugMode) - Printf(stdout, "Typedef in the class declaration for %s\n", name); - // typedefHandler(n); - } - - bool opaque = GetFlag(n, "feature:opaque") ? true : false; - - if(opaque) - opaqueClassDeclaration = name; - - int status = Language::classDeclaration(n); - - opaqueClassDeclaration = NULL; - - - if (class_member_function_types) { - - // collect the "set" methods - List *class_set_membernames = filterMemberList(class_member_function_types, - class_member_function_membernames, R_MEMBER_SET, true); - List *class_set_functionnames = filterMemberList(class_member_function_types, - class_member_function_names, R_MEMBER_SET, true); - // this one isn't used - collecting to keep code simpler - List *class_set_functiontypes = filterMemberList(class_member_function_types, - class_member_function_types, R_MEMBER_SET, true); - - // collect the others - List *class_other_membernames = filterMemberList(class_member_function_types, - class_member_function_membernames, R_MEMBER_SET, false); - List *class_other_functionnames = filterMemberList(class_member_function_types, - class_member_function_names, R_MEMBER_SET, false); - List *class_other_functiontypes = filterMemberList(class_member_function_types, - class_member_function_types, R_MEMBER_SET, false); - - if (Len(class_other_membernames) > 0) { - OutputMemberReferenceMethod(name, 0, class_other_membernames, class_other_functionnames, class_other_functiontypes, sfile); - } - if (Len(class_set_membernames) > 0) { - OutputMemberReferenceMethod(name, 1, class_set_membernames, class_set_functionnames, class_set_functiontypes, sfile); - } - Delete(class_set_membernames); - Delete(class_set_functionnames); - Delete(class_set_functiontypes); - Delete(class_other_membernames); - Delete(class_other_functionnames); - Delete(class_other_functiontypes); - } - - if (class_member_function_types) { - Delete(class_member_function_types); - class_member_function_types = NULL; - Delete(class_member_function_names); - class_member_function_names = NULL; - Delete(class_member_function_membernames); - class_member_function_membernames = NULL; - Delete(class_member_function_wrappernames); - class_member_function_wrappernames = NULL; - } - if (Getattr(n, "has_destructor")) { - Printf(sfile, "setMethod('delete', '_p%s', function(obj) {delete%s(obj)})\n", getRClassName(name), getRClassName(name)); - - } - if(!opaque && !Strcmp(kind, "struct") && copyStruct) { - - String *def = - NewStringf("setClass(\"%s\",\n%srepresentation(\n", name, tab4); - bool firstItem = true; - - for(Node *c = firstChild(n); c; ) { - String *elName; - String *tp; - - elName = Getattr(c, "name"); - - String *elKind = Getattr(c, "kind"); - if (!Equal(elKind, "variable")) { - c = nextSibling(c); - continue; - } - if (!Len(elName)) { - c = nextSibling(c); - continue; - } - tp = Swig_typemap_lookup("rtype", c, "", 0); - if(!tp) { - c = nextSibling(c); - continue; - } - if (Strstr(tp, "R_class")) { - c = nextSibling(c); - continue; - } - if (Strcmp(tp, "character") && - Strstr(Getattr(c, "decl"), "p.")) { - c = nextSibling(c); - continue; - } - - if (!firstItem) { - Printf(def, ",\n"); - } - // else - //XXX How can we tell if this is already done. - // SwigType_push(elType, elDecl); - - - // returns "" tp = processType(elType, c, NULL); - // Printf(stdout, "<classDeclaration> elType %p\n", elType); - // tp = getRClassNameCopyStruct(Getattr(c, "type"), 1); - - String *elNameT = replaceInitialDash(elName); - Printf(def, "%s%s = \"%s\"", tab8, elNameT, tp); - firstItem = false; - Delete(tp); - Delete(elNameT); - c = nextSibling(c); - } - Printf(def, "),\n%scontains = \"RSWIGStruct\")\n", tab8); - Printf(s_classes, "%s\n\n# End class %s\n\n", def, name); - - generateCopyRoutines(n); - - Delete(def); - } - - return status; -} - - - -/* ------------------------------------------------------------- - * Create the C routines that copy an S object of the class given - * by the given struct definition in Node *n to the C value - * and also the routine that goes from the C routine to an object - * of this S class. - * --------------------------------------------------------------*/ - -/*XXX - Clean up the toCRef - make certain the names are correct for the types, etc. - in all cases. -*/ - -int R::generateCopyRoutines(Node *n) { - Wrapper *copyToR = NewWrapper(); - Wrapper *copyToC = NewWrapper(); - - String *name = Getattr(n, "name"); - String *tdname = Getattr(n, "tdname"); - String *kind = Getattr(n, "kind"); - String *type; - - if(Len(tdname)) { - type = Copy(tdname); - } else { - type = NewStringf("%s %s", kind, name); - } - - String *mangledName = SwigType_manglestr(name); - - if (debugMode) - Printf(stdout, "generateCopyRoutines: name = %s, %s\n", name, type); - - Printf(copyToR->def, "CopyToR%s = function(value, obj = new(\"%s\"))\n{\n", - mangledName, name); - Printf(copyToC->def, "CopyToC%s = function(value, obj)\n{\n", - mangledName); - - Node *c = firstChild(n); - - for(; c; c = nextSibling(c)) { - String *elName = Getattr(c, "name"); - if (!Len(elName)) { - continue; - } - String *elKind = Getattr(c, "kind"); - if (!Equal(elKind, "variable")) { - continue; - } - - String *tp = Swig_typemap_lookup("rtype", c, "", 0); - if(!tp) { - continue; - } - if (Strstr(tp, "R_class")) { - continue; - } - if (Strcmp(tp, "character") && - Strstr(Getattr(c, "decl"), "p.")) { - continue; - } - - - /* The S functions to get and set the member value. */ - String *elNameT = replaceInitialDash(elName); - Printf(copyToR->code, "obj@%s = value$%s;\n", elNameT, elNameT); - Printf(copyToC->code, "obj$%s = value@%s;\n", elNameT, elNameT); - Delete(elNameT); - } - Printf(copyToR->code, "obj;\n}\n\n"); - String *rclassName = getRClassNameCopyStruct(type, 0); // without the Ref. - Printf(sfile, "# Start definition of copy functions & methods for %s\n", rclassName); - - Wrapper_print(copyToR, sfile); - Printf(copyToC->code, "obj\n}\n\n"); - Wrapper_print(copyToC, sfile); - - - Printf(sfile, "# Start definition of copy methods for %s\n", rclassName); - Printf(sfile, "setMethod('copyToR', '_p%s', CopyToR%s);\n", mangledName, - mangledName); - Printf(sfile, "setMethod('copyToC', '%s', CopyToC%s);\n\n", rclassName, - mangledName); - - Printf(sfile, "# End definition of copy methods for %s\n", rclassName); - Printf(sfile, "# End definition of copy functions & methods for %s\n", rclassName); - - String *m = NewStringf("%sCopyToR", name); - addNamespaceMethod(m); - char *tt = Char(m); tt[Len(m)-1] = 'C'; - addNamespaceMethod(m); - Delete(m); - Delete(rclassName); - Delete(mangledName); - DelWrapper(copyToR); - DelWrapper(copyToC); - - return SWIG_OK; -} - - - -/* ------------------------------------------------------------- - * Called when there is a typedef to be invoked. - * - * XXX Needs to be enhanced or split to handle the case where we have a - * typedef within a classDeclaration emission because the struct/union/etc. - * is anonymous. - * --------------------------------------------------------------*/ - -int R::typedefHandler(Node *n) { - SwigType *tp = Getattr(n, "type"); - String *type = Getattr(n, "type"); - if (debugMode) - Printf(stdout, "<typedefHandler> %s\n", Getattr(n, "name")); - - processType(tp, n); - - if(Strncmp(type, "struct ", 7) == 0) { - String *name = Getattr(n, "name"); - char *trueName = Char(type); - trueName += 7; - if (debugMode) - Printf(stdout, "<typedefHandler> Defining S class %s\n", trueName); - Printf(s_classes, "setClass('_p%s', contains = 'ExternalReference')\n", - SwigType_manglestr(name)); - } - - return Language::typedefHandler(n); -} - - - -/* -------------------------------------------------------------- - * Called when processing a field in a "class", i.e. struct, union or - * actual class. We set a state variable so that we can correctly - * interpret the resulting functionWrapper() call and understand that - * it is for a field element. - * --------------------------------------------------------------*/ - -int R::membervariableHandler(Node *n) { - SwigType *t = Getattr(n, "type"); - processType(t, n, NULL); - processing_member_access_function = 1; - member_name = Getattr(n,"sym:name"); - if (debugMode) - Printf(stdout, "<membervariableHandler> name = %s, sym:name = %s\n", - Getattr(n, "name"), member_name); - - int status(Language::membervariableHandler(n)); - - if(!opaqueClassDeclaration && debugMode) - Printf(stdout, "<membervariableHandler> %s %s\n", Getattr(n, "name"), Getattr(n, "type")); - - processing_member_access_function = 0; - member_name = NULL; - - return status; -} - - -/* - This doesn't seem to get used so leave it out for the moment. -*/ -String * R::runtimeCode() { - String *s = Swig_include_sys("rrun.swg"); - if (!s) { - Printf(stdout, "*** Unable to open 'rrun.swg'\n"); - s = NewString(""); - } - return s; -} - -/*---------------------------------------------------------------------- - * replaceSpecialVariables() - *--------------------------------------------------------------------*/ - -void R::replaceSpecialVariables(String *method, String *tm, Parm *parm) { - (void)method; - SwigType *type = Getattr(parm, "type"); - replaceRClass(tm, type); -} - - -/* ----------------------------------------------------------------------- - * Called when SWIG wants to initialize this - * We initialize anythin we want here. - * Most importantly, tell SWIG where to find the files (e.g. r.swg) for this module. - * Use Swig_mark_arg() to tell SWIG that it is understood and not to - * throw an error. - * --------------------------------------------------------------*/ - -void R::main(int argc, char *argv[]) { - init(); - Preprocessor_define("SWIGR 1", 0); - SWIG_library_directory("r"); - SWIG_config_file("r.swg"); - debugMode = false; - copyStruct = true; - memoryProfile = false; - aggressiveGc = false; - inCPlusMode = false; - outputNamespaceInfo = false; - noInitializationCode = false; - - this->Argc = argc; - this->Argv = argv; - - allow_overloading();// can we support this? - - for(int i = 0; i < argc; i++) { - if(strcmp(argv[i], "-package") == 0) { - Swig_mark_arg(i); - i++; - Swig_mark_arg(i); - Rpackage = argv[i]; - } else if(strcmp(argv[i], "-dll") == 0) { - Swig_mark_arg(i); - i++; - Swig_mark_arg(i); - DllName = argv[i]; - } else if(strcmp(argv[i], "-help") == 0) { - showUsage(); - } else if(strcmp(argv[i], "-namespace") == 0) { - outputNamespaceInfo = true; - Swig_mark_arg(i); - } else if(!strcmp(argv[i], "-no-init-code")) { - noInitializationCode = true; - Swig_mark_arg(i); - } else if(!strcmp(argv[i], "-c++")) { - inCPlusMode = true; - Swig_mark_arg(i); - Printf(s_classes, "setClass('C++Reference', contains = 'ExternalReference')\n"); - } else if(!strcmp(argv[i], "-debug")) { - debugMode = true; - Swig_mark_arg(i); - } else if (!strcmp(argv[i],"-copystruct")) { - copyStruct = true; - Swig_mark_arg(i); - } else if (!strcmp(argv[i], "-nocopystruct")) { - copyStruct = false; - Swig_mark_arg(i); - } else if (!strcmp(argv[i], "-memoryprof")) { - memoryProfile = true; - Swig_mark_arg(i); - } else if (!strcmp(argv[i], "-nomemoryprof")) { - memoryProfile = false; - Swig_mark_arg(i); - } else if (!strcmp(argv[i], "-aggressivegc")) { - aggressiveGc = true; - Swig_mark_arg(i); - } else if (!strcmp(argv[i], "-noaggressivegc")) { - aggressiveGc = false; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-cppcast") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nocppcast") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); - Swig_mark_arg(i); - Exit(EXIT_FAILURE); - } - - if (debugMode) { - Swig_typemap_search_debug_set(); - Swig_typemap_used_debug_set(); - Swig_typemap_register_debug_set(); - Swig_file_debug_set(); - } - /// copyToR copyToC functions. - - } -} - -/* ----------------------------------------------------------------------- - * Could make this work for String or File and then just store the resulting string - * rather than the collection of arguments and argc. - * ----------------------------------------------------------------------- */ -int R::outputCommandLineArguments(File *out) -{ - if(Argc < 1 || !Argv || !Argv[0]) - return(-1); - - Printf(out, "\n## Generated via the command line invocation:\n##\t"); - for(int i = 0; i < Argc ; i++) { - Printf(out, " %s", Argv[i]); - } - Printf(out, "\n\n\n"); - - return Argc; -} - - - -/* How SWIG instantiates an object from this module. - See swigmain.cxx */ -extern "C" -Language *swig_r(void) { - return new R(); -} - - - - -/* ----------------------------------------------------------------------- - * Needs to be reworked. - *----------------------------------------------------------------------- */ -String * R::processType(SwigType *t, Node *n, int *nargs) { - //XXX Need to handle typedefs, e.g. - // a type which is a typedef to a function pointer. - - SwigType *tmp = Getattr(n, "tdname"); - if (debugMode) - Printf(stdout, "processType %s (tdname = %s)(SwigType = %s)\n", Getattr(n, "name"), tmp, Copy(t)); - - SwigType *td = t; - if (expandTypedef(t) && - SwigType_istypedef(t)) { - SwigType *resolved = - SwigType_typedef_resolve_all(t); - if (expandTypedef(resolved)) { - td = Copy(resolved); - } - } - - if(!td) { - int count = 0; - String *b = getRTypeName(t, &count); - if(count && b && !Getattr(SClassDefs, b)) { - if (debugMode) - Printf(stdout, "<processType> Defining class %s\n", b); - - Printf(s_classes, "setClass('%s', contains = 'ExternalReference')\n", b); - Setattr(SClassDefs, b, b); - } - - } - - - if(td) - t = td; - - if(SwigType_isfunctionpointer(t)) { - if (debugMode) - Printf(stdout, - "<processType> Defining pointer handler %s\n", t); - - String *tmp = createFunctionPointerHandler(t, n, nargs); - return tmp; - } - - return NULL; -} - - -/* ----------------------------------------------------------------------- - * enumValue() - * This method will return a string with an enum value to use in from R when - * setting up an enum variable - * ------------------------------------------------------------------------ */ - -String *R::enumValue(Node *n) { - String *symname = Getattr(n, "sym:name"); - String *value = Getattr(n, "value"); - String *newsymname = 0; - - Node *parent = parentNode(n); - symname = Getattr(n, "sym:name"); - - // parent enumtype has namespace mangled in - String *etype = Getattr(parent, "enumtype"); - // we have to directly call the c wrapper function, as the - // R wrapper to the enum is designed to be used after the enum - // structures have been created on the R side. This means - // that we'll need to construct a .Call expression - - // change the type for variableWrapper - if (debugMode) { - Printf(stdout, "<enumValue> type set: %s\n", etype); - } - - Setattr(n, "type", etype); - - if (!getCurrentClass()) { - newsymname = Swig_name_member(0, Getattr(parent, "sym:name"), symname); - // Strange hack to change the name - Setattr(n, "name", Getattr(n, "value")); - Setattr(n, "sym:name", newsymname); - variableWrapper(n); - value = Swig_name_get(NSPACE_TODO, newsymname); - } else { - String *enumClassPrefix = getEnumClassPrefix(); - newsymname = Swig_name_member(0, enumClassPrefix, symname); - Setattr(n, "name", Getattr(n, "value")); - Setattr(n, "sym:name", newsymname); - variableWrapper(n); - value = Swig_name_get(NSPACE_TODO, newsymname); - } - value = Swig_name_wrapper(value); - Replace(value, "_wrap", "R_swig", DOH_REPLACE_FIRST); - - String *valuecall=NewString(""); - Printv(valuecall, ".Call('", value, "',FALSE, PACKAGE='", Rpackage, "')", NIL); - Delete(value); - return valuecall; -} diff --git a/contrib/tools/swig/Source/Modules/ruby.cxx b/contrib/tools/swig/Source/Modules/ruby.cxx deleted file mode 100644 index 0208435f039..00000000000 --- a/contrib/tools/swig/Source/Modules/ruby.cxx +++ /dev/null @@ -1,3470 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * ruby.cxx - * - * Ruby language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" -#include <ctype.h> -#include <string.h> -#include <limits.h> /* for INT_MAX */ - -#define SWIG_PROTECTED_TARGET_METHODS 1 - -class RClass { -private: - String *temp; - -public: - String *name; /* class name (renamed) */ - String *cname; /* original C class/struct name */ - String *mname; /* Mangled name */ - - /** - * The C variable name used in the SWIG-generated wrapper code to refer to - * this class; usually it is of the form "SwigClassXXX.klass", where SwigClassXXX - * is a swig_class struct instance and klass is a member of that struct. - */ - String *vname; - - /** - * The C variable name used in the SWIG-generated wrapper code to refer to - * the module that implements this class's methods (when we're trying to - * support C++ multiple inheritance). Usually it is of the form - * "SwigClassClassName.mImpl", where SwigClassXXX is a swig_class struct instance - * and mImpl is a member of that struct. - */ - String *mImpl; - - String *type; - String *prefix; - String *init; - - - int constructor_defined; - int destructor_defined; - - RClass() { - temp = NewString(""); - name = NewString(""); - cname = NewString(""); - mname = NewString(""); - vname = NewString(""); - mImpl = NewString(""); - type = NewString(""); - prefix = NewString(""); - init = NewString(""); - constructor_defined = 0; - destructor_defined = 0; - } - - ~RClass() { - Delete(name); - Delete(cname); - Delete(vname); - Delete(mImpl); - Delete(mname); - Delete(type); - Delete(prefix); - Delete(init); - Delete(temp); - } - - void set_name(const_String_or_char_ptr cn, const_String_or_char_ptr rn, const_String_or_char_ptr valn) { - /* Original C/C++ class (or struct) name */ - Clear(cname); - Append(cname, cn); - - /* Mangled name */ - Delete(mname); - mname = Swig_name_mangle(cname); - - /* Renamed class name */ - Clear(name); - Append(name, valn); - - /* Variable name for the VALUE that refers to the Ruby Class object */ - Clear(vname); - Printf(vname, "SwigClass%s.klass", name); - - /* Variable name for the VALUE that refers to the Ruby Class object */ - Clear(mImpl); - Printf(mImpl, "SwigClass%s.mImpl", name); - - /* Prefix */ - Clear(prefix); - Printv(prefix, (rn ? rn : cn), "_", NIL); - } - - char *strip(const_String_or_char_ptr s) { - Clear(temp); - if (Strncmp(s, prefix, Len(prefix)) == 0) { - Append(temp, Char(s) + Len(prefix)); - } else { - Append(temp, s); - } - return Char(temp); - } -}; - - -/* flags for the make_autodoc function */ -namespace { -enum autodoc_t { - AUTODOC_CLASS, - AUTODOC_CTOR, - AUTODOC_DTOR, - AUTODOC_STATICFUNC, - AUTODOC_FUNC, - AUTODOC_METHOD, - AUTODOC_GETTER, - AUTODOC_SETTER, - AUTODOC_NONE -}; -} - -static const char *usage = "\ -Ruby Options (available with -ruby)\n\ - -autorename - Enable renaming of classes and methods to follow Ruby coding standards\n\ - -globalmodule - Wrap everything into the global module\n\ - -initname <name>- Set entry function to Init_<name> (used by `require')\n\ - -minherit - Attempt to support multiple inheritance\n\ - -noautorename - Disable renaming of classes and methods (default)\n\ - -prefix <name> - Set a prefix <name> to be prepended to all names\n\ -"; - - -#define RCLASS(hash, name) (RClass*)(Getattr(hash, name) ? Data(Getattr(hash, name)) : 0) -#define SET_RCLASS(hash, name, klass) Setattr(hash, name, NewVoid(klass, 0)) - - -class RUBY:public Language { -private: - - String *module; - String *modvar; - String *feature; - String *prefix; - int current; - Hash *classes; /* key=cname val=RClass */ - RClass *klass; /* Currently processing class */ - Hash *special_methods; /* Python style special method name table */ - - File *f_directors; - File *f_directors_h; - File *f_directors_helpers; - File *f_begin; - File *f_runtime; - File *f_runtime_h; - File *f_header; - File *f_wrappers; - File *f_init; - File *f_initbeforefunc; - - bool useGlobalModule; - bool multipleInheritance; - - // Wrap modes - enum WrapperMode { - NO_CPP, - MEMBER_FUNC, - CONSTRUCTOR_ALLOCATE, - CONSTRUCTOR_INITIALIZE, - DESTRUCTOR, - MEMBER_VAR, - CLASS_CONST, - STATIC_FUNC, - STATIC_VAR - }; - - /* ------------------------------------------------------------ - * autodoc level declarations - * ------------------------------------------------------------ */ - - enum autodoc_l { - NO_AUTODOC = -2, // no autodoc - STRING_AUTODOC = -1, // use provided string - NAMES_AUTODOC = 0, // only parameter names - TYPES_AUTODOC = 1, // parameter names and types - EXTEND_AUTODOC = 2, // extended documentation and parameter names - EXTEND_TYPES_AUTODOC = 3 // extended documentation and parameter types + names - }; - - autodoc_t last_mode; - String* last_autodoc; - - autodoc_l autodoc_level(String *autodoc) { - autodoc_l dlevel = NO_AUTODOC; - char *c = Char(autodoc); - if (c) { - if (isdigit(c[0])) { - dlevel = (autodoc_l) atoi(c); - } else { - if (strcmp(c, "extended") == 0) { - dlevel = EXTEND_AUTODOC; - } else { - dlevel = STRING_AUTODOC; - } - } - } - return dlevel; - } - - - - /* ------------------------------------------------------------ - * have_docstring() - * Check if there is a docstring directive and it has text, - * or there is an autodoc flag set - * ------------------------------------------------------------ */ - - bool have_docstring(Node *n) { - String *str = Getattr(n, "feature:docstring"); - return (str && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")); - } - - /* ------------------------------------------------------------ - * docstring() - * Get the docstring text, stripping off {} if necessary, - * and enclose in triple double quotes. If autodoc is also - * set then it will build a combined docstring. - * ------------------------------------------------------------ */ - - String *docstring(Node *n, autodoc_t ad_type) { - - String *str = Getattr(n, "feature:docstring"); - bool have_ds = (str && Len(str) > 0); - bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")); - String *autodoc = NULL; - String *doc = NULL; - - if (have_ds) { - char *t = Char(str); - if (*t == '{') { - Delitem(str, 0); - Delitem(str, DOH_END); - } - } - - if (have_auto) { - autodoc = make_autodoc(n, ad_type); - have_auto = (autodoc && Len(autodoc) > 0); - } - - if (have_auto || have_ds) - doc = NewString("/*"); - - if (have_auto && have_ds) { // Both autodoc and docstring are present - Printv(doc, "\n", autodoc, "\n", str, "\n", NIL); - } else if (!have_auto && have_ds) { // only docstring - Printv(doc, str, NIL); - } else if (have_auto && !have_ds) { // only autodoc - Printv(doc, "\n", autodoc, "\n", NIL); - } else { - doc = NewString(""); - } - - if (have_auto || have_ds) - Append(doc, "*/\n"); - - // Save the generated strings in the parse tree in case they are used later - // by post processing tools - Setattr(n, "ruby:docstring", doc); - Setattr(n, "ruby:autodoc", autodoc); - return doc; - } - - /* ----------------------------------------------------------------------------- - * addMissingParameterNames() - * For functions that have not had nameless parameters set in the Language class. - * - * Inputs: - * plist - entire parameter list - * arg_offset - argument number for first parameter - * Side effects: - * The "lname" attribute in each parameter in plist will be contain a parameter name - * ----------------------------------------------------------------------------- */ - - void addMissingParameterNames(Node* n, ParmList *plist, int arg_offset) { - Parm *p = plist; - int i = arg_offset; - while (p) { - if (!Getattr(p, "lname")) { - String *name = makeParameterName(n, p, i); - Setattr(p, "lname", name); - Delete(name); - } - i++; - p = nextSibling(p); - } - } - - /* ------------------------------------------------------------ - * make_autodocParmList() - * Generate the documentation for the function parameters - * ------------------------------------------------------------ */ - - String *make_autodocParmList(Node *n, bool showTypes) { - String *doc = NewString(""); - String *pdocs = 0; - ParmList *plist = CopyParmList(Getattr(n, "parms")); - Parm *p; - Parm *pnext; - int lines = 0; - int arg_num = is_wrapping_class() ? 1 : 0; - const int maxwidth = 80; - - addMissingParameterNames(n, plist, arg_num); // for $1_name substitutions done in Swig_typemap_attach_parms - - Swig_typemap_attach_parms("in", plist, 0); - Swig_typemap_attach_parms("doc", plist, 0); - - if (Strcmp(ParmList_protostr(plist), "void") == 0) { - //No parameters actually - return doc; - } - - for (p = plist; p; p = pnext, arg_num++) { - - String *tm = Getattr(p, "tmap:in"); - if (tm) { - pnext = Getattr(p, "tmap:in:next"); - if (checkAttribute(p, "tmap:in:numinputs", "0")) { - continue; - } - } else { - pnext = nextSibling(p); - } - - String *name = 0; - String *type = 0; - String *value = 0; - String *pdoc = Getattr(p, "tmap:doc"); - if (pdoc) { - name = Getattr(p, "tmap:doc:name"); - type = Getattr(p, "tmap:doc:type"); - value = Getattr(p, "tmap:doc:value"); - } - - // Note: the generated name should be consistent with that in kwnames[] - String *made_name = 0; - if (!name) { - name = made_name = makeParameterName(n, p, arg_num); - } - - type = type ? type : Getattr(p, "type"); - value = value ? value : Getattr(p, "value"); - - if (SwigType_isvarargs(type)) - break; - - // Skip the 'self' parameter which in ruby is implicit - if ( Cmp(name, "self") == 0 ) - continue; - - // Make __p parameters just p (as used in STL) - Replace( name, "__", "", DOH_REPLACE_FIRST ); - - if (Len(doc)) { - // add a comma to the previous one if any - Append(doc, ", "); - - // Do we need to wrap a long line? - if ((Len(doc) - lines * maxwidth) > maxwidth) { - Printf(doc, "\n%s", tab4); - lines += 1; - } - } - - // Do the param type too? - Node *nn = classLookup(Getattr(p, "type")); - String *type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0); - if (showTypes) - Printf(doc, "%s ", type_str); - - Append(doc, name); - if (pdoc) { - if (!pdocs) - pdocs = NewString("Parameters:\n"); - Printf(pdocs, " %s.\n", pdoc); - } - - if (value) { - String *new_value = convertValue(value, Getattr(p, "type")); - if (new_value) { - value = new_value; - } else { - Node *lookup = Swig_symbol_clookup(value, 0); - if (lookup) - value = Getattr(lookup, "sym:name"); - } - Printf(doc, "=%s", value); - } - Delete(type_str); - Delete(made_name); - } - if (pdocs) - Setattr(n, "feature:pdocs", pdocs); - Delete(plist); - return doc; - } - - /* ------------------------------------------------------------ - * make_autodoc() - * Build a docstring for the node, using parameter and other - * info in the parse tree. If the value of the autodoc - * attribute is "0" then do not include parameter types, if - * it is "1" (the default) then do. If it has some other - * value then assume it is supplied by the extension writer - * and use it directly. - * ------------------------------------------------------------ */ - - String *make_autodoc(Node *n, autodoc_t ad_type) { - int extended = 0; - // If the function is overloaded then this function is called - // for the last one. Rewind to the first so the docstrings are - // in order. - while (Getattr(n, "sym:previousSibling")) - n = Getattr(n, "sym:previousSibling"); - - Node *pn = Swig_methodclass(n); - String* super_names = NewString(""); - String* class_name = Getattr(pn, "sym:name") ; - - if ( !class_name ) { - class_name = NewString(""); - } else { - class_name = Copy(class_name); - List *baselist = Getattr(pn, "bases"); - if (baselist && Len(baselist)) { - Iterator base = First(baselist); - while (base.item && GetFlag(base.item, "feature:ignore")) { - base = Next(base); - } - - int count = 0; - for ( ;base.item; ++count) { - if ( count ) Append(super_names, ", "); - String *basename = Getattr(base.item, "sym:name"); - - String* basenamestr = NewString(basename); - Node* parent = parentNode(base.item); - while (parent) - { - String *parent_name = Copy( Getattr(parent, "sym:name") ); - if ( !parent_name ) { - Node* mod = Getattr(parent, "module"); - if ( mod ) - parent_name = Copy( Getattr(mod, "name") ); - if ( parent_name ) - (Char(parent_name))[0] = (char)toupper((Char(parent_name))[0]); - } - if ( parent_name ) { - Insert(basenamestr, 0, "::"); - Insert(basenamestr, 0, parent_name); - Delete(parent_name); - } - parent = parentNode(parent); - } - - Append(super_names, basenamestr ); - Delete(basenamestr); - base = Next(base); - } - } - } - String* full_name; - if ( module ) { - full_name = NewString(module); - if (Len(class_name) > 0) - Append(full_name, "::"); - } - else - full_name = NewString(""); - Append(full_name, class_name); - - String* symname = Getattr(n, "sym:name"); - if ( Getattr( special_methods, symname ) ) - symname = Getattr( special_methods, symname ); - - String* methodName = NewString(full_name); - Append(methodName, symname); - - - // Each overloaded function will try to get documented, - // so we keep the name of the last overloaded function and its type. - // Documenting just from functionWrapper() is not possible as - // sym:name has already been changed to include the class name - if ( last_mode == ad_type && Cmp(methodName, last_autodoc) == 0 ) { - Delete(full_name); - Delete(class_name); - Delete(super_names); - Delete(methodName); - return NewString(""); - } - - - last_mode = ad_type; - last_autodoc = Copy(methodName); - - String *doc = NewString(""); - int counter = 0; - bool skipAuto = false; - Node* on = n; - for ( ; n; ++counter ) { - String *type_str = NULL; - skipAuto = false; - bool showTypes = false; - String *autodoc = Getattr(n, "feature:autodoc"); - autodoc_l dlevel = autodoc_level(autodoc); - switch (dlevel) { - case NO_AUTODOC: - break; - case NAMES_AUTODOC: - showTypes = false; - break; - case TYPES_AUTODOC: - showTypes = true; - break; - case EXTEND_AUTODOC: - extended = 1; - showTypes = false; - break; - case EXTEND_TYPES_AUTODOC: - extended = 1; - showTypes = true; - break; - case STRING_AUTODOC: - skipAuto = true; - break; - } - - SwigType *type = Getattr(n, "type"); - - if (type) { - if (Strcmp(type, "void") == 0) { - type_str = NULL; - } else { - SwigType *qt = SwigType_typedef_resolve_all(type); - if (SwigType_isenum(qt)) { - type_str = NewString("int"); - } else { - Node *nn = classLookup(type); - type_str = nn ? Copy(Getattr(nn, "sym:name")) : SwigType_str(type, 0); - } - } - } - - if (counter == 0) { - switch (ad_type) { - case AUTODOC_CLASS: - Printf(doc, " Document-class: %s", full_name); - if ( Len(super_names) > 0 ) - Printf( doc, " < %s", super_names); - Append(doc, "\n\n"); - break; - case AUTODOC_CTOR: - Printf(doc, " Document-method: %s.new\n\n", full_name); - break; - - case AUTODOC_DTOR: - break; - - case AUTODOC_STATICFUNC: - Printf(doc, " Document-method: %s.%s\n\n", full_name, symname); - break; - - case AUTODOC_FUNC: - case AUTODOC_METHOD: - case AUTODOC_GETTER: - Printf(doc, " Document-method: %s.%s\n\n", full_name, symname); - break; - case AUTODOC_SETTER: - Printf(doc, " Document-method: %s.%s=\n\n", full_name, symname); - break; - case AUTODOC_NONE: - break; - } - } - - if (skipAuto) { - if ( counter == 0 ) Printf(doc, " call-seq:\n"); - switch( ad_type ) - { - case AUTODOC_STATICFUNC: - case AUTODOC_FUNC: - case AUTODOC_METHOD: - case AUTODOC_GETTER: - { - String *paramList = make_autodocParmList(n, showTypes); - if (Len(paramList)) - Printf(doc, " %s(%s)", symname, paramList); - else - Printf(doc, " %s", symname); - if (type_str) - Printf(doc, " -> %s", type_str); - break; - } - case AUTODOC_SETTER: - { - Printf(doc, " %s=(x)", symname); - if (type_str) - Printf(doc, " -> %s", type_str); - break; - } - default: - break; - } - } else { - switch (ad_type) { - case AUTODOC_CLASS: - { - // Only do the autodoc if there isn't a docstring for the class - String *str = Getattr(n, "feature:docstring"); - if (counter == 0 && (str == 0 || Len(str) == 0)) { - if (CPlusPlus) { - Printf(doc, " Proxy of C++ %s class", full_name); - } else { - Printf(doc, " Proxy of C %s struct", full_name); - } - } - } - break; - case AUTODOC_CTOR: - if (counter == 0) - Printf(doc, " call-seq:\n"); - if (Strcmp(class_name, symname) == 0) { - String *paramList = make_autodocParmList(n, showTypes); - if (Len(paramList)) - Printf(doc, " %s.new(%s)", class_name, paramList); - else - Printf(doc, " %s.new", class_name); - } else { - Printf(doc, " %s.new(%s)", class_name, make_autodocParmList(n, showTypes)); - } - break; - - case AUTODOC_DTOR: - break; - - case AUTODOC_STATICFUNC: - case AUTODOC_FUNC: - case AUTODOC_METHOD: - case AUTODOC_GETTER: - { - if (counter == 0) - Printf(doc, " call-seq:\n"); - String *paramList = make_autodocParmList(n, showTypes); - if (Len(paramList)) - Printf(doc, " %s(%s)", symname, paramList); - else - Printf(doc, " %s", symname); - if (type_str) - Printf(doc, " -> %s", type_str); - break; - } - case AUTODOC_SETTER: - { - Printf(doc, " call-seq:\n"); - Printf(doc, " %s=(x)", symname); - if (type_str) - Printf(doc, " -> %s", type_str); - break; - } - case AUTODOC_NONE: - break; - } - } - - // if it's overloaded then get the next decl and loop around again - n = Getattr(n, "sym:nextSibling"); - if (n) - Append(doc, "\n"); - Delete(type_str); - } - - Printf(doc, "\n\n"); - if (!skipAuto) { - switch (ad_type) { - case AUTODOC_CLASS: - case AUTODOC_DTOR: - break; - case AUTODOC_CTOR: - Printf(doc, "Class constructor.\n"); - break; - case AUTODOC_STATICFUNC: - Printf(doc, "A class method.\n"); - break; - case AUTODOC_FUNC: - Printf(doc, "A module function.\n"); - break; - case AUTODOC_METHOD: - Printf(doc, "An instance method.\n"); - break; - case AUTODOC_GETTER: - Printf(doc, "Get value of attribute.\n"); - break; - case AUTODOC_SETTER: - Printf(doc, "Set new value for attribute.\n"); - break; - case AUTODOC_NONE: - break; - } - } - - - n = on; - while ( n ) { - String *autodoc = Getattr(n, "feature:autodoc"); - autodoc_l dlevel = autodoc_level(autodoc); - - switch (dlevel) { - case NO_AUTODOC: - case NAMES_AUTODOC: - case TYPES_AUTODOC: - extended = 0; - break; - case STRING_AUTODOC: - extended = 2; - Replaceall( autodoc, "$class", class_name ); - Printv(doc, autodoc, ".", NIL); - break; - case EXTEND_AUTODOC: - case EXTEND_TYPES_AUTODOC: - extended = 1; - break; - } - - - if (extended) { - String *pdocs = Getattr(n, "feature:pdocs"); - if (pdocs) { - Printv(doc, "\n\n", pdocs, NULL); - break; - } - if ( extended == 2 ) break; - } - n = Getattr(n, "sym:nextSibling"); - } - - Delete(full_name); - Delete(class_name); - Delete(super_names); - Delete(methodName); - - return doc; - } - - /* ------------------------------------------------------------ - * convertValue() - * Check if string v can be a Ruby value literal, - * (eg. number or string), or translate it to a Ruby literal. - * ------------------------------------------------------------ */ - String *convertValue(String *v, SwigType *t) { - if (v && Len(v) > 0) { - char fc = (Char(v))[0]; - if (('0' <= fc && fc <= '9') || '\'' == fc || '"' == fc) { - /* number or string (or maybe NULL pointer) */ - if (SwigType_ispointer(t) && Strcmp(v, "0") == 0) - return NewString("None"); - else - return v; - } - if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0) - return SwigType_ispointer(t) ? NewString("nil") : NewString("0"); - if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0) - return NewString("True"); - if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0) - return NewString("False"); - } - return 0; - } - -public: - - /* --------------------------------------------------------------------- - * RUBY() - * - * Initialize member data - * --------------------------------------------------------------------- */ - RUBY() : - module(0), - modvar(0), - feature(0), - prefix(0), - current(0), - classes(0), - klass(0), - special_methods(0), - f_directors(0), - f_directors_h(0), - f_directors_helpers(0), - f_begin(0), - f_runtime(0), - f_runtime_h(0), - f_header(0), - f_wrappers(0), - f_init(0), - f_initbeforefunc(0), - useGlobalModule(false), - multipleInheritance(false), - last_mode(AUTODOC_NONE), - last_autodoc(NewString("")) { - current = NO_CPP; - director_prot_ctor_code = NewString(""); - Printv(director_prot_ctor_code, - "if ( $comparison ) { /* subclassed */\n", - " $director_new \n", - "} else {\n", " rb_raise(rb_eRuntimeError,\"accessing abstract class or protected constructor\"); \n", " return Qnil;\n", "}\n", NIL); - director_multiple_inheritance = 0; - director_language = 1; - } - - /* --------------------------------------------------------------------- - * main() - * - * Parse command line options and initializes variables. - * --------------------------------------------------------------------- */ - - virtual void main(int argc, char *argv[]) { - - int autorename = 0; - - /* Set location of SWIG library */ - SWIG_library_directory("ruby"); - - /* Look for certain command line options */ - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-initname") == 0) { - if (argv[i + 1]) { - char *name = argv[i + 1]; - feature = NewString(name); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } - else if (strcmp(argv[i], "-feature") == 0) { - fprintf( stderr, "Warning: Ruby -feature option is deprecated, " - "please use -initname instead.\n"); - if (argv[i + 1]) { - char *name = argv[i + 1]; - feature = NewString(name); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-globalmodule") == 0) { - useGlobalModule = true; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-minherit") == 0) { - multipleInheritance = true; - director_multiple_inheritance = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-autorename") == 0) { - autorename = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-noautorename") == 0) { - autorename = 0; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-prefix") == 0) { - if (argv[i + 1]) { - char *name = argv[i + 1]; - prefix = NewString(name); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } - } else if (strcmp(argv[i], "-help") == 0) { - Printf(stdout, "%s\n", usage); - } else if (strcmp(argv[i], "-cppcast") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nocppcast") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); - Swig_mark_arg(i); - Exit(EXIT_FAILURE); - } - } - } - - if (autorename) { - /* Turn on the autorename mode */ - Preprocessor_define((DOH *) "SWIG_RUBY_AUTORENAME", 0); - } - - /* Add a symbol to the parser for conditional compilation */ - Preprocessor_define("SWIGRUBY 1", 0); - - /* Add typemap definitions */ - SWIG_typemap_lang("ruby"); - SWIG_config_file("ruby.swg"); - allow_overloading(); - } - - /** - * Generate initialization code to define the Ruby module(s), - * accounting for nested modules as necessary. - */ - void defineRubyModule() { - List *modules = Split(module, ':', INT_MAX); - if (modules != 0 && Len(modules) > 0) { - String *mv = 0; - Iterator m; - m = First(modules); - while (m.item) { - if (Len(m.item) > 0) { - if (mv != 0) { - Printv(f_init, tab4, modvar, " = rb_define_module_under(", modvar, ", \"", m.item, "\");\n", NIL); - } else { - Printv(f_init, tab4, modvar, " = rb_define_module(\"", m.item, "\");\n", NIL); - mv = NewString(modvar); - } - } - m = Next(m); - } - Delete(mv); - Delete(modules); - } - } - - void registerMagicMethods() { - - special_methods = NewHash(); - - /* Python->Ruby style special method name. */ - /* Basic */ - Setattr(special_methods, "__repr__", "inspect"); - Setattr(special_methods, "__str__", "to_s"); - Setattr(special_methods, "__cmp__", "<=>"); - Setattr(special_methods, "__hash__", "hash"); - Setattr(special_methods, "__nonzero__", "nonzero?"); - - /* Callable */ - Setattr(special_methods, "__call__", "call"); - - /* Collection */ - Setattr(special_methods, "__len__", "length"); - Setattr(special_methods, "__getitem__", "[]"); - Setattr(special_methods, "__setitem__", "[]="); - - /* Operators */ - Setattr(special_methods, "__add__", "+"); - Setattr(special_methods, "__pos__", "+@"); - Setattr(special_methods, "__sub__", "-"); - Setattr(special_methods, "__neg__", "-@"); - Setattr(special_methods, "__mul__", "*"); - Setattr(special_methods, "__div__", "/"); - Setattr(special_methods, "__mod__", "%"); - Setattr(special_methods, "__lshift__", "<<"); - Setattr(special_methods, "__rshift__", ">>"); - Setattr(special_methods, "__and__", "&"); - Setattr(special_methods, "__or__", "|"); - Setattr(special_methods, "__xor__", "^"); - Setattr(special_methods, "__invert__", "~"); - Setattr(special_methods, "__lt__", "<"); - Setattr(special_methods, "__le__", "<="); - Setattr(special_methods, "__gt__", ">"); - Setattr(special_methods, "__ge__", ">="); - Setattr(special_methods, "__eq__", "=="); - - /* Other numeric */ - Setattr(special_methods, "__divmod__", "divmod"); - Setattr(special_methods, "__pow__", "**"); - Setattr(special_methods, "__abs__", "abs"); - Setattr(special_methods, "__int__", "to_i"); - Setattr(special_methods, "__float__", "to_f"); - Setattr(special_methods, "__coerce__", "coerce"); - } - - /* --------------------------------------------------------------------- - * top() - * --------------------------------------------------------------------- */ - - virtual int top(Node *n) { - - String *mod_docstring = NULL; - - /** - * See if any Ruby module options have been specified as options - * to the %module directive. - */ - Node *swigModule = Getattr(n, "module"); - if (swigModule) { - Node *options = Getattr(swigModule, "options"); - if (options) { - if (Getattr(options, "directors")) { - allow_directors(); - } - if (Getattr(options, "dirprot")) { - allow_dirprot(); - } - if (Getattr(options, "ruby_globalmodule")) { - useGlobalModule = true; - } - if (Getattr(options, "ruby_minherit")) { - multipleInheritance = true; - director_multiple_inheritance = 1; - } - mod_docstring = Getattr(options, "docstring"); - } - } - - /* Set comparison with none for ConstructorToFunction */ - - - setSubclassInstanceCheck(NewStringf("strcmp(rb_obj_classname(self), classname) != 0")); - // setSubclassInstanceCheck(NewString("CLASS_OF(self) != cFoo.klass")); - - /* Initialize all of the output files */ - String *outfile = Getattr(n, "outfile"); - String *outfile_h = Getattr(n, "outfile_h"); - - if (!outfile) { - Printf(stderr, "Unable to determine outfile\n"); - Exit(EXIT_FAILURE); - } - - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - f_wrappers = NewString(""); - f_directors_h = NewString(""); - f_directors = NewString(""); - f_directors_helpers = NewString(""); - f_initbeforefunc = NewString(""); - - if (directorsEnabled()) { - if (!outfile_h) { - Printf(stderr, "Unable to determine outfile_h\n"); - Exit(EXIT_FAILURE); - } - f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files()); - if (!f_runtime_h) { - FileErrorDisplay(outfile_h); - Exit(EXIT_FAILURE); - } - } - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", f_init); - Swig_register_filebyname("director", f_directors); - Swig_register_filebyname("director_h", f_directors_h); - Swig_register_filebyname("director_helpers", f_directors_helpers); - Swig_register_filebyname("initbeforefunc", f_initbeforefunc); - - modvar = 0; - current = NO_CPP; - klass = 0; - classes = NewHash(); - - registerMagicMethods(); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "RUBY"); - - if (directorsEnabled()) { - Printf(f_runtime, "#define SWIG_DIRECTORS\n"); - } - - Printf(f_runtime, "\n"); - - /* typedef void *VALUE */ - SwigType *value = NewSwigType(T_VOID); - SwigType_add_pointer(value); - SwigType_typedef(value, "VALUE"); - Delete(value); - - /* Set module name */ - set_module(Char(Getattr(n, "name"))); - - if (directorsEnabled()) { - /* Build a version of the module name for use in a C macro name. */ - String *module_macro = Copy(module); - Replaceall(module_macro, "::", "__"); - - Swig_banner(f_directors_h); - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module_macro); - Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module_macro); - Printf(f_directors_h, "namespace Swig {\n"); - Printf(f_directors_h, " class Director;\n"); - Printf(f_directors_h, "}\n\n"); - - Printf(f_directors_helpers, "/* ---------------------------------------------------\n"); - Printf(f_directors_helpers, " * C++ director class helpers\n"); - Printf(f_directors_helpers, " * --------------------------------------------------- */\n\n"); - - Printf(f_directors, "\n\n"); - Printf(f_directors, "/* ---------------------------------------------------\n"); - Printf(f_directors, " * C++ director class methods\n"); - Printf(f_directors, " * --------------------------------------------------- */\n\n"); - if (outfile_h) { - String *filename = Swig_file_filename(outfile_h); - Printf(f_directors, "#include \"%s\"\n\n", filename); - Delete(filename); - } - - Delete(module_macro); - } - - Printf(f_header, "#define SWIG_init Init_%s\n", feature); - Printf(f_header, "#define SWIG_name \"%s\"\n\n", module); - - if (mod_docstring) { - if (Len(mod_docstring)) { - Printf(f_header, "/*\n Document-module: %s\n\n%s\n*/\n", module, mod_docstring); - } - Delete(mod_docstring); - mod_docstring = NULL; - } - - Printf(f_header, "static VALUE %s;\n", modvar); - - /* Start generating the initialization function */ - String* docs = docstring(n, AUTODOC_CLASS); - Printf(f_init, "/*\n%s\n*/", docs ); - Printv(f_init, "\n", "#ifdef __cplusplus\n", "extern \"C\"\n", "#endif\n", "SWIGEXPORT void Init_", feature, "(void) {\n", "size_t i;\n", "\n", NIL); - - Printv(f_init, tab4, "SWIG_InitRuntime();\n", NIL); - - if (!useGlobalModule) - defineRubyModule(); - - Printv(f_init, "\n", "SWIG_InitializeModule(0);\n", "for (i = 0; i < swig_module.size; i++) {\n", "SWIG_define_class(swig_module.types[i]);\n", "}\n", NIL); - Printf(f_init, "\n"); - - /* Initialize code to keep track of objects */ - Printf(f_init, "SWIG_RubyInitializeTrackings();\n"); - - Language::top(n); - - if (directorsEnabled()) { - // Insert director runtime into the f_runtime file (make it occur before %header section) - Swig_insert_file("director_common.swg", f_runtime); - Swig_insert_file("director.swg", f_runtime); - } - - /* Finish off our init function */ - Printf(f_init, "}\n"); - SwigType_emit_type_table(f_runtime, f_wrappers); - - /* Close all of the files */ - Dump(f_runtime, f_begin); - Dump(f_header, f_begin); - - if (directorsEnabled()) { - Dump(f_directors_helpers, f_begin); - Dump(f_directors, f_begin); - Dump(f_directors_h, f_runtime_h); - Printf(f_runtime_h, "\n"); - Printf(f_runtime_h, "#endif\n"); - Delete(f_runtime_h); - } - - Dump(f_wrappers, f_begin); - Dump(f_initbeforefunc, f_begin); - Wrapper_pretty_print(f_init, f_begin); - - Delete(f_header); - Delete(f_wrappers); - Delete(f_init); - Delete(f_initbeforefunc); - Delete(f_runtime); - Delete(f_begin); - - return SWIG_OK; - } - - /* ----------------------------------------------------------------------------- - * importDirective() - * ----------------------------------------------------------------------------- */ - - virtual int importDirective(Node *n) { - String *modname = Getattr(n, "module"); - if (modname) { - if (prefix) { - Insert(modname, 0, prefix); - } - - List *modules = Split(modname, ':', INT_MAX); - if (modules && Len(modules) > 0) { - modname = NewString(""); - String *last = NULL; - Iterator m = First(modules); - while (m.item) { - if (Len(m.item) > 0) { - if (last) { - Append(modname, "/"); - } - Append(modname, m.item); - last = m.item; - } - m = Next(m); - } - Printf(f_init, "rb_require(\"%s\");\n", modname); - Delete(modname); - } - Delete(modules); - } - return Language::importDirective(n); - } - - /* --------------------------------------------------------------------- - * set_module(const char *mod_name) - * - * Sets the module name. Does nothing if it's already set (so it can - * be overridden as a command line option). - *---------------------------------------------------------------------- */ - - void set_module(const char *s) { - String *mod_name = NewString(s); - if (module == 0) { - /* Start with the empty string */ - module = NewString(""); - - if (prefix) { - Insert(mod_name, 0, prefix); - } - - /* Account for nested modules */ - List *modules = Split(mod_name, ':', INT_MAX); - if (modules != 0 && Len(modules) > 0) { - String *last = 0; - Iterator m = First(modules); - while (m.item) { - if (Len(m.item) > 0) { - String *cap = NewString(m.item); - (Char(cap))[0] = (char)toupper((Char(cap))[0]); - if (last != 0) { - Append(module, "::"); - } - Append(module, cap); - last = m.item; - } - m = Next(m); - } - if (last) { - if (feature == 0) { - feature = Copy(last); - } - (Char(last))[0] = (char)toupper((Char(last))[0]); - modvar = NewStringf("m%s", last); - } - } - Delete(modules); - } - Delete(mod_name); - } - - /* -------------------------------------------------------------------------- - * nativeWrapper() - * -------------------------------------------------------------------------- */ - virtual int nativeWrapper(Node *n) { - String *funcname = Getattr(n, "wrap:name"); - Swig_warning(WARN_LANG_NATIVE_UNIMPL, input_file, line_number, "Adding native function %s not supported (ignored).\n", funcname); - return SWIG_NOWRAP; - } - - /** - * Process the comma-separated list of aliases (if any). - */ - void defineAliases(Node *n, const_String_or_char_ptr iname) { - String *aliasv = Getattr(n, "feature:alias"); - if (aliasv) { - List *aliases = Split(aliasv, ',', INT_MAX); - if (aliases && Len(aliases) > 0) { - Iterator alias = First(aliases); - while (alias.item) { - if (Len(alias.item) > 0) { - if (current == NO_CPP) { - if (useGlobalModule) { - Printv(f_init, tab4, "rb_define_alias(rb_cObject, \"", alias.item, "\", \"", iname, "\");\n", NIL); - } else { - Printv(f_init, tab4, "rb_define_alias(rb_singleton_class(", modvar, "), \"", alias.item, "\", \"", iname, "\");\n", NIL); - } - } else if (multipleInheritance) { - Printv(klass->init, tab4, "rb_define_alias(", klass->mImpl, ", \"", alias.item, "\", \"", iname, "\");\n", NIL); - } else { - Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias.item, "\", \"", iname, "\");\n", NIL); - } - } - alias = Next(alias); - } - } - Delete(aliases); - } - } - - /* --------------------------------------------------------------------- - * create_command(Node *n, char *iname) - * - * Creates a new command from a C function. - * iname = Name of function in scripting language - * - * A note about what "protected" and "private" mean in Ruby: - * - * A private method is accessible only within the class or its subclasses, - * and it is callable only in "function form", with 'self' (implicit or - * explicit) as a receiver. - * - * A protected method is callable only from within its class, but unlike - * a private method, it can be called with a receiver other than self, such - * as another instance of the same class. - * --------------------------------------------------------------------- */ - - void create_command(Node *n, const_String_or_char_ptr iname) { - - String *alloc_func = Swig_name_wrapper(iname); - String *wname = Swig_name_wrapper(iname); - if (CPlusPlus) { - Insert(wname, 0, "VALUEFUNC("); - Append(wname, ")"); - } - if (current != NO_CPP) - iname = klass->strip(iname); - if (Getattr(special_methods, iname)) { - iname = GetChar(special_methods, iname); - } - - String *s = NewString(""); - String *temp = NewString(""); - -#ifdef SWIG_PROTECTED_TARGET_METHODS - const char *rb_define_method = is_public(n) ? "rb_define_method" : "rb_define_protected_method"; -#else - const char *rb_define_method = "rb_define_method"; -#endif - switch (current) { - case MEMBER_FUNC: - { - if (multipleInheritance) { - Printv(klass->init, tab4, rb_define_method, "(", klass->mImpl, ", \"", iname, "\", ", wname, ", -1);\n", NIL); - } else { - Printv(klass->init, tab4, rb_define_method, "(", klass->vname, ", \"", iname, "\", ", wname, ", -1);\n", NIL); - } - } - break; - case CONSTRUCTOR_ALLOCATE: - Printv(s, tab4, "rb_define_alloc_func(", klass->vname, ", ", alloc_func, ");\n", NIL); - Replaceall(klass->init, "$allocator", s); - break; - case CONSTRUCTOR_INITIALIZE: - Printv(s, tab4, rb_define_method, "(", klass->vname, ", \"initialize\", ", wname, ", -1);\n", NIL); - Replaceall(klass->init, "$initializer", s); - break; - case MEMBER_VAR: - Append(temp, iname); - /* Check for _set or _get at the end of the name. */ - if (Len(temp) > 4) { - const char *p = Char(temp) + (Len(temp) - 4); - if (strcmp(p, "_set") == 0) { - Delslice(temp, Len(temp) - 4, DOH_END); - Append(temp, "="); - } else if (strcmp(p, "_get") == 0) { - Delslice(temp, Len(temp) - 4, DOH_END); - } - } - if (multipleInheritance) { - Printv(klass->init, tab4, "rb_define_method(", klass->mImpl, ", \"", temp, "\", ", wname, ", -1);\n", NIL); - } else { - Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"", temp, "\", ", wname, ", -1);\n", NIL); - } - break; - case STATIC_FUNC: - Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname, ", \"", iname, "\", ", wname, ", -1);\n", NIL); - break; - case NO_CPP: - if (!useGlobalModule) { - Printv(s, tab4, "rb_define_module_function(", modvar, ", \"", iname, "\", ", wname, ", -1);\n", NIL); - Printv(f_init, s, NIL); - } else { - Printv(s, tab4, "rb_define_global_function(\"", iname, "\", ", wname, ", -1);\n", NIL); - Printv(f_init, s, NIL); - } - break; - case DESTRUCTOR: - case CLASS_CONST: - case STATIC_VAR: - default: - assert(false); // Should not have gotten here for these types - } - - defineAliases(n, iname); - - Delete(temp); - Delete(s); - Delete(wname); - Delete(alloc_func); - } - - /* --------------------------------------------------------------------- - * applyInputTypemap() - * - * Look up the appropriate "in" typemap for this parameter (p), - * substitute the correct strings for the typemap parameters, and dump the - * resulting code to the wrapper file. - * --------------------------------------------------------------------- */ - - Parm *applyInputTypemap(Parm *p, String *source, Wrapper *f, String *symname) { - String *tm; - SwigType *pt = Getattr(p, "type"); - if ((tm = Getattr(p, "tmap:in"))) { - Replaceall(tm, "$input", source); - Replaceall(tm, "$symname", symname); - - if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - - Setattr(p, "emit:input", Copy(source)); - Printf(f->code, "%s\n", tm); - p = Getattr(p, "tmap:in:next"); - } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); - p = nextSibling(p); - } - return p; - } - - Parm *skipIgnoredArgs(Parm *p) { - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - return p; - } - - /* --------------------------------------------------------------------- - * marshalInputArgs() - * - * Process all of the arguments passed into the scripting language - * method and convert them into C/C++ function arguments using the - * supplied typemaps. - * --------------------------------------------------------------------- */ - - void marshalInputArgs(Node *n, ParmList *l, int numarg, int numreq, String *kwargs, bool allow_kwargs, Wrapper *f) { - int i; - Parm *p; - String *tm; - String *source; - - source = NewString(""); - - bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n)); - - /** - * The 'start' value indicates which of the C/C++ function arguments - * produced here corresponds to the first value in Ruby's argv[] array. - * The value of start is either zero or one. If start is zero, then - * the first argument (with name arg1) is based on the value of argv[0]. - * If start is one, then arg1 is based on the value of argv[1]. - */ - int start = (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) ? 1 : 0; - - int varargs = emit_isvarargs(l); - - Printf(kwargs, "{ "); - for (i = 0, p = l; i < numarg; i++) { - - p = skipIgnoredArgs(p); - - String *pn = Getattr(p, "name"); - - /* Produce string representation of source argument */ - Clear(source); - - /* First argument is a special case */ - if (i == 0) { - Printv(source, (start == 0) ? "argv[0]" : "self", NIL); - } else { - Printf(source, "argv[%d]", i - start); - } - - if (i >= (numreq)) { /* Check if parsing an optional argument */ - Printf(f->code, " if (argc > %d) {\n", i - start); - } - - /* Record argument name for keyword argument handling */ - if (Len(pn)) { - Printf(kwargs, "\"%s\",", pn); - } else { - Printf(kwargs, "\"arg%d\",", i + 1); - } - - /* Look for an input typemap */ - p = applyInputTypemap(p, source, f, Getattr(n, "name")); - if (i >= numreq) { - Printf(f->code, "}\n"); - } - } - - /* Finish argument marshalling */ - Printf(kwargs, " NULL }"); - if (allow_kwargs) { -// kwarg support not implemented -// Printv(f->locals, tab4, "const char *kwnames[] = ", kwargs, ";\n", NIL); - } - - /* Trailing varargs */ - if (varargs) { - if (p && (tm = Getattr(p, "tmap:in"))) { - Clear(source); - Printf(source, "argv[%d]", i - start); - Replaceall(tm, "$input", source); - Setattr(p, "emit:input", Copy(source)); - Printf(f->code, "if (argc > %d) {\n", i - start); - Printv(f->code, tm, "\n", NIL); - Printf(f->code, "}\n"); - } - } - - Delete(source); - } - - /* --------------------------------------------------------------------- - * insertConstraintCheckingCode(ParmList *l, Wrapper *f) - * - * Checks each of the parameters in the parameter list for a "check" - * typemap and (if it finds one) inserts the typemapping code into - * the function wrapper. - * --------------------------------------------------------------------- */ - - void insertConstraintCheckingCode(ParmList *l, Wrapper *f) { - Parm *p; - String *tm; - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - } - - /* --------------------------------------------------------------------- - * insertCleanupCode(ParmList *l, String *cleanup) - * - * Checks each of the parameters in the parameter list for a "freearg" - * typemap and (if it finds one) inserts the typemapping code into - * the function wrapper. - * --------------------------------------------------------------------- */ - - void insertCleanupCode(ParmList *l, String *cleanup) { - String *tm; - for (Parm *p = l; p;) { - if ((tm = Getattr(p, "tmap:freearg"))) { - if (Len(tm) != 0) { - Printv(cleanup, tm, "\n", NIL); - } - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - } - - /* --------------------------------------------------------------------- - * insertArgOutputCode(ParmList *l, String *outarg, int& need_result) - * - * Checks each of the parameters in the parameter list for a "argout" - * typemap and (if it finds one) inserts the typemapping code into - * the function wrapper. - * --------------------------------------------------------------------- */ - - void insertArgOutputCode(ParmList *l, String *outarg, int &need_result) { - String *tm; - for (Parm *p = l; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - Replaceall(tm, "$result", "vresult"); - Replaceall(tm, "$arg", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - - Printv(outarg, tm, "\n", NIL); - need_result += 1; - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - } - - /* --------------------------------------------------------------------- - * validIdentifier() - * - * Is this a valid identifier in the scripting language? - * Ruby method names can include any combination of letters, numbers - * and underscores. A Ruby method name may optionally end with - * a question mark ("?"), exclamation point ("!") or equals sign ("="). - * - * Methods whose names end with question marks are, by convention, - * predicate methods that return true or false (e.g. Array#empty?). - * - * Methods whose names end with exclamation points are, by convention, - * called bang methods that modify the instance in place (e.g. Array#sort!). - * - * Methods whose names end with an equals sign are attribute setters - * (e.g. Thread#critical=). - * --------------------------------------------------------------------- */ - - virtual int validIdentifier(String *s) { - char *c = Char(s); - while (*c) { - if (!(isalnum(*c) || (*c == '_') || (*c == '?') || (*c == '!') || (*c == '='))) - return 0; - c++; - } - return 1; - } - - /* --------------------------------------------------------------------- - * functionWrapper() - * - * Create a function declaration and register it with the interpreter. - * --------------------------------------------------------------------- */ - - virtual int functionWrapper(Node *n) { - - String *nodeType; - bool destructor; - - String *symname = Copy(Getattr(n, "sym:name")); - SwigType *t = Getattr(n, "type"); - ParmList *l = Getattr(n, "parms"); - int director_method = 0; - String *tm; - - int need_result = 0; - - /* Ruby needs no destructor wrapper */ - if (current == DESTRUCTOR) - return SWIG_NOWRAP; - - nodeType = Getattr(n, "nodeType"); - destructor = (!Cmp(nodeType, "destructor")); - - /* If the C++ class constructor is overloaded, we only want to - * write out the "new" singleton method once since it is always - * the same. (It's the "initialize" method that will handle the - * overloading). */ - - if (current == CONSTRUCTOR_ALLOCATE && Swig_symbol_isoverloaded(n) && Getattr(n, "sym:nextSibling") != 0) - return SWIG_OK; - - String *overname = 0; - if (Getattr(n, "sym:overloaded")) { - overname = Getattr(n, "sym:overname"); - } else { - if (!addSymbol(symname, n)) - return SWIG_ERROR; - } - - String *cleanup = NewString(""); - String *outarg = NewString(""); - String *kwargs = NewString(""); - Wrapper *f = NewWrapper(); - - /* Rename predicate methods */ - if (GetFlag(n, "feature:predicate")) { - Append(symname, "?"); - } - - /* Rename bang methods */ - if (GetFlag(n, "feature:bang")) { - Append(symname, "!"); - } - - /* Determine the name of the SWIG wrapper function */ - String *wname = Swig_name_wrapper(symname); - if (overname && current != CONSTRUCTOR_ALLOCATE) { - Append(wname, overname); - } - - /* Emit arguments */ - if (current != CONSTRUCTOR_ALLOCATE) { - emit_parameter_variables(l, f); - } - - /* Attach standard typemaps */ - if (current != CONSTRUCTOR_ALLOCATE) { - emit_attach_parmmaps(l, f); - } - Setattr(n, "wrap:parms", l); - - /* Get number of arguments */ - int numarg = emit_num_arguments(l); - int numreq = emit_num_required(l); - int varargs = emit_isvarargs(l); - bool allow_kwargs = GetFlag(n, "feature:kwargs") ? true : false; - - bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n)); - int start = (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) ? 1 : 0; - - /* Now write the wrapper function itself */ - if (current == CONSTRUCTOR_ALLOCATE) { - Printv(f->def, "SWIGINTERN VALUE\n", NIL); - Printf(f->def, "#ifdef HAVE_RB_DEFINE_ALLOC_FUNC\n"); - Printv(f->def, wname, "(VALUE self)\n", NIL); - Printf(f->def, "#else\n"); - Printv(f->def, wname, "(int argc, VALUE *argv, VALUE self)\n", NIL); - Printf(f->def, "#endif\n"); - Printv(f->def, "{\n", NIL); - } else if (current == CONSTRUCTOR_INITIALIZE) { - Printv(f->def, "SWIGINTERN VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL); - if (!varargs) { - Printf(f->code, "if ((argc < %d) || (argc > %d)) ", numreq - start, numarg - start); - } else { - Printf(f->code, "if (argc < %d) ", numreq - start); - } - Printf(f->code, "{rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc); SWIG_fail;}\n", numreq - start); - } else { - - if ( current == NO_CPP ) - { - String* docs = docstring(n, AUTODOC_FUNC); - Printf(f_wrappers, "%s", docs); - Delete(docs); - } - - Printv(f->def, "SWIGINTERN VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL); - if (!varargs) { - Printf(f->code, "if ((argc < %d) || (argc > %d)) ", numreq - start, numarg - start); - } else { - Printf(f->code, "if (argc < %d) ", numreq - start); - } - Printf(f->code, "{rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc); SWIG_fail;}\n", numreq - start); - } - - /* Now walk the function parameter list and generate code */ - /* to get arguments */ - if (current != CONSTRUCTOR_ALLOCATE) { - marshalInputArgs(n, l, numarg, numreq, kwargs, allow_kwargs, f); - } - // FIXME? - if (ctor_director) { - numarg--; - numreq--; - } - - /* Insert constraint checking code */ - insertConstraintCheckingCode(l, f); - - /* Insert cleanup code */ - insertCleanupCode(l, cleanup); - - /* Insert argument output code */ - insertArgOutputCode(l, outarg, need_result); - - /* if the object is a director, and the method call originated from its - * underlying Ruby object, resolve the call by going up the c++ - * inheritance chain. otherwise try to resolve the method in Ruby. - * without this check an infinite loop is set up between the director and - * shadow class method calls. - */ - - // NOTE: this code should only be inserted if this class is the - // base class of a director class. however, in general we haven't - // yet analyzed all classes derived from this one to see if they are - // directors. furthermore, this class may be used as the base of - // a director class defined in a completely different module at a - // later time, so this test must be included whether or not directorbase - // is true. we do skip this code if directors have not been enabled - // at the command line to preserve source-level compatibility with - // non-polymorphic swig. also, if this wrapper is for a smart-pointer - // method, there is no need to perform the test since the calling object - // (the smart-pointer) and the director object (the "pointee") are - // distinct. - - director_method = is_member_director(n) && !is_smart_pointer() && !destructor; - if (director_method) { - Wrapper_add_local(f, "director", "Swig::Director *director = 0"); - Printf(f->code, "director = dynamic_cast<Swig::Director *>(arg1);\n"); - Wrapper_add_local(f, "upcall", "bool upcall = false"); - Append(f->code, "upcall = (director && (director->swig_get_self() == self));\n"); - } - - /* Now write code to make the function call */ - if (current != CONSTRUCTOR_ALLOCATE) { - if (current == CONSTRUCTOR_INITIALIZE) { - Node *pn = Swig_methodclass(n); - String *symname = Getattr(pn, "sym:name"); - String *action = Getattr(n, "wrap:action"); - if (directorsEnabled()) { - String *classname = NewStringf("const char *classname SWIGUNUSED = \"%s::%s\"", module, symname); - Wrapper_add_local(f, "classname", classname); - } - if (action) { - SwigType *smart = Swig_cparse_smartptr(pn); - String *result_name = NewStringf("%s%s", smart ? "smart" : "", Swig_cresult_name()); - if (smart) { - String *result_var = NewStringf("%s *%s = 0", SwigType_namestr(smart), result_name); - Wrapper_add_local(f, result_name, result_var); - Printf(action, "\n%s = new %s(%s);", result_name, SwigType_namestr(smart), Swig_cresult_name()); - } - Printf(action, "\nDATA_PTR(self) = %s;", result_name); - if (GetFlag(pn, "feature:trackobjects")) { - Printf(action, "\nSWIG_RubyAddTracking(%s, self);", result_name); - } - Delete(result_name); - Delete(smart); - } - } - - /* Emit the function call */ - if (director_method) { - Printf(f->code, "try {\n"); - } - - Setattr(n, "wrap:name", wname); - - Swig_director_emit_dynamic_cast(n, f); - String *actioncode = emit_action(n); - - if (director_method) { - Printf(actioncode, "} catch (Swig::DirectorException& e) {\n"); - Printf(actioncode, " rb_exc_raise(e.getError());\n"); - Printf(actioncode, " SWIG_fail;\n"); - Printf(actioncode, "}\n"); - } - - /* Return value if necessary */ - if (SwigType_type(t) != T_VOID && current != CONSTRUCTOR_INITIALIZE) { - need_result = 1; - if (GetFlag(n, "feature:predicate")) { - Printv(actioncode, tab4, "vresult = (", Swig_cresult_name(), " ? Qtrue : Qfalse);\n", NIL); - } else { - tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode); - actioncode = 0; - if (tm) { - Replaceall(tm, "$result", "vresult"); - - if (GetFlag(n, "feature:new")) - Replaceall(tm, "$owner", "SWIG_POINTER_OWN"); - else - Replaceall(tm, "$owner", "0"); - - // Unwrap return values that are director classes so that the original Ruby object is returned instead. - if (Swig_director_can_unwrap(n)) { - Wrapper_add_local(f, "director", "Swig::Director *director = 0"); - Printf(f->code, "director = dynamic_cast<Swig::Director *>(%s);\n", Swig_cresult_name()); - Printf(f->code, "if (director) {\n"); - Printf(f->code, " vresult = director->swig_get_self();\n"); - Printf(f->code, "} else {\n"); - Printf(f->code, "%s\n", tm); - Printf(f->code, "}\n"); - director_method = 0; - } else { - Printf(f->code, "%s\n", tm); - } - - Delete(tm); - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s.\n", SwigType_str(t, 0)); - } - } - } - if (actioncode) { - Append(f->code, actioncode); - Delete(actioncode); - } - emit_return_variable(n, t, f); - } - - /* Extra code needed for new and initialize methods */ - if (current == CONSTRUCTOR_ALLOCATE) { - Node *pn = Swig_methodclass(n); - SwigType *smart = Swig_cparse_smartptr(pn); - if (smart) - SwigType_add_pointer(smart); - String *classtype = smart ? smart : t; - need_result = 1; - Printf(f->code, "VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE%s);\n", Char(SwigType_manglestr(classtype))); - Printf(f->code, "#ifndef HAVE_RB_DEFINE_ALLOC_FUNC\n"); - Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n"); - Printf(f->code, "#endif\n"); - Delete(smart); - } else if (current == CONSTRUCTOR_INITIALIZE) { - need_result = 1; - } - else - { - if ( need_result > 1 ) { - if ( SwigType_type(t) == T_VOID ) - Printf(f->code, "vresult = rb_ary_new();\n"); - else - { - Printf(f->code, "if (vresult == Qnil) vresult = rb_ary_new();\n"); - Printf(f->code, "else vresult = SWIG_Ruby_AppendOutput( " - "rb_ary_new(), vresult);\n"); - } - } - } - - /* Dump argument output code; */ - Printv(f->code, outarg, NIL); - - /* Dump the argument cleanup code */ - int need_cleanup = (current != CONSTRUCTOR_ALLOCATE) && (Len(cleanup) != 0); - if (need_cleanup) { - Printv(f->code, cleanup, NIL); - } - - - /* Look for any remaining cleanup. This processes the %new directive */ - if (current != CONSTRUCTOR_ALLOCATE && GetFlag(n, "feature:new")) { - tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0); - if (tm) { - Printv(f->code, tm, "\n", NIL); - Delete(tm); - } - } - - /* Special processing on return value. */ - tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0); - if (tm) { - Printv(f->code, tm, NIL); - Delete(tm); - } - - if (director_method) { - if ((tm = Swig_typemap_lookup("directorfree", n, Swig_cresult_name(), 0))) { - Replaceall(tm, "$input", Swig_cresult_name()); - Replaceall(tm, "$result", "vresult"); - Printf(f->code, "%s\n", tm); - } - } - - - /* Wrap things up (in a manner of speaking) */ - if (need_result) { - if (current == CONSTRUCTOR_ALLOCATE) { - Printv(f->code, tab4, "return vresult;\n", NIL); - } else if (current == CONSTRUCTOR_INITIALIZE) { - Printv(f->code, tab4, "return self;\n", NIL); - Printv(f->code, "fail:\n", NIL); - if (need_cleanup) { - Printv(f->code, cleanup, NIL); - } - Printv(f->code, tab4, "return Qnil;\n", NIL); - } else { - Wrapper_add_local(f, "vresult", "VALUE vresult = Qnil"); - Printv(f->code, tab4, "return vresult;\n", NIL); - Printv(f->code, "fail:\n", NIL); - if (need_cleanup) { - Printv(f->code, cleanup, NIL); - } - Printv(f->code, tab4, "return Qnil;\n", NIL); - } - } else { - Printv(f->code, tab4, "return Qnil;\n", NIL); - Printv(f->code, "fail:\n", NIL); - if (need_cleanup) { - Printv(f->code, cleanup, NIL); - } - Printv(f->code, tab4, "return Qnil;\n", NIL); - } - - Printf(f->code, "}\n"); - - /* Substitute the cleanup code */ - Replaceall(f->code, "$cleanup", cleanup); - - /* Substitute the function name */ - Replaceall(f->code, "$symname", symname); - - /* Emit the function */ - Wrapper_print(f, f_wrappers); - - /* Now register the function with the interpreter */ - if (!Swig_symbol_isoverloaded(n)) { - create_command(n, symname); - } else { - if (current == CONSTRUCTOR_ALLOCATE) { - create_command(n, symname); - } else { - if (!Getattr(n, "sym:nextSibling")) - dispatchFunction(n); - } - } - - Delete(kwargs); - Delete(cleanup); - Delete(outarg); - DelWrapper(f); - Delete(symname); - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * dispatchFunction() - * ------------------------------------------------------------ */ - - void dispatchFunction(Node *n) { - /* Last node in overloaded chain */ - - int maxargs; - String *tmp = NewString(""); - String *dispatch = Swig_overload_dispatch(n, "return %s(nargs, args, self);", &maxargs); - - /* Generate a dispatch wrapper for all overloaded functions */ - - Wrapper *f = NewWrapper(); - String *symname = Getattr(n, "sym:name"); - String *wname = Swig_name_wrapper(symname); - - Printv(f->def, "SWIGINTERN VALUE ", wname, "(int nargs, VALUE *args, VALUE self) {", NIL); - - Wrapper_add_local(f, "argc", "int argc"); - bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n)); - if (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) { - Printf(tmp, "VALUE argv[%d]", maxargs + 1); - } else { - Printf(tmp, "VALUE argv[%d]", maxargs); - } - Wrapper_add_local(f, "argv", tmp); - Wrapper_add_local(f, "ii", "int ii"); - - if (current == MEMBER_FUNC || current == MEMBER_VAR || ctor_director) { - maxargs += 1; - Printf(f->code, "argc = nargs + 1;\n"); - Printf(f->code, "argv[0] = self;\n"); - Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs); - Printf(f->code, "for (ii = 1; (ii < argc); ++ii) {\n"); - Printf(f->code, "argv[ii] = args[ii-1];\n"); - Printf(f->code, "}\n"); - } else { - Printf(f->code, "argc = nargs;\n"); - Printf(f->code, "if (argc > %d) SWIG_fail;\n", maxargs); - Printf(f->code, "for (ii = 0; (ii < argc); ++ii) {\n"); - Printf(f->code, "argv[ii] = args[ii];\n"); - Printf(f->code, "}\n"); - } - - Replaceall(dispatch, "$args", "nargs, args, self"); - Printv(f->code, dispatch, "\n", NIL); - - - - // Generate prototype list, go to first node - Node *sibl = n; - - while (Getattr(sibl, "sym:previousSibling")) - sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up - - // Constructors will be treated specially - const bool isCtor = (!Cmp(Getattr(sibl, "nodeType"), "constructor")); - const bool isMethod = ( Cmp(Getattr(sibl, "ismember"), "1") == 0 && - (!isCtor) ); - - // Construct real method name - String* methodName = NewString(""); - if ( isMethod ) { - // Sometimes a method node has no parent (SF#3034054). - // This value is used in an exception message, so just skip the class - // name in this case so at least we don't segfault. This is probably - // just working around a problem elsewhere though. - Node *parent_node = parentNode(sibl); - if (parent_node) - Printv( methodName, Getattr(parent_node,"sym:name"), ".", NIL ); - } - Append( methodName, Getattr(sibl,"sym:name" ) ); - if ( isCtor ) Append( methodName, ".new" ); - - // Generate prototype list - String *protoTypes = NewString(""); - do { - Append( protoTypes, "\n\" "); - if (!isCtor) { - SwigType *type = SwigType_str(Getattr(sibl, "type"), NULL); - Printv(protoTypes, type, " ", NIL); - Delete(type); - } - Printv(protoTypes, methodName, NIL ); - Parm* p = Getattr(sibl, "wrap:parms"); - if (p && (current == MEMBER_FUNC || current == MEMBER_VAR || - ctor_director) ) - p = nextSibling(p); // skip self - Append( protoTypes, "(" ); - while(p) - { - Append( protoTypes, SwigType_str(Getattr(p,"type"), Getattr(p,"name")) ); - if ( ( p = nextSibling(p)) ) Append(protoTypes, ", "); - } - Append( protoTypes, ")\\n\"" ); - } while ((sibl = Getattr(sibl, "sym:nextSibling"))); - - Append(f->code, "fail:\n"); - Printf(f->code, "Ruby_Format_OverloadedError( argc, %d, \"%s\", %s);\n", - maxargs, methodName, protoTypes); - Append(f->code, "\nreturn Qnil;\n"); - - Delete(methodName); - Delete(protoTypes); - - Printv(f->code, "}\n", NIL); - Wrapper_print(f, f_wrappers); - create_command(n, Char(symname)); - - DelWrapper(f); - Delete(dispatch); - Delete(tmp); - Delete(wname); - } - - /* --------------------------------------------------------------------- - * variableWrapper() - * --------------------------------------------------------------------- */ - - virtual int variableWrapper(Node *n) { - String* docs = docstring(n, AUTODOC_GETTER); - Printf(f_wrappers, "%s", docs); - Delete(docs); - - - char *name = GetChar(n, "name"); - char *iname = GetChar(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - String *tm; - String *getfname, *setfname; - Wrapper *getf, *setf; - const int assignable = is_assignable(n); - - // Determine whether virtual global variables shall be used - // which have different getter and setter signatures, - // see https://docs.ruby-lang.org/en/2.6.0/extension_rdoc.html#label-Global+Variables+Shared+Between+C+and+Ruby - const bool use_virtual_var = (current == NO_CPP && useGlobalModule); - - getf = NewWrapper(); - setf = NewWrapper(); - - /* create getter */ - int addfail = 0; - String *getname = Swig_name_get(NSPACE_TODO, iname); - getfname = Swig_name_wrapper(getname); - Setattr(n, "wrap:name", getfname); - Printv(getf->def, "SWIGINTERN VALUE\n", getfname, "(", NIL); - Printf(getf->def, (use_virtual_var) ? "ID id, VALUE *data" : "VALUE self"); - Printf(getf->def, ") {"); - Wrapper_add_local(getf, "_val", "VALUE _val"); - - tm = Swig_typemap_lookup("varout", n, name, 0); - if (tm) { - Replaceall(tm, "$result", "_val"); - /* Printv(getf->code,tm, NIL); */ - addfail = emit_action_code(n, getf->code, tm); - } else { - Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0)); - } - Printv(getf->code, tab4, "return _val;\n", NIL); - if (addfail) { - Append(getf->code, "fail:\n"); - Append(getf->code, " return Qnil;\n"); - } - Append(getf->code, "}\n"); - - Wrapper_print(getf, f_wrappers); - - if (!assignable) { - setfname = NewString("(rb_gvar_setter_t *)NULL"); - } else { - /* create setter */ - String* docs = docstring(n, AUTODOC_SETTER); - Printf(f_wrappers, "%s", docs); - Delete(docs); - - String *setname = Swig_name_set(NSPACE_TODO, iname); - setfname = Swig_name_wrapper(setname); - Setattr(n, "wrap:name", setfname); - Printf(setf->def, "SWIGINTERN "); - if (use_virtual_var) { - Printv(setf->def, "void\n", setfname, "(VALUE _val, ID id, VALUE *data) {", NIL); - } else { - Printv(setf->def, "VALUE\n", setfname, "(VALUE self, VALUE _val) {", NIL); - } - tm = Swig_typemap_lookup("varin", n, name, 0); - if (tm) { - Replaceall(tm, "$input", "_val"); - /* Printv(setf->code,tm,"\n",NIL); */ - emit_action_code(n, setf->code, tm); - } else { - Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s\n", SwigType_str(t, 0)); - } - if (use_virtual_var) { - Printf(setf->code, "fail:\n"); - Printv(setf->code, tab4, "return;\n", NIL); - } else { - Printv(setf->code, tab4, "return _val;\n", NIL); - Printf(setf->code, "fail:\n"); - Printv(setf->code, tab4, "return Qnil;\n", NIL); - } - Printf(setf->code, "}\n"); - Wrapper_print(setf, f_wrappers); - Delete(setname); - } - - /* define accessor methods */ - Insert(getfname, 0, "VALUEFUNC("); - Append(getfname, ")"); - Insert(setfname, 0, (use_virtual_var) ? "SWIG_RUBY_VOID_ANYARGS_FUNC(" : "VALUEFUNC("); - Append(setfname, ")"); - - String *s = NewString(""); - switch (current) { - case STATIC_VAR: - /* C++ class variable */ - Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "\", ", getfname, ", 0);\n", NIL); - if (assignable) { - Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "=\", ", setfname, ", 1);\n", NIL); - } - Printv(klass->init, s, NIL); - break; - default: - /* C global variable */ - /* wrapped in Ruby module attribute */ - assert(current == NO_CPP); - if (!useGlobalModule) { - Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "\", ", getfname, ", 0);\n", NIL); - if (assignable) { - Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "=\", ", setfname, ", 1);\n", NIL); - } - } else { - Printv(s, tab4, "rb_define_virtual_variable(\"$", iname, "\", ", getfname, ", ", setfname, ");\n", NIL); - } - Printv(f_init, s, NIL); - Delete(s); - break; - } - Delete(getname); - Delete(getfname); - Delete(setfname); - DelWrapper(setf); - DelWrapper(getf); - return SWIG_OK; - } - - - /* --------------------------------------------------------------------- - * validate_const_name(char *name) - * - * Validate constant name. - * --------------------------------------------------------------------- */ - - char *validate_const_name(char *name, const char *reason) { - if (!name || name[0] == '\0') - return name; - - if (isupper(name[0])) - return name; - - if (islower(name[0])) { - name[0] = (char)toupper(name[0]); - Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number, "Wrong %s name (corrected to `%s')\n", reason, name); - return name; - } - - Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number, "Wrong %s name %s\n", reason, name); - - return name; - } - - /* --------------------------------------------------------------------- - * constantWrapper() - * --------------------------------------------------------------------- */ - - virtual int constantWrapper(Node *n) { - Swig_require("constantWrapper", n, "*sym:name", "type", "value", NIL); - - char *iname = GetChar(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - String *rawval = Getattr(n, "rawval"); - String *value = rawval ? rawval : Getattr(n, "value"); - - if (current == CLASS_CONST) { - iname = klass->strip(iname); - } - validate_const_name(iname, "constant"); - SetChar(n, "sym:name", iname); - - /* Special hook for member pointer */ - if (SwigType_type(type) == T_MPOINTER) { - String *wname = Swig_name_wrapper(iname); - Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value); - value = Char(wname); - } - String *tm = Swig_typemap_lookup("constant", n, value, 0); - if (!tm) - tm = Swig_typemap_lookup("constcode", n, value, 0); - if (tm) { - Replaceall(tm, "$symname", iname); - Replaceall(tm, "$value", value); - if (current == CLASS_CONST) { - if (multipleInheritance) { - Replaceall(tm, "$module", klass->mImpl); - Printv(klass->init, tm, "\n", NIL); - } else { - Replaceall(tm, "$module", klass->vname); - Printv(klass->init, tm, "\n", NIL); - } - } else { - if (!useGlobalModule) { - Replaceall(tm, "$module", modvar); - } else { - Replaceall(tm, "$module", "rb_cObject"); - } - Printf(f_init, "%s\n", tm); - } - } else { - Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value); - } - Swig_restore(n); - return SWIG_OK; - } - - /* ----------------------------------------------------------------------------- - * classDeclaration() - * - * Records information about classes---even classes that might be defined in - * other modules referenced by %import. - * ----------------------------------------------------------------------------- */ - - virtual int classDeclaration(Node *n) { - if (!Getattr(n, "feature:onlychildren")) { - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - - String *namestr = SwigType_namestr(name); - klass = RCLASS(classes, Char(namestr)); - if (!klass) { - klass = new RClass(); - String *valid_name = NewString(symname ? symname : namestr); - validate_const_name(Char(valid_name), "class"); - klass->set_name(namestr, symname, valid_name); - SET_RCLASS(classes, Char(namestr), klass); - Delete(valid_name); - } - Delete(namestr); - } - return Language::classDeclaration(n); - } - - /** - * Process the comma-separated list of mixed-in module names (if any). - */ - void includeRubyModules(Node *n) { - String *mixin = Getattr(n, "feature:mixin"); - if (mixin) { - List *modules = Split(mixin, ',', INT_MAX); - if (modules && Len(modules) > 0) { - Iterator mod = First(modules); - while (mod.item) { - if (Len(mod.item) > 0) { - Printf(klass->init, "rb_include_module(%s, rb_eval_string(\"%s\"));\n", klass->vname, mod.item); - } - mod = Next(mod); - } - } - Delete(modules); - } - } - - void handleBaseClasses(Node *n) { - List *baselist = Getattr(n, "bases"); - if (baselist && Len(baselist)) { - Iterator base = First(baselist); - while (base.item && GetFlag(base.item, "feature:ignore")) { - base = Next(base); - } - while (base.item) { - String *basename = Getattr(base.item, "name"); - String *basenamestr = SwigType_namestr(basename); - RClass *super = RCLASS(classes, Char(basenamestr)); - Delete(basenamestr); - if (super) { - SwigType *btype = NewString(basename); - SwigType_add_pointer(btype); - SwigType_remember(btype); - SwigType *smart = Swig_cparse_smartptr(base.item); - if (smart) { - SwigType_add_pointer(smart); - SwigType_remember(smart); - } - String *bmangle = SwigType_manglestr(smart ? smart : btype); - if (multipleInheritance) { - Insert(bmangle, 0, "((swig_class *) SWIGTYPE"); - Append(bmangle, "->clientdata)->mImpl"); - Printv(klass->init, "rb_include_module(", klass->mImpl, ", ", bmangle, ");\n", NIL); - } else { - Insert(bmangle, 0, "((swig_class *) SWIGTYPE"); - Append(bmangle, "->clientdata)->klass"); - Replaceall(klass->init, "$super", bmangle); - } - Delete(bmangle); - Delete(smart); - Delete(btype); - } - base = Next(base); - while (base.item && GetFlag(base.item, "feature:ignore")) { - base = Next(base); - } - if (!multipleInheritance) { - /* Warn about multiple inheritance for additional base class(es) */ - while (base.item) { - if (GetFlag(base.item, "feature:ignore")) { - base = Next(base); - continue; - } - String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0); - String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0); - Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, Getfile(n), Getline(n), - "Warning for %s, base %s ignored. Multiple inheritance is not supported in Ruby.\n", proxyclassname, baseclassname); - base = Next(base); - } - } - } - } - } - - /** - * Check to see if a %markfunc was specified. - */ - void handleMarkFuncDirective(Node *n) { - String *markfunc = Getattr(n, "feature:markfunc"); - if (markfunc) { - Printf(klass->init, "SwigClass%s.mark = (void (*)(void *)) %s;\n", klass->name, markfunc); - } else { - Printf(klass->init, "SwigClass%s.mark = 0;\n", klass->name); - } - } - - /** - * Check to see if a %freefunc was specified. - */ - void handleFreeFuncDirective(Node *n) { - String *freefunc = Getattr(n, "feature:freefunc"); - if (freefunc) { - Printf(klass->init, "SwigClass%s.destroy = (void (*)(void *)) %s;\n", klass->name, freefunc); - } else { - if (klass->destructor_defined) { - Printf(klass->init, "SwigClass%s.destroy = (void (*)(void *)) free_%s;\n", klass->name, klass->mname); - } - } - } - - /** - * Check to see if tracking is enabled for this class. - */ - void handleTrackDirective(Node *n) { - int trackObjects = GetFlag(n, "feature:trackobjects"); - if (trackObjects) { - Printf(klass->init, "SwigClass%s.trackObjects = 1;\n", klass->name); - } else { - Printf(klass->init, "SwigClass%s.trackObjects = 0;\n", klass->name); - } - } - - /* ---------------------------------------------------------------------- - * classHandler() - * ---------------------------------------------------------------------- */ - - virtual int classHandler(Node *n) { - String* docs = docstring(n, AUTODOC_CLASS); - Printf(f_wrappers, "%s", docs); - Delete(docs); - - String *name = Getattr(n, "name"); - String *symname = Getattr(n, "sym:name"); - String *namestr = SwigType_namestr(name); // does template expansion - - klass = RCLASS(classes, Char(namestr)); - assert(klass != 0); - Delete(namestr); - String *valid_name = NewString(symname); - validate_const_name(Char(valid_name), "class"); - - Clear(klass->type); - Printv(klass->type, Getattr(n, "classtype"), NIL); - Printv(f_wrappers, "static swig_class SwigClass", valid_name, ";\n\n", NIL); - Printv(klass->init, "\n", tab4, NIL); - - if (!useGlobalModule) { - Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar, ", \"", klass->name, "\", $super);\n", NIL); - } else { - Printv(klass->init, klass->vname, " = rb_define_class(\"", klass->name, - "\", $super);\n", NIL); - } - - if (multipleInheritance) { - Printv(klass->init, klass->mImpl, " = rb_define_module_under(", klass->vname, ", \"Impl\");\n", NIL); - } - - SwigType *tt = NewString(name); - SwigType_add_pointer(tt); - SwigType_remember(tt); - SwigType *smart = Swig_cparse_smartptr(n); - if (smart) { - SwigType_add_pointer(smart); - SwigType_remember(smart); - } - String *tm = SwigType_manglestr(smart ? smart : tt); - Printf(klass->init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) &SwigClass%s);\n", tm, valid_name); - Delete(tm); - Delete(smart); - Delete(tt); - Delete(valid_name); - - includeRubyModules(n); - - Printv(klass->init, "$allocator", NIL); - Printv(klass->init, "$initializer", NIL); - - Language::classHandler(n); - - handleBaseClasses(n); - handleMarkFuncDirective(n); - handleFreeFuncDirective(n); - handleTrackDirective(n); - - if (multipleInheritance) { - Printv(klass->init, "rb_include_module(", klass->vname, ", ", klass->mImpl, ");\n", NIL); - } - - String *s = NewString(""); - Printv(s, tab4, "rb_undef_alloc_func(", klass->vname, ");\n", NIL); - Replaceall(klass->init, "$allocator", s); - Replaceall(klass->init, "$initializer", ""); - - if (GetFlag(n, "feature:exceptionclass")) { - Replaceall(klass->init, "$super", "rb_eRuntimeError"); - } else { - Replaceall(klass->init, "$super", "rb_cObject"); - } - Delete(s); - - Printv(f_init, klass->init, NIL); - klass = 0; - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * memberfunctionHandler() - * - * Method for adding C++ member function - * - * By default, we're going to create a function of the form : - * - * Foo_bar(this,args) - * - * Where Foo is the classname, bar is the member name and the this pointer - * is explicitly attached to the beginning. - * - * The renaming only applies to the member function part, not the full - * classname. - * - * --------------------------------------------------------------------- */ - - virtual int memberfunctionHandler(Node *n) { - current = MEMBER_FUNC; - - String* docs = docstring(n, AUTODOC_METHOD); - Printf(f_wrappers, "%s", docs); - Delete(docs); - - Language::memberfunctionHandler(n); - current = NO_CPP; - return SWIG_OK; - } - - /* --------------------------------------------------------------------- - * constructorHandler() - * - * Method for adding C++ member constructor - * -------------------------------------------------------------------- */ - - void set_director_ctor_code(Node *n) { - /* director ctor code is specific for each class */ - Delete(director_prot_ctor_code); - director_prot_ctor_code = NewString(""); - Node *pn = Swig_methodclass(n); - String *symname = Getattr(pn, "sym:name"); - String *name = Copy(symname); - char *cname = Char(name); - if (cname) - cname[0] = (char)toupper(cname[0]); - Printv(director_prot_ctor_code, - "if ( $comparison ) { /* subclassed */\n", - " $director_new \n", - "} else {\n", " rb_raise(rb_eNameError,\"accessing abstract class or protected constructor\"); \n", " return Qnil;\n", "}\n", NIL); - Delete(director_ctor_code); - director_ctor_code = NewString(""); - Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", " $director_new \n", "} else {\n", " $nondirector_new \n", "}\n", NIL); - Delete(name); - } - - virtual int constructorHandler(Node *n) { - int use_director = Swig_directorclass(n); - if (use_director) { - set_director_ctor_code(n); - } - - /* First wrap the allocate method */ - current = CONSTRUCTOR_ALLOCATE; - Swig_name_register("construct", "%n%c_allocate"); - - Language::constructorHandler(n); - - String* docs = docstring(n, AUTODOC_CTOR); - Printf(f_wrappers, "%s", docs); - Delete(docs); - - /* - * If we're wrapping the constructor of a C++ director class, prepend a new parameter - * to receive the scripting language object (e.g. 'self') - * - */ - Swig_save("ruby:constructorHandler", n, "parms", NIL); - if (use_director) { - Parm *parms = Getattr(n, "parms"); - Parm *self; - String *name = NewString("self"); - String *type = NewString("VALUE"); - self = NewParm(type, name, n); - Delete(type); - Delete(name); - Setattr(self, "lname", "Qnil"); - if (parms) - set_nextSibling(self, parms); - Setattr(n, "parms", self); - Setattr(n, "wrap:self", "1"); - Delete(self); - } - - /* Now do the instance initialize method */ - current = CONSTRUCTOR_INITIALIZE; - Swig_name_register("construct", "new_%n%c"); - Language::constructorHandler(n); - - /* Restore original parameter list */ - Delattr(n, "wrap:self"); - Swig_restore(n); - - /* Done */ - Swig_name_unregister("construct"); - current = NO_CPP; - klass->constructor_defined = 1; - return SWIG_OK; - } - - virtual int copyconstructorHandler(Node *n) { - int use_director = Swig_directorclass(n); - if (use_director) { - set_director_ctor_code(n); - } - - /* First wrap the allocate method */ - current = CONSTRUCTOR_ALLOCATE; - Swig_name_register("construct", "%n%c_allocate"); - - return Language::copyconstructorHandler(n); - } - - - /* --------------------------------------------------------------------- - * destructorHandler() - * -------------------------------------------------------------------- */ - - virtual int destructorHandler(Node *n) { - - /* Do no spit free function if user defined his own for this class */ - Node *pn = Swig_methodclass(n); - String *freefunc = Getattr(pn, "feature:freefunc"); - if (freefunc) return SWIG_OK; - - current = DESTRUCTOR; - Language::destructorHandler(n); - - freefunc = NewString(""); - String *freebody = NewString(""); - String *pname0 = Swig_cparm_name(0, 0); - - Printv(freefunc, "free_", klass->mname, NIL); - Printv(freebody, "SWIGINTERN void\n", freefunc, "(void *self) {\n", NIL); - Printv(freebody, tab4, klass->type, " *", pname0, " = (", klass->type, " *)self;\n", NIL); - Printv(freebody, tab4, NIL); - - /* Check to see if object tracking is activated for the class - that owns this destructor. */ - if (GetFlag(pn, "feature:trackobjects")) { - Printf(freebody, "SWIG_RubyRemoveTracking(%s);\n", pname0); - Printv(freebody, tab4, NIL); - } - - if (Extend) { - String *wrap = Getattr(n, "wrap:code"); - if (wrap) { - Printv(f_wrappers, wrap, NIL); - } - /* Printv(freebody, Swig_name_destroy(name), "(", pname0, ")", NIL); */ - Printv(freebody, Getattr(n, "wrap:action"), "\n", NIL); - } else { - String *action = Getattr(n, "wrap:action"); - if (action) { - Printv(freebody, action, "\n", NIL); - } else { - /* In the case swig emits no destroy function. */ - if (CPlusPlus) - Printf(freebody, "delete %s;\n", pname0); - else - Printf(freebody, "free((char*) %s);\n", pname0); - } - } - - Printv(freebody, "}\n\n", NIL); - - Printv(f_wrappers, freebody, NIL); - - klass->destructor_defined = 1; - current = NO_CPP; - Delete(freefunc); - Delete(freebody); - Delete(pname0); - return SWIG_OK; - } - - /* --------------------------------------------------------------------- - * membervariableHandler() - * - * This creates a pair of functions to set/get the variable of a member. - * -------------------------------------------------------------------- */ - - virtual int membervariableHandler(Node *n) { - String* docs = docstring(n, AUTODOC_GETTER); - Printf(f_wrappers, "%s", docs); - Delete(docs); - - if (is_assignable(n)) { - String* docs = docstring(n, AUTODOC_SETTER); - Printf(f_wrappers, "%s", docs); - Delete(docs); - } - - current = MEMBER_VAR; - Language::membervariableHandler(n); - current = NO_CPP; - return SWIG_OK; - } - - /* ----------------------------------------------------------------------- - * staticmemberfunctionHandler() - * - * Wrap a static C++ function - * ---------------------------------------------------------------------- */ - - virtual int staticmemberfunctionHandler(Node *n) { - String* docs = docstring(n, AUTODOC_STATICFUNC); - Printf(f_wrappers, "%s", docs); - Delete(docs); - - current = STATIC_FUNC; - Language::staticmemberfunctionHandler(n); - current = NO_CPP; - return SWIG_OK; - } - - /* ---------------------------------------------------------------------- - * memberconstantHandler() - * - * Create a C++ constant - * --------------------------------------------------------------------- */ - - virtual int memberconstantHandler(Node *n) { - String* docs = docstring(n, AUTODOC_STATICFUNC); - Printf(f_wrappers, "%s", docs); - Delete(docs); - - current = CLASS_CONST; - Language::memberconstantHandler(n); - current = NO_CPP; - return SWIG_OK; - } - - /* --------------------------------------------------------------------- - * staticmembervariableHandler() - * --------------------------------------------------------------------- */ - - virtual int staticmembervariableHandler(Node *n) { - String* docs = docstring(n, AUTODOC_GETTER); - Printf(f_wrappers, "%s", docs); - Delete(docs); - - if (is_assignable(n)) { - String* docs = docstring(n, AUTODOC_SETTER); - Printf(f_wrappers, "%s", docs); - Delete(docs); - } - - current = STATIC_VAR; - Language::staticmembervariableHandler(n); - current = NO_CPP; - return SWIG_OK; - } - - /* C++ director class generation */ - virtual int classDirector(Node *n) { - return Language::classDirector(n); - } - - virtual int classDirectorInit(Node *n) { - String *declaration; - declaration = Swig_director_declaration(n); - Printf(f_directors_h, "\n"); - Printf(f_directors_h, "%s\n", declaration); - Printf(f_directors_h, "public:\n"); - Delete(declaration); - return Language::classDirectorInit(n); - } - - virtual int classDirectorEnd(Node *n) { - Printf(f_directors_h, "};\n\n"); - return Language::classDirectorEnd(n); - } - - /* ------------------------------------------------------------ - * classDirectorConstructor() - * ------------------------------------------------------------ */ - - virtual int classDirectorConstructor(Node *n) { - Node *parent = Getattr(n, "parentNode"); - String *sub = NewString(""); - String *decl = Getattr(n, "decl"); - String *supername = Swig_class_name(parent); - String *classname = NewString(""); - Printf(classname, "SwigDirector_%s", supername); - - /* insert self parameter */ - Parm *p; - ParmList *superparms = Getattr(n, "parms"); - ParmList *parms = CopyParmList(superparms); - String *type = NewString("VALUE"); - p = NewParm(type, NewString("self"), n); - set_nextSibling(p, parms); - parms = p; - - if (!Getattr(n, "defaultargs")) { - /* constructor */ - { - Wrapper *w = NewWrapper(); - String *call; - String *basetype = Getattr(parent, "classtype"); - String *target = Swig_method_decl(0, decl, classname, parms, 0); - call = Swig_csuperclass_call(0, basetype, superparms); - Printf(w->def, "%s::%s: %s, Swig::Director(self) { }", classname, target, call); - Delete(target); - Wrapper_print(w, f_directors); - Delete(call); - DelWrapper(w); - } - - /* constructor header */ - { - String *target = Swig_method_decl(0, decl, classname, parms, 1); - Printf(f_directors_h, " %s;\n", target); - Delete(target); - } - } - - Delete(sub); - Delete(classname); - Delete(supername); - Delete(parms); - return Language::classDirectorConstructor(n); - } - - /* ------------------------------------------------------------ - * classDirectorDefaultConstructor() - * ------------------------------------------------------------ */ - - virtual int classDirectorDefaultConstructor(Node *n) { - String *classname; - Wrapper *w; - classname = Swig_class_name(n); - w = NewWrapper(); - Printf(w->def, "SwigDirector_%s::SwigDirector_%s(VALUE self) : Swig::Director(self) { }", classname, classname); - Wrapper_print(w, f_directors); - DelWrapper(w); - Printf(f_directors_h, " SwigDirector_%s(VALUE self);\n", classname); - Delete(classname); - return Language::classDirectorDefaultConstructor(n); - } - - /* --------------------------------------------------------------- - * exceptionSafeMethodCall() - * - * Emit a virtual director method to pass a method call on to the - * underlying Ruby instance. - * - * --------------------------------------------------------------- */ - - void exceptionSafeMethodCall(String *className, Node *n, Wrapper *w, int argc, String *args, bool initstack) { - Wrapper *body = NewWrapper(); - Wrapper *rescue = NewWrapper(); - - String *methodName = Getattr(n, "sym:name"); - - String *bodyName = NewStringf("%s_%s_body", className, methodName); - String *rescueName = NewStringf("%s_%s_rescue", className, methodName); - String *depthCountName = NewStringf("%s_%s_call_depth", className, methodName); - - // Check for an exception typemap of some kind - String *tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0); - if (!tm) { - tm = Getattr(n, "feature:director:except"); - } - - if ((tm != 0) && (Len(tm) > 0) && (Strcmp(tm, "1") != 0)) { - // Declare a global to hold the depth count - if (!Getattr(n, "sym:nextSibling")) { - Printf(body->def, "static int %s = 0;\n", depthCountName); - - // Function body - Printf(body->def, "VALUE %s(VALUE data) {\n", bodyName); - Wrapper_add_localv(body, "args", "Swig::body_args *", "args", "= reinterpret_cast<Swig::body_args *>(data)", NIL); - Wrapper_add_localv(body, Swig_cresult_name(), "VALUE", Swig_cresult_name(), "= Qnil", NIL); - Printf(body->code, "%s++;\n", depthCountName); - Printv(body->code, Swig_cresult_name(), " = rb_funcall2(args->recv, args->id, args->argc, args->argv);\n", NIL); - Printf(body->code, "%s--;\n", depthCountName); - Printv(body->code, "return ", Swig_cresult_name(), ";\n", NIL); - Printv(body->code, "}", NIL); - - // Exception handler - Printf(rescue->def, "VALUE %s(VALUE args, VALUE error) {\n", rescueName); - Replaceall(tm, "$error", "error"); - Printf(rescue->code, "%s--;\n", depthCountName); - Printf(rescue->code, "if (%s == 0) ", depthCountName); - Printv(rescue->code, Str(tm), "\n", NIL); - Printv(rescue->code, "rb_exc_raise(error);\n", NIL); - Printv(rescue->code, "return Qnil;\n", NIL); - Printv(rescue->code, "}", NIL); - } - - // Main code - Wrapper_add_localv(w, "args", "Swig::body_args", "args", NIL); - Wrapper_add_localv(w, "status", "int", "status", NIL); - Printv(w->code, "args.recv = swig_get_self();\n", NIL); - Printf(w->code, "args.id = rb_intern(\"%s\");\n", methodName); - Printf(w->code, "args.argc = %d;\n", argc); - if (argc > 0) { - Printf(w->code, "args.argv = new VALUE[%d];\n", argc); - for (int i = 0; i < argc; i++) { - Printf(w->code, "args.argv[%d] = obj%d;\n", i, i); - } - } else { - Printv(w->code, "args.argv = 0;\n", NIL); - } - Printf(w->code, "%s = rb_protect(PROTECTFUNC(%s), reinterpret_cast<VALUE>(&args), &status);\n", Swig_cresult_name(), bodyName); - if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n"); - Printf(w->code, "if (status) {\n"); - Printf(w->code, "VALUE lastErr = rb_gv_get(\"$!\");\n"); - Printf(w->code, "%s(reinterpret_cast<VALUE>(&args), lastErr);\n", rescueName); - Printf(w->code, "}\n"); - if (argc > 0) { - Printv(w->code, "delete [] args.argv;\n", NIL); - } - // Dump wrapper code - Wrapper_print(body, f_directors_helpers); - Wrapper_print(rescue, f_directors_helpers); - } else { - if (argc > 0) { - Printf(w->code, "%s = rb_funcall(swig_get_self(), rb_intern(\"%s\"), %d%s);\n", Swig_cresult_name(), methodName, argc, args); - } else { - Printf(w->code, "%s = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, Qnil);\n", Swig_cresult_name(), methodName); - } - if ( initstack ) Printf(w->code, "SWIG_RELEASE_STACK;\n"); - } - - // Clean up - Delete(bodyName); - Delete(rescueName); - Delete(depthCountName); - DelWrapper(body); - DelWrapper(rescue); - } - - virtual int classDirectorMethod(Node *n, Node *parent, String *super) { - int is_void = 0; - int is_pointer = 0; - String *decl = Getattr(n, "decl"); - String *name = Getattr(n, "name"); - String *classname = Getattr(parent, "sym:name"); - String *c_classname = Getattr(parent, "name"); - String *symname = Getattr(n, "sym:name"); - String *declaration = NewString(""); - ParmList *l = Getattr(n, "parms"); - Wrapper *w = NewWrapper(); - String *tm; - String *wrap_args = NewString(""); - String *returntype = Getattr(n, "type"); - Parm *p; - String *value = Getattr(n, "value"); - String *storage = Getattr(n, "storage"); - bool pure_virtual = false; - int status = SWIG_OK; - int idx; - bool ignored_method = GetFlag(n, "feature:ignore") ? true : false; - bool asvoid = checkAttribute( n, "feature:numoutputs", "0") ? true : false; - bool initstack = checkAttribute( n, "feature:initstack", "1") ? true : false; - - if (Cmp(storage, "virtual") == 0) { - if (Cmp(value, "0") == 0) { - pure_virtual = true; - } - } - String *overnametmp = NewString(Getattr(n, "sym:name")); - if (Getattr(n, "sym:overloaded")) { - Printf(overnametmp, "::%s", Getattr(n, "sym:overname")); - } - - /* determine if the method returns a pointer */ - is_pointer = SwigType_ispointer_return(decl); - is_void = (!Cmp(returntype, "void") && !is_pointer); - - /* virtual method definition */ - String *target; - String *pclassname = NewStringf("SwigDirector_%s", classname); - String *qualified_name = NewStringf("%s::%s", pclassname, name); - SwigType *rtype = Getattr(n, "conversion_operator") ? 0 : Getattr(n, "classDirectorMethods:type"); - target = Swig_method_decl(rtype, decl, qualified_name, l, 0); - Printf(w->def, "%s", target); - Delete(qualified_name); - Delete(target); - /* header declaration */ - target = Swig_method_decl(rtype, decl, name, l, 1); - Printf(declaration, " virtual %s", target); - Delete(target); - - // Get any exception classes in the throws typemap - if (Getattr(n, "noexcept")) { - Append(w->def, " noexcept"); - Append(declaration, " noexcept"); - } - ParmList *throw_parm_list = 0; - - if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) { - Parm *p; - int gencomma = 0; - - Append(w->def, " throw("); - Append(declaration, " throw("); - - if (throw_parm_list) - Swig_typemap_attach_parms("throws", throw_parm_list, 0); - for (p = throw_parm_list; p; p = nextSibling(p)) { - if (Getattr(p, "tmap:throws")) { - if (gencomma++) { - Append(w->def, ", "); - Append(declaration, ", "); - } - - Printf(w->def, "%s", SwigType_str(Getattr(p, "type"), 0)); - Printf(declaration, "%s", SwigType_str(Getattr(p, "type"), 0)); - } - } - - Append(w->def, ")"); - Append(declaration, ")"); - } - - Append(w->def, " {"); - Append(declaration, ";\n"); - - if (initstack && !(ignored_method && !pure_virtual)) { - Append(w->def, "\nSWIG_INIT_STACK;\n"); - } - - /* declare method return value - * if the return value is a reference or const reference, a specialized typemap must - * handle it, including declaration of c_result ($result). - */ - if (!is_void && (!ignored_method || pure_virtual)) { - if (!SwigType_isclass(returntype)) { - if (!(SwigType_ispointer(returntype) || SwigType_isreference(returntype))) { - String *construct_result = NewStringf("= SwigValueInit< %s >()", SwigType_lstr(returntype, 0)); - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), construct_result, NIL); - Delete(construct_result); - } else { - Wrapper_add_localv(w, "c_result", SwigType_lstr(returntype, "c_result"), "= 0", NIL); - } - } else { - String *cres = SwigType_lstr(returntype, "c_result"); - Printf(w->code, "%s;\n", cres); - Delete(cres); - } - } - - if (ignored_method) { - if (!pure_virtual) { - if (!is_void) - Printf(w->code, "return "); - String *super_call = Swig_method_call(super, l); - Printf(w->code, "%s;\n", super_call); - Delete(super_call); - } else { - Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname), - SwigType_namestr(name)); - } - } else { - /* attach typemaps to arguments (C/C++ -> Ruby) */ - String *arglist = NewString(""); - - Swig_director_parms_fixup(l); - - Swig_typemap_attach_parms("in", l, 0); - Swig_typemap_attach_parms("directorin", l, w); - Swig_typemap_attach_parms("directorargout", l, w); - - char source[256]; - - int outputs = 0; - if (!is_void && !asvoid) - outputs++; - - /* build argument list and type conversion string */ - idx = 0; p = l; - while ( p ) { - - if (Getattr(p, "tmap:ignore")) { - p = Getattr(p, "tmap:ignore:next"); - continue; - } - - if (Getattr(p, "tmap:directorargout") != 0) - outputs++; - - if ( checkAttribute( p, "tmap:in:numinputs", "0") ) { - p = Getattr(p, "tmap:in:next"); - continue; - } - - String *parameterName = Getattr(p, "name"); - String *parameterType = Getattr(p, "type"); - - Putc(',', arglist); - if ((tm = Getattr(p, "tmap:directorin")) != 0) { - sprintf(source, "obj%d", idx++); - String *input = NewString(source); - Setattr(p, "emit:directorinput", input); - Replaceall(tm, "$input", input); - Replaceall(tm, "$owner", "0"); - Delete(input); - Printv(wrap_args, tm, "\n", NIL); - Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL); - Printv(arglist, source, NIL); - p = Getattr(p, "tmap:directorin:next"); - continue; - } else if (Cmp(parameterType, "void")) { - /** - * Special handling for pointers to other C++ director classes. - * Ideally this would be left to a typemap, but there is currently no - * way to selectively apply the dynamic_cast<> to classes that have - * directors. In other words, the type "SwigDirector_$1_lname" only exists - * for classes with directors. We avoid the problem here by checking - * module.wrap::directormap, but it's not clear how to get a typemap to - * do something similar. Perhaps a new default typemap (in addition - * to SWIGTYPE) called DIRECTORTYPE? - */ - if (SwigType_ispointer(parameterType) || SwigType_isreference(parameterType)) { - Node *modname = Getattr(parent, "module"); - Node *target = Swig_directormap(modname, parameterType); - sprintf(source, "obj%d", idx++); - String *nonconst = 0; - /* strip pointer/reference --- should move to Swig/stype.c */ - String *nptype = NewString(Char(parameterType) + 2); - /* name as pointer */ - String *ppname = Copy(parameterName); - if (SwigType_isreference(parameterType)) { - Insert(ppname, 0, "&"); - } - /* if necessary, cast away const since Ruby doesn't support it! */ - if (SwigType_isconst(nptype)) { - nonconst = NewStringf("nc_tmp_%s", parameterName); - String *nonconst_i = NewStringf("= const_cast< %s >(%s)", SwigType_lstr(parameterType, 0), ppname); - Wrapper_add_localv(w, nonconst, SwigType_lstr(parameterType, 0), nonconst, nonconst_i, NIL); - Delete(nonconst_i); - Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number, - "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(parameterType, parameterName), - SwigType_namestr(c_classname), SwigType_namestr(name)); - } else { - nonconst = Copy(ppname); - } - Delete(nptype); - Delete(ppname); - String *mangle = SwigType_manglestr(parameterType); - if (target) { - String *director = NewStringf("director_%s", mangle); - Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL); - Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL); - Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst); - Printf(wrap_args, "if (!%s) {\n", director); - Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); - Printf(wrap_args, "} else {\n"); - Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director); - Printf(wrap_args, "}\n"); - Delete(director); - Printv(arglist, source, NIL); - } else { - Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL); - Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); - //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n", - // source, nonconst, base); - Printv(arglist, source, NIL); - } - Delete(mangle); - Delete(nonconst); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, - "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(parameterType, 0), - SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_NOWRAP; - break; - } - } - p = nextSibling(p); - } - - /* declare Ruby return value */ - String *value_result = NewStringf("VALUE SWIGUNUSED %s", Swig_cresult_name()); - Wrapper_add_local(w, Swig_cresult_name(), value_result); - Delete(value_result); - - /* wrap complex arguments to VALUEs */ - Printv(w->code, wrap_args, NIL); - - /* pass the method call on to the Ruby object */ - exceptionSafeMethodCall(classname, n, w, idx, arglist, initstack); - - /* - * Ruby method may return a simple object, or an Array of objects. - * For in/out arguments, we have to extract the appropriate VALUEs from the Array, - * then marshal everything back to C/C++ (return value and output arguments). - */ - - /* Marshal return value and other outputs (if any) from VALUE to C/C++ type */ - - String *cleanup = NewString(""); - String *outarg = NewString(""); - - if (outputs > 1) { - Wrapper_add_local(w, "output", "VALUE output"); - Printf(w->code, "if (TYPE(%s) != T_ARRAY) {\n", Swig_cresult_name()); - Printf(w->code, "Ruby_DirectorTypeMismatchException(\"Ruby method failed to return an array.\");\n"); - Printf(w->code, "}\n"); - } - - idx = 0; - - /* Marshal return value */ - if (!is_void) { - tm = Swig_typemap_lookup("directorout", n, Swig_cresult_name(), w); - if (tm != 0) { - if (outputs > 1 && !asvoid ) { - Printf(w->code, "output = rb_ary_entry(%s, %d);\n", Swig_cresult_name(), idx++); - Replaceall(tm, "$input", "output"); - } else { - Replaceall(tm, "$input", Swig_cresult_name()); - } - /* TODO check this */ - if (Getattr(n, "wrap:disown")) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - Replaceall(tm, "$result", "c_result"); - Printv(w->code, tm, "\n", NIL); - } else { - Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number, - "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0), - SwigType_namestr(c_classname), SwigType_namestr(name)); - status = SWIG_ERROR; - } - } - - /* Marshal outputs */ - for (p = l; p;) { - if ((tm = Getattr(p, "tmap:directorargout")) != 0) { - if (outputs > 1) { - Printf(w->code, "output = rb_ary_entry(%s, %d);\n", Swig_cresult_name(), idx++); - Replaceall(tm, "$result", "output"); - } else { - Replaceall(tm, "$result", Swig_cresult_name()); - } - Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); - Printv(w->code, tm, "\n", NIL); - p = Getattr(p, "tmap:directorargout:next"); - } else { - p = nextSibling(p); - } - } - - Delete(arglist); - Delete(cleanup); - Delete(outarg); - } - - /* any existing helper functions to handle this? */ - if (!is_void) { - if (!(ignored_method && !pure_virtual)) { - String *rettype = SwigType_str(returntype, 0); - if (!SwigType_isreference(returntype)) { - Printf(w->code, "return (%s) c_result;\n", rettype); - } else { - Printf(w->code, "return (%s) *c_result;\n", rettype); - } - Delete(rettype); - } - } - - Printf(w->code, "}\n"); - - // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method - String *inline_extra_method = NewString(""); - if (dirprot_mode() && !is_public(n) && !pure_virtual) { - Printv(inline_extra_method, declaration, NIL); - String *extra_method_name = NewStringf("%sSwigPublic", name); - Replaceall(inline_extra_method, name, extra_method_name); - Replaceall(inline_extra_method, ";\n", " {\n "); - if (!is_void) - Printf(inline_extra_method, "return "); - String *methodcall = Swig_method_call(super, l); - Printv(inline_extra_method, methodcall, ";\n }\n", NIL); - Delete(methodcall); - Delete(extra_method_name); - } - - /* emit the director method */ - if (status == SWIG_OK) { - if (!Getattr(n, "defaultargs")) { - Replaceall(w->code, "$symname", symname); - Wrapper_print(w, f_directors); - Printv(f_directors_h, declaration, NIL); - Printv(f_directors_h, inline_extra_method, NIL); - } - } - - /* clean up */ - Delete(wrap_args); - Delete(pclassname); - DelWrapper(w); - return status; - } - - virtual int classDirectorConstructors(Node *n) { - return Language::classDirectorConstructors(n); - } - - virtual int classDirectorMethods(Node *n) { - return Language::classDirectorMethods(n); - } - - virtual int classDirectorDisown(Node *n) { - return Language::classDirectorDisown(n); - } - - String *runtimeCode() { - String *s = NewString(""); - String *shead = Swig_include_sys("rubyhead.swg"); - if (!shead) { - Printf(stderr, "*** Unable to open 'rubyhead.swg'\n"); - } else { - Append(s, shead); - Delete(shead); - } - String *serrors = Swig_include_sys("rubyerrors.swg"); - if (!serrors) { - Printf(stderr, "*** Unable to open 'rubyerrors.swg'\n"); - } else { - Append(s, serrors); - Delete(serrors); - } - String *strack = Swig_include_sys("rubytracking.swg"); - if (!strack) { - Printf(stderr, "*** Unable to open 'rubytracking.swg'\n"); - } else { - Append(s, strack); - Delete(strack); - } - String *sapi = Swig_include_sys("rubyapi.swg"); - if (!sapi) { - Printf(stderr, "*** Unable to open 'rubyapi.swg'\n"); - } else { - Append(s, sapi); - Delete(sapi); - } - String *srun = Swig_include_sys("rubyrun.swg"); - if (!srun) { - Printf(stderr, "*** Unable to open 'rubyrun.swg'\n"); - } else { - Append(s, srun); - Delete(srun); - } - return s; - } - - String *defaultExternalRuntimeFilename() { - return NewString("swigrubyrun.h"); - } - - /*---------------------------------------------------------------------- - * kwargsSupport() - *--------------------------------------------------------------------*/ - - bool kwargsSupport() const { - // kwargs support isn't actually implemented, but changing to return false may break something now as it turns on compactdefaultargs - return true; - } -}; /* class RUBY */ - -/* ----------------------------------------------------------------------------- - * swig_ruby() - Instantiate module - * ----------------------------------------------------------------------------- */ - -static Language *new_swig_ruby() { - return new RUBY(); -} -extern "C" Language *swig_ruby(void) { - return new_swig_ruby(); -} - - -/* - * Local Variables: - * c-basic-offset: 2 - * End: - */ diff --git a/contrib/tools/swig/Source/Modules/scilab.cxx b/contrib/tools/swig/Source/Modules/scilab.cxx deleted file mode 100644 index aabd2d84260..00000000000 --- a/contrib/tools/swig/Source/Modules/scilab.cxx +++ /dev/null @@ -1,1167 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * scilab.cxx - * - * Scilab language module for SWIG. - * --------------------------------------------------------------------------*/ - -#include "swigmod.h" -#include <cstddef> -#include <cstdlib> - -static const int SCILAB_IDENTIFIER_NAME_CHAR_MAX = 24; - -static const char *usage = (char *) " \ -Scilab options (available with -scilab)\n \ - -builder - Generate a Scilab builder script\n \ - -buildercflags <cflags> - Add <cflags> to the builder compiler flags\n \ - -builderflagscript <file> - Set the Scilab script <file> to use by builder to configure the build flags\n \ - -builderldflags <ldflags> - Add <ldflags> to the builder linker flags\n \ - -buildersources <files> - Add the (comma separated) files <files> to the builder sources\n \ - -builderverbositylevel <level> - Set the builder verbosity level to <level> (default 0: off, 2: high)\n \ - -gatewayxml <gateway_id> - Generate gateway xml with the given <gateway_id>\n \ -\n"; - - -class SCILAB:public Language { -protected: - /* General objects used for holding the strings */ - File *beginSection; - File *runtimeSection; - File *headerSection; - File *wrappersSection; - File *initSection; - - String *variablesCode; - - bool generateBuilder; - File *builderFile; - String *builderCode; - String *builderCode5; - String *builderCode6; - int builderFunctionCount; - - List *sourceFileList; - List *cflags; - List *ldflags; - - String *verboseBuildLevel; - String *buildFlagsScript; - - String *gatewayHeader; - String *gatewayHeaderV5; - String *gatewayHeaderV6; - - bool createGatewayXML; - File *gatewayXMLFile; - String *gatewayXML; - String *gatewayID; - int primitiveID; - - bool createLoader; - File *loaderFile; - String *loaderScript; - String *loaderScript5; - String *loaderScript6; - int loaderFunctionCount; -public: - - /* ------------------------------------------------------------------------ - * main() - * ----------------------------------------------------------------------*/ - - virtual void main(int argc, char *argv[]) { - generateBuilder = false; - sourceFileList = NewList(); - cflags = NewList(); - ldflags = NewList(); - verboseBuildLevel = NULL; - buildFlagsScript = NULL; - - gatewayHeader = NULL; - gatewayHeaderV5 = NULL; - gatewayHeaderV6 = NULL; - - createGatewayXML = false; - gatewayXML = NULL; - gatewayXMLFile = NULL; - gatewayID = NULL; - - createLoader = true; - loaderFile = NULL; - loaderScript = NULL; - - /* Manage command line arguments */ - for (int argIndex = 1; argIndex < argc; argIndex++) { - if (argv[argIndex] != NULL) { - if (strcmp(argv[argIndex], "-help") == 0) { - Printf(stdout, "%s\n", usage); - } else if (strcmp(argv[argIndex], "-builder") == 0) { - Swig_mark_arg(argIndex); - generateBuilder = true; - createLoader = false; - } else if (strcmp(argv[argIndex], "-buildersources") == 0) { - if (argv[argIndex + 1] != NULL) { - Swig_mark_arg(argIndex); - char *sourceFile = strtok(argv[argIndex + 1], ","); - while (sourceFile != NULL) { - Insert(sourceFileList, Len(sourceFileList), sourceFile); - sourceFile = strtok(NULL, ","); - } - Swig_mark_arg(argIndex + 1); - } - } else if (strcmp(argv[argIndex], "-buildercflags") == 0) { - Swig_mark_arg(argIndex); - if (argv[argIndex + 1] != NULL) { - Insert(cflags, Len(cflags), argv[argIndex + 1]); - Swig_mark_arg(argIndex + 1); - } - } else if (strcmp(argv[argIndex], "-builderldflags") == 0) { - Swig_mark_arg(argIndex); - if (argv[argIndex + 1] != NULL) { - Insert(ldflags, Len(ldflags), argv[argIndex + 1]); - Swig_mark_arg(argIndex + 1); - } - } else if (strcmp(argv[argIndex], "-builderverbositylevel") == 0) { - Swig_mark_arg(argIndex); - verboseBuildLevel = NewString(argv[argIndex + 1]); - Swig_mark_arg(argIndex + 1); - } else if (strcmp(argv[argIndex], "-builderflagscript") == 0) { - Swig_mark_arg(argIndex); - buildFlagsScript = NewString(argv[argIndex + 1]); - Swig_mark_arg(argIndex + 1); - } else if (strcmp(argv[argIndex], "-gatewayxml") == 0) { - Swig_mark_arg(argIndex); - createGatewayXML = true; - gatewayID = NewString(argv[argIndex + 1]); - Swig_mark_arg(argIndex + 1); - } - } - } - - if (verboseBuildLevel == NULL) { - verboseBuildLevel = NewString("0"); - } - - /* Set language-specific subdirectory in SWIG library */ - SWIG_library_directory("scilab"); - - /* Add a symbol to the parser for conditional compilation */ - Preprocessor_define("SWIGSCILAB 1", 0); - - /* Set scilab configuration file */ - SWIG_config_file("scilab.swg"); - - /* Set typemap for scilab */ - SWIG_typemap_lang("scilab"); - - allow_overloading(); - } - - /* ------------------------------------------------------------------------ - * top() - * ----------------------------------------------------------------------*/ - - virtual int top(Node *node) { - - /* Get the module name */ - String *gatewayName = Getattr(node, "name"); - - // Set library name - String *gatewayLibraryName = NewStringf("lib%s", gatewayName); - - /* Get the output file name */ - String *outputFilename = Getattr(node, "outfile"); - - /* Initialize I/O */ - beginSection = NewFile(outputFilename, "w", SWIG_output_files()); - if (!beginSection) { - FileErrorDisplay(outputFilename); - Exit(EXIT_FAILURE); - } - runtimeSection = NewString(""); - initSection = NewString(""); - headerSection = NewString(""); - wrappersSection = NewString(""); - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("begin", beginSection); - Swig_register_filebyname("header", headerSection); - Swig_register_filebyname("wrapper", wrappersSection); - Swig_register_filebyname("runtime", runtimeSection); - Swig_register_filebyname("init", initSection); - - /* Output module initialization code */ - Swig_banner(beginSection); - - Swig_obligatory_macros(runtimeSection, "SCILAB"); - - // Gateway header source merged with wrapper source in nobuilder mode - if (!generateBuilder) - startGatewayHeader(gatewayLibraryName); - - // Create builder file if required - if (generateBuilder) { - createBuilderFile(outputFilename); - } - - // Create gateway XML if required - if (createGatewayXML) { - createGatewayXMLFile(gatewayName); - } - - // Create loader script if required - if (createLoader) { - createLoaderFile(gatewayLibraryName); - } - - // Module initialization function - String *smallFunctionName = createSmallIdentifierName(gatewayName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 5); - String *gatewayInitFunctionName = NewStringf("%s_Init", gatewayName); - String *gatewayInitSmallFunctionName = NewStringf("%s_Init", smallFunctionName); - String *wrapperFunctionName = NewStringf("SWIG_%s_Init", gatewayName); - - /* Add initialization function to builder table */ - addFunctionToScilab(gatewayInitFunctionName, gatewayInitSmallFunctionName, wrapperFunctionName); - - // Add helper functions to builder table - addHelperFunctions(); - - // Open Scilab wrapper variables creation function - variablesCode = NewString(""); - Printf(variablesCode, "int SWIG_CreateScilabVariables(void *_pvApiCtx) {"); - - /* Emit code for children */ - if (CPlusPlus) { - Printf(wrappersSection, "extern \"C\" {\n"); - } - - Language::top(node); - - if (CPlusPlus) { - Printf(wrappersSection, "}\n"); - } - // Close Scilab wrapper variables creation function - Printf(variablesCode, " return SWIG_OK;\n}\n"); - - // Add Builder footer code and save - if (generateBuilder) { - saveBuilderFile(gatewayLibraryName); - } - - /* Close the init function and rename with module name */ - Printf(initSection, "return 0;\n}\n"); - Replaceall(initSection, "<module>", gatewayName); - - /* Write all to the wrapper file */ - SwigType_emit_type_table(runtimeSection, wrappersSection); // Declare pointer types, ... (Ex: SWIGTYPE_p_p_double) - - // Gateway header source merged with wrapper source in nobuilder mode - if (!generateBuilder) { - terminateGatewayHeader(gatewayLibraryName); - Printv(initSection, gatewayHeader, NIL); - } - - Dump(runtimeSection, beginSection); - Dump(headerSection, beginSection); - Dump(wrappersSection, beginSection); - Dump(variablesCode, beginSection); - Wrapper_pretty_print(initSection, beginSection); - - if (createGatewayXML) { - saveGatewayXMLFile(); - } - - if (createLoader) { - saveLoaderFile(gatewayLibraryName); - } - - /* Cleanup files */ - Delete(runtimeSection); - Delete(headerSection); - Delete(wrappersSection); - Delete(initSection); - Delete(beginSection); - - Delete(sourceFileList); - Delete(cflags); - Delete(ldflags); - - return SWIG_OK; - } - - /* ------------------------------------------------------------------------ - * emitBanner() - * ----------------------------------------------------------------------*/ - - void emitBanner(File *f) { - Printf(f, "// ----------------------------------------------------------------------------\n"); - Swig_banner_target_lang(f, "// "); - Printf(f, "// ----------------------------------------------------------------------------- */\n\n"); - } - - /* ------------------------------------------------------------------------ - * functionWrapper() - * ----------------------------------------------------------------------*/ - - virtual int functionWrapper(Node *node) { - - /* Get some useful attributes of this function */ - String *functionName = Getattr(node, "sym:name"); - String *smallFunctionName = createSmallIdentifierName(functionName); - - SwigType *functionReturnType = Getattr(node, "type"); - ParmList *functionParamsList = Getattr(node, "parms"); - - int paramIndex = 0; // Used for loops over ParmsList - Parm *param = NULL; // Used for loops over ParamsList - - /* Create the wrapper object */ - Wrapper *wrapper = NewWrapper(); - - /* Create the function wrapper name */ - String *wrapperName = Swig_name_wrapper(functionName); - - /* Deal with overloading */ - String *overloadedName = Copy(wrapperName); - /* Determine whether the function is overloaded or not */ - bool isOverloaded = ! !Getattr(node, "sym:overloaded"); - /* Determine whether the function is the last overloaded */ - bool isLastOverloaded = isOverloaded && !Getattr(node, "sym:nextSibling"); - - if (!isOverloaded && !addSymbol(functionName, node)) { - DelWrapper(wrapper); - return SWIG_ERROR; - } - - if (isOverloaded) { - Append(overloadedName, Getattr(node, "sym:overname")); - } - - /* Write the wrapper function definition (standard Scilab gateway function prototype) */ - Printv(wrapper->def, "SWIGEXPORT int ", overloadedName, "(SWIG_GatewayParameters) {", NIL); - - /* Emit all of the local variables for holding arguments */ - // E.g.: double arg1; - emit_parameter_variables(functionParamsList, wrapper); - - /* Attach typemaps to the parameter list */ - // Add local variables used in typemaps (iRows, iCols, ...) - emit_attach_parmmaps(functionParamsList, wrapper); - Setattr(node, "wrap:parms", functionParamsList); - - /* Check input/output arguments count */ - int maxInputArguments = emit_num_arguments(functionParamsList); - int minInputArguments = emit_num_required(functionParamsList); - int minOutputArguments = 0; - int maxOutputArguments = 1; - - if (!emit_isvarargs(functionParamsList)) { - Printf(wrapper->code, "SWIG_CheckInputArgument(pvApiCtx, $mininputarguments, $maxinputarguments);\n"); - } - else { - Printf(wrapper->code, "SWIG_CheckInputArgumentAtLeast(pvApiCtx, $mininputarguments-1);\n"); - } - Printf(wrapper->code, "SWIG_CheckOutputArgument(pvApiCtx, $minoutputarguments, $maxoutputarguments);\n"); - - /* Set context */ - Printf(wrapper->code, "SWIG_Scilab_SetFuncName(fname);\n"); - Printf(wrapper->code, "SWIG_Scilab_SetApiContext(pvApiCtx);\n"); - - /* Write typemaps(in) */ - - for (paramIndex = 0, param = functionParamsList; paramIndex < maxInputArguments; ++paramIndex) { - // Ignore parameter if the typemap specifies numinputs=0 - while (checkAttribute(param, "tmap:in:numinputs", "0")) { - param = Getattr(param, "tmap:in:next"); - } - - SwigType *paramType = Getattr(param, "type"); - String *paramTypemap = Getattr(param, "tmap:in"); - - if (paramTypemap) { - // Replace $input by the position on Scilab stack - String *source = NewString(""); - Printf(source, "%d", paramIndex + 1); - Setattr(param, "emit:input", source); - Replaceall(paramTypemap, "$input", Getattr(param, "emit:input")); - - if (Getattr(param, "wrap:disown") || (Getattr(param, "tmap:in:disown"))) { - Replaceall(paramTypemap, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(paramTypemap, "$disown", "0"); - } - - if (paramIndex >= minInputArguments) { /* Optional input argument management */ - Printf(wrapper->code, "if (SWIG_NbInputArgument(pvApiCtx) > %d) {\n%s\n}\n", paramIndex, paramTypemap); - } else { - Printf(wrapper->code, "%s\n", paramTypemap); - } - param = Getattr(param, "tmap:in:next"); - } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(paramType, 0)); - break; - } - } - - /* TODO write constraints */ - - Setattr(node, "wrap:name", overloadedName); - - /* Emit the function call */ - Swig_director_emit_dynamic_cast(node, wrapper); - String *functionActionCode = emit_action(node); - - /* Insert the return variable */ - emit_return_variable(node, functionReturnType, wrapper); - - /* Return the function value if necessary */ - String *functionReturnTypemap = Swig_typemap_lookup_out("out", node, Swig_cresult_name(), wrapper, functionActionCode); - if (functionReturnTypemap) { - // Result is actually the position of output value on stack - if (Len(functionReturnTypemap) > 0) { - Printf(wrapper->code, "SWIG_Scilab_SetOutputPosition(%d);\n", 1); - } - Replaceall(functionReturnTypemap, "$result", "1"); - - if (GetFlag(node, "feature:new")) { - Replaceall(functionReturnTypemap, "$owner", "1"); - } else { - Replaceall(functionReturnTypemap, "$owner", "0"); - } - - Printf(wrapper->code, "%s\n", functionReturnTypemap); - - /* If the typemap is not empty, the function return one more argument than the typemaps gives */ - if (Len(functionReturnTypemap) > 0) { - minOutputArguments++; - maxOutputArguments++; - } - Delete(functionReturnTypemap); - - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(functionReturnType, 0), - functionName); - } - - /* Write typemaps(out) */ - for (param = functionParamsList; param;) { - String *paramTypemap = Getattr(param, "tmap:argout"); - if (paramTypemap) { - minOutputArguments++; - maxOutputArguments++; - Printf(wrapper->code, "SWIG_Scilab_SetOutputPosition(%d);\n", minOutputArguments); - String *result = NewString(""); - Printf(result, "%d", minOutputArguments); - Replaceall(paramTypemap, "$result", result); - Printf(wrapper->code, "%s\n", paramTypemap); - Delete(paramTypemap); - param = Getattr(param, "tmap:argout:next"); - } else { - param = nextSibling(param); - } - } - /* Add cleanup code */ - for (param = functionParamsList; param;) { - String *tm; - if ((tm = Getattr(param, "tmap:freearg"))) { - if (tm && (Len(tm) != 0)) { - Printf(wrapper->code, "%s\n", tm); - } - param = Getattr(param, "tmap:freearg:next"); - } else { - param = nextSibling(param); - } - } - - /* See if there is any return cleanup code */ - String *tm; - if ((tm = Swig_typemap_lookup("ret", node, Swig_cresult_name(), 0))) { - Printf(wrapper->code, "%s\n", tm); - Delete(tm); - } - - /* Close the function(ok) */ - Printv(wrapper->code, "return SWIG_OK;\n", NIL); - Printv(wrapper->code, "}\n", NIL); - - /* Add the failure cleanup code */ - /* TODO */ - - /* Final substitutions if applicable */ - Replaceall(wrapper->code, "$symname", functionName); - - /* Set CheckInputArgument and CheckOutputArgument input arguments */ - if (maxOutputArguments < 1) { - maxOutputArguments = 1; - } - if (minOutputArguments == 1) { - minOutputArguments = 0; - } - String *argnumber = NewString(""); - Printf(argnumber, "%d", minInputArguments); - Replaceall(wrapper->code, "$mininputarguments", argnumber); - - argnumber = NewString(""); - Printf(argnumber, "%d", maxInputArguments); - Replaceall(wrapper->code, "$maxinputarguments", argnumber); - - argnumber = NewString(""); - Printf(argnumber, "%d", minOutputArguments); - Replaceall(wrapper->code, "$minoutputarguments", argnumber); - - argnumber = NewString(""); - Printf(argnumber, "%d", maxOutputArguments); - Replaceall(wrapper->code, "$maxoutputarguments", argnumber); - - /* Dump the function out */ - Wrapper_print(wrapper, wrappersSection); - - /* Update builder.sce contents */ - if (isLastOverloaded) { - addFunctionToScilab(functionName, smallFunctionName, wrapperName); - dispatchFunction(node); - } - - if (!isOverloaded) { - addFunctionToScilab(functionName, smallFunctionName, wrapperName); - } - - /* tidy up */ - Delete(overloadedName); - Delete(wrapperName); - DelWrapper(wrapper); - - return SWIG_OK; - } - - /* ----------------------------------------------------------------------- - * dispatchFunction() - * ----------------------------------------------------------------------- */ - - void dispatchFunction(Node *node) { - Wrapper *wrapper = NewWrapper(); - - String *functionName = Getattr(node, "sym:name"); - String *wrapperName = Swig_name_wrapper(functionName); - int maxargs = 0; - - /* Generate the dispatch function */ - String *dispatch = Swig_overload_dispatch(node, "return %s(SWIG_GatewayArguments);", &maxargs); - String *tmp = NewString(""); - - Printv(wrapper->def, "SWIGEXPORT int ", wrapperName, "(SWIG_GatewayParameters) {\n", NIL); - - /* Get the number of the parameters */ - Wrapper_add_local(wrapper, "argc", "int argc = SWIG_NbInputArgument(pvApiCtx)"); - Printf(tmp, "int argv[%d] = {", maxargs); - for (int j = 0; j < maxargs; ++j) { - Printf(tmp, "%s%d", j ? "," : " ", j + 1); - } - Printf(tmp, "}"); - Wrapper_add_local(wrapper, "argv", tmp); - - Printf(wrapper->code, "SWIG_Scilab_SetApiContext(pvApiCtx);\n"); - - /* Dump the dispatch function */ - Printv(wrapper->code, dispatch, "\n", NIL); - Printf(wrapper->code, "Scierror(999, _(\"No matching function for overload\"));\n"); - Printf(wrapper->code, "return SWIG_ERROR;\n"); - Printv(wrapper->code, "}\n", NIL); - Wrapper_print(wrapper, wrappersSection); - - Delete(tmp); - DelWrapper(wrapper); - Delete(dispatch); - Delete(wrapperName); - } - - /* ----------------------------------------------------------------------- - * variableWrapper() - * ----------------------------------------------------------------------- */ - - virtual int variableWrapper(Node *node) { - - /* Get information about variable */ - String *origVariableName = Getattr(node, "name"); // Ex: Shape::nshapes - String *variableName = Getattr(node, "sym:name"); // Ex; Shape_nshapes (can be used for function names, ...) - String *smallVariableName = createSmallIdentifierName(variableName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 4); - - /* Manage GET function */ - Wrapper *getFunctionWrapper = NewWrapper(); - String *getFunctionName = Swig_name_get(NSPACE_TODO, variableName); - String *scilabGetFunctionName = Swig_name_get(NSPACE_TODO, variableName); - String *scilabGetSmallFunctionName = Swig_name_get(NSPACE_TODO, smallVariableName); - - Setattr(node, "wrap:name", getFunctionName); - Printv(getFunctionWrapper->def, "SWIGEXPORT int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL); - - /* Check the number of input and output */ - Printf(getFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 0, 0);\n"); - Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n"); - Printf(getFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n"); - - String *varoutTypemap = Swig_typemap_lookup("varout", node, origVariableName, 0); - if (varoutTypemap != NULL) { - Printf(getFunctionWrapper->code, "SWIG_Scilab_SetOutputPosition(%d);\n", 1); - Replaceall(varoutTypemap, "$value", origVariableName); - Replaceall(varoutTypemap, "$result", "1"); - emit_action_code(node, getFunctionWrapper->code, varoutTypemap); - Delete(varoutTypemap); - } - Append(getFunctionWrapper->code, "return SWIG_OK;\n"); - Append(getFunctionWrapper->code, "}\n"); - Wrapper_print(getFunctionWrapper, wrappersSection); - - /* Add function to builder table */ - addFunctionToScilab(scilabGetFunctionName, scilabGetSmallFunctionName, getFunctionName); - - /* Manage SET function */ - if (is_assignable(node)) { - Wrapper *setFunctionWrapper = NewWrapper(); - String *setFunctionName = Swig_name_set(NSPACE_TODO, variableName); - String *scilabSetFunctionName = Swig_name_set(NSPACE_TODO, variableName); - String *scilabSetSmallFunctionName = Swig_name_set(NSPACE_TODO, smallVariableName); - - Setattr(node, "wrap:name", setFunctionName); - Printv(setFunctionWrapper->def, "SWIGEXPORT int ", setFunctionName, "(SWIG_GatewayParameters) {\n", NIL); - - /* Check the number of input and output */ - Printf(setFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 1, 1);\n"); - Printf(setFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n"); - Printf(setFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n"); - - String *varinTypemap = Swig_typemap_lookup("varin", node, origVariableName, 0); - if (varinTypemap != NULL) { - Replaceall(varinTypemap, "$input", "1"); - emit_action_code(node, setFunctionWrapper->code, varinTypemap); - Delete(varinTypemap); - } - Append(setFunctionWrapper->code, "return SWIG_OK;\n"); - Append(setFunctionWrapper->code, "}\n"); - Wrapper_print(setFunctionWrapper, wrappersSection); - - /* Add function to builder table */ - addFunctionToScilab(scilabSetFunctionName, scilabSetSmallFunctionName, setFunctionName); - - DelWrapper(setFunctionWrapper); - } - DelWrapper(getFunctionWrapper); - - return SWIG_OK; - } - - /* ----------------------------------------------------------------------- - * constantWrapper() - * ----------------------------------------------------------------------- */ - - virtual int constantWrapper(Node *node) { - - /* Get the useful information from the node */ - String *nodeName = Getattr(node, "name"); - SwigType *type = Getattr(node, "type"); - String *constantName = Getattr(node, "sym:name"); - String *rawValue = Getattr(node, "rawval"); - String *constantValue = rawValue ? rawValue : Getattr(node, "value"); - String *constantTypemap = NULL; - - // If feature scilab:const enabled, constants & enums are wrapped to Scilab variables - if (GetFlag(node, "feature:scilab:const")) { - bool isConstant = ((SwigType_issimple(type)) || (SwigType_type(type) == T_STRING)); - bool isEnum = (Cmp(nodeType(node), "enumitem") == 0); - - if (isConstant || isEnum) { - if (isEnum) { - Setattr(node, "type", "double"); - constantValue = Getattr(node, "value"); - } - - constantTypemap = Swig_typemap_lookup("scilabconstcode", node, nodeName, 0); - if (constantTypemap != NULL) { - - Setattr(node, "wrap:name", constantName); - Replaceall(constantTypemap, "$result", constantName); - Replaceall(constantTypemap, "$value", constantValue); - - emit_action_code(node, variablesCode, constantTypemap); - Delete(constantTypemap); - return SWIG_OK; - } - } - } - - /* Create variables for member pointer constants, not supported by typemaps (like Python wrapper does) */ - if (SwigType_type(type) == T_MPOINTER) { - String *wname = Swig_name_wrapper(constantName); - String *str = SwigType_str(type, wname); - Printf(headerSection, "static %s = %s;\n", str, constantValue); - Delete(str); - constantValue = wname; - } - - // Constant names can have SCILAB_VARIABLE_NAME_CHAR_MAX because of suffixes "_get" added to function - String *smallConstantName = createSmallIdentifierName(constantName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 4); - - /* Create GET function to get the constant value */ - Wrapper *getFunctionWrapper = NewWrapper(); - String *getFunctionName = Swig_name_get(NSPACE_TODO, constantName); - String *scilabGetSmallFunctionName = Swig_name_get(NSPACE_TODO, smallConstantName); - Setattr(node, "wrap:name", getFunctionName); - Setattr(node, "wrap:name", getFunctionName); - Printv(getFunctionWrapper->def, "SWIGEXPORT int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL); - - /* Check the number of input and output */ - Printf(getFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 0, 0);\n"); - Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n"); - Printf(getFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n"); - - constantTypemap = Swig_typemap_lookup("constcode", node, nodeName, 0); - if (constantTypemap != NULL) { - Printf(getFunctionWrapper->code, "SWIG_Scilab_SetOutputPosition(%d);\n", 1); - Replaceall(constantTypemap, "$value", constantValue); - Replaceall(constantTypemap, "$result", "1"); - emit_action_code(node, getFunctionWrapper->code, constantTypemap); - Delete(constantTypemap); - } - - /* Dump the wrapper function */ - Append(getFunctionWrapper->code, "return SWIG_OK;\n"); - Append(getFunctionWrapper->code, "}\n"); - Wrapper_print(getFunctionWrapper, wrappersSection); - - /* Add the function to Scilab */ - addFunctionToScilab(getFunctionName, scilabGetSmallFunctionName, getFunctionName); - - DelWrapper(getFunctionWrapper); - - return SWIG_OK; - } - - /* --------------------------------------------------------------------- - * enumvalueDeclaration() - * --------------------------------------------------------------------- */ - - virtual int enumvalueDeclaration(Node *node) { - static int iPreviousEnumValue = 0; - - if (GetFlag(node, "feature:scilab:const")) { - // Compute the "absolute" value of enum if needed - // (most of time enum values are a linked list of relative values) - String *enumValue = Getattr(node, "enumvalue"); - String *enumValueEx = Getattr(node, "enumvalueex"); - - // First enum value ? - String *firstenumitem = Getattr(node, "firstenumitem"); - if (firstenumitem) { - if (enumValue) { - // Value is in 'enumvalue' - iPreviousEnumValue = atoi(Char(enumValue)); - } else if (enumValueEx) { - // Or value is in 'enumValueEx' - iPreviousEnumValue = atoi(Char(enumValueEx)); - - enumValue = NewString(""); - Printf(enumValue, "%d", iPreviousEnumValue); - Setattr(node, "enumvalue", enumValue); - } - } else if (!enumValue && enumValueEx) { - // Value is not specified, set it by incrementing last value - enumValue = NewString(""); - Printf(enumValue, "%d", ++iPreviousEnumValue); - Setattr(node, "enumvalue", enumValue); - } - // Enums in Scilab are mapped to double - Setattr(node, "type", "double"); - } - - return Language::enumvalueDeclaration(node); - } - - /* ----------------------------------------------------------------------- - * addHelperFunctions() - * ----------------------------------------------------------------------- */ - - void addHelperFunctions() { - addFunctionToScilab("SWIG_this", "SWIG_this", "SWIG_this"); - addFunctionToScilab("SWIG_ptr", "SWIG_ptr", "SWIG_ptr"); - } - - /* ----------------------------------------------------------------------- - * addFunctionToScilab() - * Declare a wrapped function in Scilab (builder, gateway, XML, ...) - * ----------------------------------------------------------------------- */ - - void addFunctionToScilab(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName) { - if (!generateBuilder) - addFunctionInGatewayHeader(scilabFunctionName, scilabSmallFunctionName, wrapperFunctionName); - - if (generateBuilder) { - addFunctionInScriptTable(scilabFunctionName, scilabSmallFunctionName, wrapperFunctionName, builderCode5, builderCode6); - } - - if (createLoader) { - addFunctionInLoader(scilabFunctionName, scilabSmallFunctionName); - } - - if (gatewayXMLFile) { - Printf(gatewayXML, "<PRIMITIVE gatewayId=\"%s\" primitiveId=\"%d\" primitiveName=\"%s\"/>\n", gatewayID, primitiveID++, scilabSmallFunctionName); - } - } - - - /* ----------------------------------------------------------------------- - * createBuilderCode() - * ----------------------------------------------------------------------- */ - - void createBuilderFile(String *outputFilename) { - String *builderFilename = NewStringf("builder.sce"); - builderFile = NewFile(builderFilename, "w", SWIG_output_files()); - if (!builderFile) { - FileErrorDisplay(builderFilename); - Exit(EXIT_FAILURE); - } - emitBanner(builderFile); - - builderFunctionCount = 0; - builderCode = NewString(""); - builderCode5 = NewString(""); - builderCode6 = NewString(""); - Printf(builderCode, "mode(-1);\n"); - Printf(builderCode, "lines(0);\n"); /* Useful for automatic tests */ - - // Scilab needs to be in the build directory - Printf(builderCode, "originaldir = pwd();\n"); - Printf(builderCode, "builddir = get_absolute_file_path('builder.sce');\n"); - Printf(builderCode, "cd(builddir);\n"); - - Printf(builderCode, "ilib_verbose(%s);\n", verboseBuildLevel); - - Printf(builderCode, "libs = [];\n"); - - // Flags from command line arguments - Printf(builderCode, "cflags = \"\";\n"); - for (int i = 0; i < Len(cflags); i++) { - String *cflag = Getitem(cflags, i); - Printf(builderCode, "cflags = cflags + \" %s\";\n", cflag); - } - - if (Len(ldflags) > 0) { - for (int i = 0; i < Len(ldflags); i++) { - String *ldflag = Getitem(ldflags, i); - if (i == 0) { - Printf(builderCode, "ldflags = \"%s\";\n", ldflag); - } else { - Printf(builderCode, "ldflags = ldflags + \" %s\";\n", ldflag); - } - } - } else { - Printf(builderCode, "ldflags = \"\";\n"); - } - - // External script to set flags - if (buildFlagsScript) { - Printf(builderCode, "exec(\"%s\");\n", buildFlagsScript); - Printf(builderCode, "cflags = cflags + getCompilationFlags();\n"); - Printf(builderCode, "ldflags = ldflags + getLinkFlags();\n"); - } - // Additional sources - Insert(sourceFileList, 0, outputFilename); - for (int i = 0; i < Len(sourceFileList); i++) { - String *sourceFile = Getitem(sourceFileList, i); - if (i == 0) { - Printf(builderCode, "files = \"%s\";\n", sourceFile); - } else { - Printf(builderCode, "files($ + 1) = \"%s\";\n", sourceFile); - } - } - - Printf(builderCode5, "table = [ ..\n"); - Printf(builderCode6, "table = [ ..\n"); - } - - /* ----------------------------------------------------------------------- - * addFunctionInBuilderCode() - * Add a function wrapper in the function table of generated builder script - * ----------------------------------------------------------------------- */ - - void addFunctionInScriptTable(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName, String *scriptCode5, String *scriptCode6) { - if (++builderFunctionCount % 10 == 0) { - Printf(scriptCode5, "];\ntable = [table; ..\n"); - Printf(scriptCode6, "];\ntable = [table; ..\n"); - } - Printf(scriptCode5, "\"%s\",\"%s\"; ..\n", scilabSmallFunctionName, wrapperFunctionName); - Printf(scriptCode6, "\"%s\",\"%s\"; ..\n", scilabFunctionName, wrapperFunctionName); - } - - /* ----------------------------------------------------------------------- - * saveBuilderFile() - * ----------------------------------------------------------------------- */ - - void saveBuilderFile(String *gatewayName) { - Printf(builderCode5, "];\n"); - Printf(builderCode6, "];\n"); - - if (Equal(builderCode5, builderCode6)) { - Append(builderCode, builderCode6); - } else { - Printf(builderCode, "ver = getversion('scilab');\n"); - Printf(builderCode, "if ver(1) < 6 then\n"); - Printf(builderCode, " // version is less or equal to 5.5.2\n"); - Printf(builderCode, " \n"); - Append(builderCode, builderCode5); - Printf(builderCode, " \n"); - Printf(builderCode, "else\n"); - Printf(builderCode, " // version is 6.0.0 or more\n"); - Printf(builderCode, " \n"); - Append(builderCode, builderCode6); - Printf(builderCode, " \n"); - Printf(builderCode, "end\n"); - } - - Printf(builderCode, "ierr = 0;\n"); - Printf(builderCode, "if ~isempty(table) then\n"); - Printf(builderCode, " ierr = execstr(\"ilib_build(''%s'', table, files, libs, [], ldflags, cflags);\", 'errcatch');\n", gatewayName); - Printf(builderCode, " if ierr <> 0 then\n"); - Printf(builderCode, " err_msg = lasterror();\n"); - Printf(builderCode, " end\n"); - Printf(builderCode, "end\n"); - Printf(builderCode, "cd(originaldir);\n"); - Printf(builderCode, "if ierr <> 0 then\n"); - Printf(builderCode, " error(ierr, err_msg);\n"); - Printf(builderCode, "end\n"); - Printv(builderFile, builderCode, NIL); - - Delete(builderCode); - Delete(builderFile); - } - - /* ----------------------------------------------------------------------- - * createGatewayXMLFile() - * This XML file is used by Scilab in the context of internal modules - * ----------------------------------------------------------------------- */ - - void createGatewayXMLFile(String *gatewayName) { - String *gatewayXMLFilename = NewStringf("%s_gateway.xml", gatewayName); - gatewayXMLFile = NewFile(gatewayXMLFilename, "w", SWIG_output_files()); - if (!gatewayXMLFile) { - FileErrorDisplay(gatewayXMLFilename); - Exit(EXIT_FAILURE); - } - // Add a slightly modified SWIG banner to the gateway XML ("--modify" is illegal in XML) - gatewayXML = NewString(""); - Printf(gatewayXML, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); - Printf(gatewayXML, "<!--\n"); - Swig_banner_target_lang(gatewayXML, ""); - Printf(gatewayXML, "-->\n"); - Printf(gatewayXML, "<GATEWAY name=\"%s\">\n", gatewayName); - - primitiveID = 1; - } - - /* ----------------------------------------------------------------------- - * saveGatewayXMLFile() - * ----------------------------------------------------------------------- */ - - void saveGatewayXMLFile() { - Printf(gatewayXML, "</GATEWAY>\n"); - Printv(gatewayXMLFile, gatewayXML, NIL); - Delete(gatewayXMLFile); - } - - /* ----------------------------------------------------------------------- - * startGatewayHeader() - * Start the gateway header - * ----------------------------------------------------------------------- */ - void startGatewayHeader(String *gatewayLibraryName) { - gatewayHeader = NewString(""); - Printf(gatewayHeader, "\n"); - - gatewayHeaderV6 = NewString(""); - Printf(gatewayHeaderV6, "#ifdef __cplusplus\n"); - Printf(gatewayHeaderV6, "extern \"C\" {\n"); - Printf(gatewayHeaderV6, "#endif\n"); - Printf(gatewayHeaderV6, "#include \"c_gateway_prototype.h\"\n"); - Printf(gatewayHeaderV6, "#include \"addfunction.h\"\n"); - Printf(gatewayHeaderV6, "#ifdef __cplusplus\n"); - Printf(gatewayHeaderV6, "}\n"); - Printf(gatewayHeaderV6, "#endif\n"); - Printf(gatewayHeaderV6, "\n"); - Printf(gatewayHeaderV6, "#define MODULE_NAME L\"%s\"\n", gatewayLibraryName); - Printf(gatewayHeaderV6, "#ifdef __cplusplus\n"); - Printf(gatewayHeaderV6, "extern \"C\"\n"); - Printf(gatewayHeaderV6, "#endif\n"); - Printf(gatewayHeaderV6, "SWIGEXPORT int %s(wchar_t *pwstFuncName) {\n", gatewayLibraryName); - Printf(gatewayHeaderV6, "\n"); - } - - /* ----------------------------------------------------------------------- - * addFunctionInGatewayHeader() - * Add a function in the gateway header - * ----------------------------------------------------------------------- */ - - void addFunctionInGatewayHeader(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName) { - if (gatewayHeaderV5 == NULL) { - gatewayHeaderV5 = NewString(""); - Printf(gatewayHeaderV5, "static GenericTable Tab[] = {\n"); - } else - Printf(gatewayHeaderV5, ",\n"); - Printf(gatewayHeaderV5, " {(Myinterfun)sci_gateway, (GT)%s, (char *)\"%s\"}", wrapperFunctionName, scilabSmallFunctionName); - - Printf(gatewayHeaderV6, "if (wcscmp(pwstFuncName, L\"%s\") == 0) { addCStackFunction((wchar_t *)L\"%s\", &%s, (wchar_t *)MODULE_NAME); }\n", scilabFunctionName, scilabFunctionName, wrapperFunctionName); - } - - /* ----------------------------------------------------------------------- - * terminateGatewayHeader() - * Terminates the gateway header - * ----------------------------------------------------------------------- */ - - void terminateGatewayHeader(String *gatewayLibraryName) { - Printf(gatewayHeaderV5, "};\n"); - Printf(gatewayHeaderV5, "\n"); - Printf(gatewayHeaderV5, "#ifdef __cplusplus\n"); - Printf(gatewayHeaderV5, "extern \"C\" {\n"); - Printf(gatewayHeaderV5, "#endif\n"); - Printf(gatewayHeaderV5, "SWIGEXPORT int C2F(%s)() {\n", gatewayLibraryName); - Printf(gatewayHeaderV5, " Rhs = Max(0, Rhs);\n"); - Printf(gatewayHeaderV5, " if (*(Tab[Fin-1].f) != NULL) {\n"); - Printf(gatewayHeaderV5, " if(pvApiCtx == NULL) {\n"); - Printf(gatewayHeaderV5, " pvApiCtx = (StrCtx *)MALLOC(sizeof(StrCtx));\n"); - Printf(gatewayHeaderV5, " }\n"); - Printf(gatewayHeaderV5, " pvApiCtx->pstName = (char *)Tab[Fin-1].name;\n"); - Printf(gatewayHeaderV5, " (*(Tab[Fin-1].f))(Tab[Fin-1].name,(GatefuncH)Tab[Fin-1].F);\n"); - Printf(gatewayHeaderV5, " }\n"); - Printf(gatewayHeaderV5, " return 0;\n"); - Printf(gatewayHeaderV5, "}\n"); - Printf(gatewayHeaderV5, "\n"); - Printf(gatewayHeaderV5, "#ifdef __cplusplus\n"); - Printf(gatewayHeaderV5, "}\n"); - Printf(gatewayHeaderV5, "#endif\n"); - - Printf(gatewayHeaderV6, "return 1;\n"); - Printf(gatewayHeaderV6, "};\n"); - - Printf(gatewayHeader, "#if SWIG_SCILAB_VERSION >= 600\n"); - Printv(gatewayHeader, gatewayHeaderV6, NIL); - Printf(gatewayHeader, "#else\n"); - Printv(gatewayHeader, gatewayHeaderV5, NIL); - Printf(gatewayHeader, "#endif\n"); - } - - - /* ----------------------------------------------------------------------- - * createLoaderScriptFile() - * Creates the loader script file (loader.sce) - * ----------------------------------------------------------------------- */ - - void createLoaderFile(String *gatewayLibraryName) { - String *loaderFilename = NewString("loader.sce"); - loaderFile = NewFile(loaderFilename, "w", SWIG_output_files()); - if (!loaderFile) { - FileErrorDisplay(loaderFilename); - Exit(EXIT_FAILURE); - } - - emitBanner(loaderFile); - - loaderFunctionCount = 0; - loaderScript = NewString("function loader_function()\n"); - Printf(loaderScript, " p = get_absolute_file_path('loader.sce');\n", gatewayLibraryName); - Printf(loaderScript, " [bOK, ilib] = c_link('%s');\n", gatewayLibraryName); - Printf(loaderScript, " if bOK then\n"); - Printf(loaderScript, " ulink(ilib);\n"); - Printf(loaderScript, " end\n"); - loaderScript5 = NewString(" list_functions = [ ..\n"); - loaderScript6 = NewString(" list_functions = [ ..\n"); - } - - /* ----------------------------------------------------------------------- - * addFunctionInLoaderScript() - * Add a function in the loader script table - * ----------------------------------------------------------------------- */ - - void addFunctionInLoader(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName) { - if (++loaderFunctionCount % 10 == 0) { - Printf(loaderScript5, " ];\n list_functions = [list_functions; ..\n"); - Printf(loaderScript6, " ];\n list_functions = [list_functions; ..\n"); - } - Printf(loaderScript5, " '%s'; ..\n", scilabSmallFunctionName); - Printf(loaderScript6, " '%s'; ..\n", scilabFunctionName); - } - - /* ----------------------------------------------------------------------- - * saveLoaderScriptFile() - * Terminates and saves the loader script - * ----------------------------------------------------------------------- */ - - void saveLoaderFile(String *gatewayLibraryName) { - Printf(loaderScript5, " ];\n"); - Printf(loaderScript6, " ];\n"); - - if (Equal(loaderScript5, loaderScript6)) { - Append(loaderScript, loaderScript6); - } else { - Printf(loaderScript, " ver = getversion('scilab');\n"); - Printf(loaderScript, " if ver(1) < 6 then\n"); - Printf(loaderScript, " // version is less or equal to 5.5.2\n"); - Printf(loaderScript, " \n"); - Append(loaderScript, loaderScript5); - Delete(loaderScript5); - Printf(loaderScript, " \n"); - Printf(loaderScript, " else\n"); - Printf(loaderScript, " // version is 6.0.0 or more\n"); - Printf(loaderScript, " \n"); - Append(loaderScript, loaderScript6); - Delete(loaderScript6); - Printf(loaderScript, " \n"); - Printf(loaderScript, " end\n"); - } - - Printf(loaderScript, " addinter(p + '%s' + getdynlibext(), '%s', list_functions);\n", gatewayLibraryName, gatewayLibraryName); - Printf(loaderScript, "endfunction\n"); - Printf(loaderScript, "loader_function();\n"); - Printf(loaderScript, "clear loader_function;\n"); - Printv(loaderFile, loaderScript, NIL); - - Delete(loaderScript); - Delete(loaderFile); - } - - /* ----------------------------------------------------------------------- - * createSmallIdentifierName() - * Create a Scilab small identifier to be used by Scilab 5 - * ----------------------------------------------------------------------- */ - - String* createSmallIdentifierName(String* name, int outputLen = SCILAB_IDENTIFIER_NAME_CHAR_MAX) { - char* s = Char(name); - int nameLen = Len(s); - - // truncate and preserve common suffix - if (outputLen > 4 && nameLen > outputLen) { - String* smallName = NewStringWithSize(name, outputLen); - char* smallNameStr = (char*) Data(smallName); - - if (s[nameLen-4] == '_' && s[nameLen - 3] == 'g' && s[nameLen - 2] == 'e' && s[nameLen - 1] == 't') { - // get - memcpy(&smallNameStr[outputLen - 4], &s[nameLen - 4], 4); - } else if (s[nameLen-4] == '_' && s[nameLen - 3] == 's' && s[nameLen - 2] == 'e' && s[nameLen - 1] == 't') { - // set - memcpy(&smallNameStr[outputLen - 4], &s[nameLen - 4], 4); - } - - return smallName; - } - - return name; - } - -}; - -extern "C" Language *swig_scilab(void) { - return new SCILAB(); -} diff --git a/contrib/tools/swig/Source/Modules/swigmain.cxx b/contrib/tools/swig/Source/Modules/swigmain.cxx deleted file mode 100644 index d553fe8930c..00000000000 --- a/contrib/tools/swig/Source/Modules/swigmain.cxx +++ /dev/null @@ -1,265 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * swigmain.cxx - * - * Simplified Wrapper and Interface Generator (SWIG) - * - * This file is the main entry point to SWIG. It collects the command - * line options, registers built-in language modules, and instantiates - * a module for code generation. If adding new language modules - * to SWIG, you would modify this file. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include <ctype.h> - -/* Module factories. These functions are used to instantiate - the built-in language modules. If adding a new language - module to SWIG, place a similar function here. Make sure - the function has "C" linkage. This is required so that modules - can be dynamically loaded in future versions. */ - -extern "C" { - Language *swig_csharp(void); - Language *swig_d(void); - Language *swig_go(void); - Language *swig_guile(void); - Language *swig_java(void); - Language *swig_javascript(void); - Language *swig_lua(void); - Language *swig_mzscheme(void); - Language *swig_ocaml(void); - Language *swig_octave(void); - Language *swig_perl5(void); - Language *swig_php(void); - Language *swig_python(void); - Language *swig_r(void); - Language *swig_ruby(void); - Language *swig_scilab(void); - Language *swig_tcl(void); - Language *swig_xml(void); -} - -/* Association of command line options to language modules. - Place an entry for new language modules here, keeping the - list sorted alphabetically. */ - -static TargetLanguageModule modules[] = { - {"-allegrocl", NULL, "ALLEGROCL", Disabled}, - {"-chicken", NULL, "CHICKEN", Disabled}, - {"-clisp", NULL, "CLISP", Disabled}, - {"-cffi", NULL, "CFFI", Disabled}, - {"-csharp", swig_csharp, "C#", Supported}, - {"-d", swig_d, "D", Supported}, - {"-go", swig_go, "Go", Supported}, - {"-guile", swig_guile, "Guile", Supported}, - {"-java", swig_java, "Java", Supported}, - {"-javascript", swig_javascript, "Javascript", Supported}, - {"-lua", swig_lua, "Lua", Supported}, - {"-modula3", NULL, "Modula 3", Disabled}, - {"-mzscheme", swig_mzscheme, "MzScheme/Racket", Experimental}, - {"-ocaml", swig_ocaml, "OCaml", Experimental}, - {"-octave", swig_octave, "Octave", Supported}, - {"-perl", swig_perl5, NULL, Supported}, - {"-perl5", swig_perl5, "Perl 5", Supported}, - {"-php", swig_php, NULL, Supported}, - {"-php5", NULL, "PHP 5", Disabled}, - {"-php7", swig_php, "PHP 7 or later", Supported}, - {"-pike", NULL, "Pike", Disabled}, - {"-python", swig_python, "Python", Supported}, - {"-r", swig_r, "R (aka GNU S)", Supported}, - {"-ruby", swig_ruby, "Ruby", Supported}, - {"-scilab", swig_scilab, "Scilab", Supported}, - {"-sexp", NULL, "Lisp S-Expressions", Disabled}, - {"-tcl", swig_tcl, NULL, Supported}, - {"-tcl8", swig_tcl, "Tcl 8", Supported}, - {"-uffi", NULL, "Common Lisp / UFFI", Disabled}, - {"-xml", swig_xml, "XML", Supported}, - {NULL, NULL, NULL, Disabled} -}; - -//----------------------------------------------------------------- -// main() -// -// Main program. Initializes the files and starts the parser. -//----------------------------------------------------------------- - -void SWIG_merge_envopt(const char *env, int oargc, char *oargv[], int *nargc, char ***nargv) { - if (!env) { - *nargc = oargc; - *nargv = (char **)Malloc(sizeof(char *) * (oargc + 1)); - memcpy(*nargv, oargv, sizeof(char *) * (oargc + 1)); - return; - } - - int argc = 1; - int arge = oargc + 1024; - char **argv = (char **) Malloc(sizeof(char *) * (arge + 1)); - char *buffer = (char *) Malloc(2048); - char *b = buffer; - char *be = b + 1023; - const char *c = env; - while ((b != be) && *c && (argc < arge)) { - while (isspace(*c) && *c) - ++c; - if (*c) { - argv[argc] = b; - ++argc; - } - while ((b != be) && *c && !isspace(*c)) { - *(b++) = *(c++); - } - *b++ = 0; - } - - argv[0] = oargv[0]; - for (int i = 1; (i < oargc) && (argc < arge); ++i, ++argc) { - argv[argc] = oargv[i]; - } - argv[argc] = NULL; - - *nargc = argc; - *nargv = argv; -} - -static void insert_option(int *argc, char ***argv, int index, char const *start, char const *end) { - int new_argc = *argc; - char **new_argv = *argv; - size_t option_len = end - start; - - // Preserve the NULL pointer at argv[argc] - new_argv = (char **)Realloc(new_argv, (new_argc + 2) * sizeof(char *)); - memmove(&new_argv[index + 1], &new_argv[index], sizeof(char *) * (new_argc + 1 - index)); - new_argc++; - - new_argv[index] = (char *)Malloc(option_len + 1); - memcpy(new_argv[index], start, option_len); - new_argv[index][option_len] = '\0'; - - *argc = new_argc; - *argv = new_argv; -} - -static void merge_options_files(int *argc, char ***argv) { - static const int BUFFER_SIZE = 4096; - char buffer[BUFFER_SIZE]; - int i; - int insert; - char **new_argv = *argv; - int new_argc = *argc; - FILE *f; - - i = 1; - while (i < new_argc) { - if (new_argv[i] && new_argv[i][0] == '@' && (f = fopen(&new_argv[i][1], "r"))) { - int ci; - char *b; - char *be = &buffer[BUFFER_SIZE]; - int quote = 0; - bool escape = false; - - new_argc--; - memmove(&new_argv[i], &new_argv[i + 1], sizeof(char *) * (new_argc - i)); - insert = i; - b = buffer; - - while ((ci = fgetc(f)) != EOF) { - const char c = static_cast<char>(ci); - if (escape) { - if (b != be) { - *b = c; - ++b; - } - escape = false; - } else if (c == '\\') { - escape = true; - } else if (!quote && (c == '\'' || c == '"')) { - quote = c; - } else if (quote && c == quote) { - quote = 0; - } else if (isspace(c) && !quote) { - if (b != buffer) { - insert_option(&new_argc, &new_argv, insert, buffer, b); - insert++; - - b = buffer; - } - } else if (b != be) { - *b = c; - ++b; - } - } - if (b != buffer) - insert_option(&new_argc, &new_argv, insert, buffer, b); - fclose(f); - } else { - ++i; - } - } - - *argv = new_argv; - *argc = new_argc; -} - -int main(int margc, char **margv) { - int i; - const TargetLanguageModule *language_module = 0; - - int argc; - char **argv; - - SWIG_merge_envopt(getenv("SWIG_FEATURES"), margc, margv, &argc, &argv); - merge_options_files(&argc, &argv); - - Swig_init_args(argc, argv); - - /* Get options */ - for (i = 1; i < argc; i++) { - if (argv[i]) { - bool is_target_language_module = false; - for (int j = 0; modules[j].name; j++) { - if (strcmp(modules[j].name, argv[i]) == 0) { - language_module = &modules[j]; - is_target_language_module = true; - break; - } - } - if (is_target_language_module) { - Swig_mark_arg(i); - if (language_module->status == Disabled) { - if (language_module->help) - Printf(stderr, "Target language option %s (%s) is no longer supported.\n", language_module->name, language_module->help); - else - Printf(stderr, "Target language option %s is no longer supported.\n", language_module->name); - Exit(EXIT_FAILURE); - } - } else if ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) { - if (strcmp(argv[i], "--help") == 0) - strcpy(argv[i], "-help"); - Printf(stdout, "Supported Target Language Options\n"); - for (int j = 0; modules[j].name; j++) { - if (modules[j].help && modules[j].status == Supported) { - Printf(stdout, " %-15s - Generate %s wrappers\n", modules[j].name, modules[j].help); - } - } - Printf(stdout, "\nExperimental Target Language Options\n"); - for (int j = 0; modules[j].name; j++) { - if (modules[j].help && modules[j].status == Experimental) { - Printf(stdout, " %-15s - Generate %s wrappers\n", modules[j].name, modules[j].help); - } - } - // Swig_mark_arg not called as the general -help options also need to be displayed later on - } - } - } - - int res = SWIG_main(argc, argv, language_module); - - return res; -} diff --git a/contrib/tools/swig/Source/Modules/swigmod.h b/contrib/tools/swig/Source/Modules/swigmod.h deleted file mode 100644 index c605edf9d04..00000000000 --- a/contrib/tools/swig/Source/Modules/swigmod.h +++ /dev/null @@ -1,463 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * swigmod.h - * - * Main header file for SWIG modules. - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_SWIGMOD_H -#define SWIG_SWIGMOD_H - -#include "swig.h" -#include "preprocessor.h" -#include "swigwarn.h" - -#define NOT_VIRTUAL 0 -#define PLAIN_VIRTUAL 1 -#define PURE_VIRTUAL 2 - -extern String *input_file; -extern int line_number; -extern int start_line; -extern int CPlusPlus; // C++ mode -extern int Extend; // Extend mode -extern int Verbose; -extern int IsVirtual; -extern int ImportMode; -extern int NoExcept; // -no_except option -extern int Abstract; // abstract base class -extern int SmartPointer; // smart pointer methods being emitted -extern int SwigRuntime; - -/* Overload "argc" and "argv" */ -extern String *argv_template_string; -extern String *argc_template_string; - -/* Miscellaneous stuff */ - -#define tab2 " " -#define tab4 " " -#define tab8 " " - -class Dispatcher { -public: - - Dispatcher ():cplus_mode(PUBLIC) { - } - virtual ~ Dispatcher () { - } - - virtual int emit_one(Node *n); - virtual int emit_children(Node *n); - virtual int defaultHandler(Node *n); - - /* Top of the parse tree */ - virtual int top(Node *n) = 0; - - /* SWIG directives */ - - virtual int applyDirective(Node *n); - virtual int clearDirective(Node *n); - virtual int constantDirective(Node *n); - virtual int extendDirective(Node *n); - virtual int fragmentDirective(Node *n); - virtual int importDirective(Node *n); - virtual int includeDirective(Node *n); - virtual int insertDirective(Node *n); - virtual int moduleDirective(Node *n); - virtual int nativeDirective(Node *n); - virtual int pragmaDirective(Node *n); - virtual int typemapDirective(Node *n); - virtual int typemapitemDirective(Node *n); - virtual int typemapcopyDirective(Node *n); - virtual int typesDirective(Node *n); - - /* C/C++ parsing */ - - virtual int cDeclaration(Node *n); - virtual int externDeclaration(Node *n); - virtual int enumDeclaration(Node *n); - virtual int enumvalueDeclaration(Node *n); - virtual int enumforwardDeclaration(Node *n); - virtual int classDeclaration(Node *n); - virtual int classforwardDeclaration(Node *n); - virtual int constructorDeclaration(Node *n); - virtual int destructorDeclaration(Node *n); - virtual int accessDeclaration(Node *n); - virtual int usingDeclaration(Node *n); - virtual int namespaceDeclaration(Node *n); - virtual int templateDeclaration(Node *n); - virtual int lambdaDeclaration(Node *n); - - enum AccessMode { PUBLIC, PRIVATE, PROTECTED }; - -protected: - AccessMode cplus_mode; -}; - -/* ---------------------------------------------------------------------------- - * class language: - * - * This class defines the functions that need to be supported by the - * scripting language being used. The translator calls these virtual - * functions to output different types of code for different languages. - * ------------------------------------------------------------------------- */ - -class Language:public Dispatcher { -public: - Language(); - virtual ~Language(); - virtual int emit_one(Node *n); - - String *directorClassName(Node *n); - - /* Parse command line options */ - - virtual void main(int argc, char *argv[]); - - /* Top of the parse tree */ - - virtual int top(Node *n); - - /* SWIG directives */ - - - virtual int applyDirective(Node *n); - virtual int clearDirective(Node *n); - virtual int constantDirective(Node *n); - virtual int extendDirective(Node *n); - virtual int fragmentDirective(Node *n); - virtual int importDirective(Node *n); - virtual int includeDirective(Node *n); - virtual int insertDirective(Node *n); - virtual int moduleDirective(Node *n); - virtual int nativeDirective(Node *n); - virtual int pragmaDirective(Node *n); - virtual int typemapDirective(Node *n); - virtual int typemapcopyDirective(Node *n); - virtual int typesDirective(Node *n); - - /* C/C++ parsing */ - - virtual int cDeclaration(Node *n); - virtual int externDeclaration(Node *n); - virtual int enumDeclaration(Node *n); - virtual int enumvalueDeclaration(Node *n); - virtual int enumforwardDeclaration(Node *n); - virtual int classDeclaration(Node *n); - virtual int classforwardDeclaration(Node *n); - virtual int constructorDeclaration(Node *n); - virtual int destructorDeclaration(Node *n); - virtual int accessDeclaration(Node *n); - virtual int namespaceDeclaration(Node *n); - virtual int usingDeclaration(Node *n); - - /* Function handlers */ - - virtual int functionHandler(Node *n); - virtual int globalfunctionHandler(Node *n); - virtual int memberfunctionHandler(Node *n); - virtual int staticmemberfunctionHandler(Node *n); - virtual int callbackfunctionHandler(Node *n); - - /* Variable handlers */ - - virtual int variableHandler(Node *n); - virtual int globalvariableHandler(Node *n); - virtual int membervariableHandler(Node *n); - virtual int staticmembervariableHandler(Node *n); - - /* C++ handlers */ - - virtual int memberconstantHandler(Node *n); - virtual int constructorHandler(Node *n); - virtual int copyconstructorHandler(Node *n); - virtual int destructorHandler(Node *n); - virtual int classHandler(Node *n); - - /* Miscellaneous */ - - virtual int typedefHandler(Node *n); - - /* Low-level code generation */ - - virtual int constantWrapper(Node *n); - virtual int variableWrapper(Node *n); - virtual int functionWrapper(Node *n); - virtual int nativeWrapper(Node *n); - - /* C++ director class generation */ - virtual int classDirector(Node *n); - virtual int classDirectorInit(Node *n); - virtual int classDirectorEnd(Node *n); - virtual int unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase = 0); - virtual int classDirectorConstructor(Node *n); - virtual int classDirectorDefaultConstructor(Node *n); - virtual int classDirectorMethod(Node *n, Node *parent, String *super); - virtual int classDirectorConstructors(Node *n); - virtual int classDirectorDestructor(Node *n); - virtual int classDirectorMethods(Node *n); - virtual int classDirectorDisown(Node *n); - - /* Miscellaneous */ - virtual int validIdentifier(String *s); /* valid identifier? */ - virtual int addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope = ""); /* Add symbol */ - virtual int addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope = ""); - virtual void dumpSymbols(); - virtual Node *symbolLookup(const String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */ - virtual Hash* symbolAddScope(const_String_or_char_ptr scope); - virtual Hash* symbolScopeLookup(const_String_or_char_ptr scope); - virtual Hash* symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope); - static Node *classLookup(const SwigType *s); /* Class lookup */ - static Node *enumLookup(SwigType *s); /* Enum lookup */ - virtual int abstractClassTest(Node *n); /* Is class really abstract? */ - virtual int is_assignable(Node *n); /* Is variable assignable? */ - virtual String *runtimeCode(); /* returns the language specific runtime code */ - virtual String *defaultExternalRuntimeFilename(); /* the default filename for the external runtime */ - virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm); /* Language specific special variable substitutions for $typemap() */ - - /* Runtime is C++ based, so extern "C" header section */ - void enable_cplus_runtime_mode(); - - /* Returns the cplus_runtime mode */ - int cplus_runtime_mode(); - - /* Allow director related code generation */ - void allow_directors(int val = 1); - - /* Return true if directors are enabled */ - int directorsEnabled() const; - - /* Allow director protected members related code generation */ - void allow_dirprot(int val = 1); - - /* Allow all protected members code generation (for directors) */ - void allow_allprotected(int val = 0); - - /* Returns the dirprot mode */ - int dirprot_mode() const; - - /* Check if the non public constructor is needed (for directors) */ - int need_nonpublic_ctor(Node *n); - - /* Check if the non public member is needed (for directors) */ - int need_nonpublic_member(Node *n); - - /* Set none comparison string */ - void setSubclassInstanceCheck(String *s); - - /* Set overload variable templates argc and argv */ - void setOverloadResolutionTemplates(String *argc, String *argv); - - /* Language instance is a singleton - get instance */ - static Language* instance(); - -protected: - /* Allow multiple-input typemaps */ - void allow_multiple_input(int val = 1); - - /* Allow overloaded functions */ - void allow_overloading(int val = 1); - - /* Wrapping class query */ - int is_wrapping_class() const; - - /* Return the node for the current class */ - Node *getCurrentClass() const; - - /* Return C++ mode */ - int getCPlusMode() const; - - /* Return the namespace for the class/enum - the nspace feature */ - String *getNSpace() const; - - /* Return the real name of the current class */ - String *getClassName() const; - - /* Return the classes hash */ - Hash *getClassHash() const; - - /* Return the current class prefix */ - String *getClassPrefix() const; - - /* Return the current enum class prefix */ - String *getEnumClassPrefix() const; - - /* Fully qualified type name to use */ - String *getClassType() const; - - /* Return true if the current method is part of a smart-pointer */ - int is_smart_pointer() const; - - /* Return the name to use for the given parameter. */ - virtual String *makeParameterName(Node *n, Parm *p, int arg_num, bool setter = false) const; - - /* Some language modules require additional wrappers for virtual methods not declared in sub-classes */ - virtual bool extraDirectorProtectedCPPMethodsRequired() const; - -public: - enum NestedClassSupport { - NCS_None, // Target language does not have an equivalent to nested classes - NCS_Full, // Target language does have an equivalent to nested classes and is fully implemented - NCS_Unknown // Target language may or may not have an equivalent to nested classes. If it does, it has not been implemented yet. - }; - /* Does target language support nested classes? Default is NCS_Unknown. - If NCS_Unknown is returned, then the nested classes will be ignored unless - %feature "flatnested" is applied to them, in which case they will appear in global space. - If the target language does not support the notion of class - nesting, the language module should return NCS_None from this function, and - the nested classes will be moved to the global scope (like implicit global %feature "flatnested"). - */ - virtual NestedClassSupport nestedClassesSupport() const; - - /* Returns true if the target language supports key word arguments (kwargs) */ - virtual bool kwargsSupport() const; - -protected: - /* Identifies if a protected members that are generated when the allprotected option is used. - This does not include protected virtual methods as they are turned on with the dirprot option. */ - bool isNonVirtualProtectedAccess(Node *n) const; - - /* Identify if a wrapped global or member variable n should use the naturalvar feature */ - int use_naturalvar_mode(Node *n) const; - - /* Director subclass comparison test */ - String *none_comparison; - - /* Director constructor "template" code */ - String *director_ctor_code; - - /* Director 'protected' constructor "template" code */ - String *director_prot_ctor_code; - - /* Director allows multiple inheritance */ - int director_multiple_inheritance; - - /* Director language module */ - int director_language; - - /* Used to translate Doxygen comments to target documentation format */ - class DoxygenTranslator *doxygenTranslator; - -private: - void unrollOneVirtualMethod(String *classname, Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase); - - Hash *symtabs; /* symbol tables */ - int overloading; - int multiinput; - int cplus_runtime; - int directors; - static Language *this_; -}; - -extern "C" { - void SWIG_typemap_lang(const char *); - typedef Language *(*ModuleFactory) (void); -} - -enum Status {Disabled, Experimental, Supported}; - -struct TargetLanguageModule { - const char *name; - ModuleFactory fac; - const char *help; - Status status; -}; - -int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm); -void emit_parameter_variables(ParmList *l, Wrapper *f); -void emit_return_variable(Node *n, SwigType *rt, Wrapper *f); -void SWIG_config_file(const_String_or_char_ptr ); -const String *SWIG_output_directory(); -void SWIG_config_cppext(const char *ext); -void Swig_print_xml(Node *obj, String *filename); - -/* get the list of generated files */ -List *SWIG_output_files(); - -void SWIG_library_directory(const char *); -int emit_num_arguments(ParmList *); -int emit_num_required(ParmList *); -int emit_isvarargs(ParmList *p); -bool emit_isvarargs_function(Node *n); -void emit_attach_parmmaps(ParmList *, Wrapper *f); -void emit_mark_varargs(ParmList *l); -String *emit_action(Node *n); -int emit_action_code(Node *n, String *wrappercode, String *action); -void Swig_overload_check(Node *n); -String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *, const_String_or_char_ptr fmt_fastdispatch = 0); -String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *); -List *Swig_overload_rank(Node *n, bool script_lang_wrapping); -SwigType *cplus_value_type(SwigType *t); - -/* directors.cxx start */ -String *Swig_csuperclass_call(String *base, String *method, ParmList *l); -String *Swig_class_declaration(Node *n, String *name); -String *Swig_class_name(Node *n); -String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms); -String *Swig_method_decl(SwigType *return_base_type, SwigType *decl, const_String_or_char_ptr id, List *args, int default_args); -String *Swig_director_declaration(Node *n); -void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f); -void Swig_director_parms_fixup(ParmList *parms); -bool Swig_director_can_unwrap(Node *n); -/* directors.cxx end */ - -/* Utilities */ - -int is_public(Node *n); -int is_private(Node *n); -int is_protected(Node *n); -int is_member_director(Node *parentnode, Node *member); -int is_member_director(Node *member); -int is_non_virtual_protected_access(Node *n); /* Check if the non-virtual protected members are required (for directors) */ - -void Wrapper_virtual_elimination_mode_set(int); -void Wrapper_fast_dispatch_mode_set(int); -void Wrapper_cast_dispatch_mode_set(int); -void Wrapper_naturalvar_mode_set(int); - -void clean_overloaded(Node *n); - -extern "C" { - const char *Swig_to_string(DOH *object, int count = -1); - const char *Swig_to_string_with_location(DOH *object, int count = -1); - void Swig_print(DOH *object, int count = -1); - void Swig_print_with_location(DOH *object, int count = -1); -} - -void Swig_default_allocators(Node *n); -void Swig_process_types(Node *n); - -/* Contracts */ -void Swig_contracts(Node *n); -void Swig_contract_mode_set(int flag); -int Swig_contract_mode_get(); - -/* Nested classes */ -void Swig_nested_process_classes(Node *n); -void Swig_nested_name_unnamed_c_structs(Node *n); - -/* Interface feature */ -void Swig_interface_feature_enable(); -void Swig_interface_propagate_methods(Node *n); - -/* Miscellaneous */ -template <class T> class save_value { - T _value; - T& _value_ptr; - save_value(const save_value&); - save_value& operator=(const save_value&); - -public: - save_value(T& value) : _value(value), _value_ptr(value) {} - save_value(T& value, T new_val) : _value(value), _value_ptr(value) { value = new_val; } - ~save_value() { _value_ptr = _value; } -}; - -#endif diff --git a/contrib/tools/swig/Source/Modules/tcl8.cxx b/contrib/tools/swig/Source/Modules/tcl8.cxx deleted file mode 100644 index 975230e8495..00000000000 --- a/contrib/tools/swig/Source/Modules/tcl8.cxx +++ /dev/null @@ -1,1291 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * tcl8.cxx - * - * Tcl8 language module for SWIG. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" - -static const char *usage = "\ -Tcl 8 Options (available with -tcl8)\n\ - -itcl - Enable ITcl support\n\ - -nosafe - Leave out SafeInit module function.\n\ - -prefix <name> - Set a prefix <name> to be prepended to all names\n\ - -namespace - Build module into a Tcl 8 namespace\n\ - -pkgversion - Set package version\n\n"; - -static String *cmd_tab = 0; /* Table of command names */ -static String *var_tab = 0; /* Table of global variables */ -static String *const_tab = 0; /* Constant table */ -static String *methods_tab = 0; /* Methods table */ -static String *attr_tab = 0; /* Attribute table */ -static String *prefix = 0; -static String *module = 0; -static int namespace_option = 0; -static String *init_name = 0; -static String *ns_name = 0; -static int have_constructor; -static String *constructor_name; -static int have_destructor; -static int have_base_classes; -static String *destructor_action = 0; -static String *version = (String *) "0.0"; -static String *class_name = 0; - -static int have_attributes; -static int have_methods; -static int nosafe = 0; - -static File *f_header = 0; -static File *f_wrappers = 0; -static File *f_init = 0; -static File *f_begin = 0; -static File *f_runtime = 0; - - -// Itcl support -static int itcl = 0; -static File *f_shadow = 0; -static File *f_shadow_stubs = 0; - -static String *constructor = 0; -static String *destructor = 0; -static String *base_classes = 0; -static String *base_class_init = 0; -static String *methods = 0; -static String *imethods = 0; -static String *attributes = 0; -static String *attribute_traces = 0; -static String *iattribute_traces = 0; - - - -class TCL8:public Language { -public: - - /* ------------------------------------------------------------ - * TCL8::main() - * ------------------------------------------------------------ */ - - virtual void main(int argc, char *argv[]) { - - SWIG_library_directory("tcl"); - - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-prefix") == 0) { - if (argv[i + 1]) { - prefix = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else - Swig_arg_error(); - } else if (strcmp(argv[i], "-pkgversion") == 0) { - if (argv[i + 1]) { - version = NewString(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } - } else if (strcmp(argv[i], "-namespace") == 0) { - namespace_option = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-itcl") == 0) { - itcl = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nosafe") == 0) { - nosafe = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-help") == 0) { - fputs(usage, stdout); - } else if (strcmp(argv[i], "-cppcast") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]); - Swig_mark_arg(i); - } else if (strcmp(argv[i], "-nocppcast") == 0) { - Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]); - Swig_mark_arg(i); - Exit(EXIT_FAILURE); - } - } - } - - Preprocessor_define("SWIGTCL 1", 0); - // SWIGTCL8 is deprecated, and no longer documented. - Preprocessor_define("SWIGTCL8 1", 0); - SWIG_typemap_lang("tcl8"); - SWIG_config_file("tcl8.swg"); - allow_overloading(); - } - - /* ------------------------------------------------------------ - * top() - * ------------------------------------------------------------ */ - - virtual int top(Node *n) { - - /* Initialize all of the output files */ - String *outfile = Getattr(n, "outfile"); - - f_begin = NewFile(outfile, "w", SWIG_output_files()); - if (!f_begin) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - f_runtime = NewString(""); - f_init = NewString(""); - f_header = NewString(""); - f_wrappers = NewString(""); - - /* Register file targets with the SWIG file handler */ - Swig_register_filebyname("header", f_header); - Swig_register_filebyname("wrapper", f_wrappers); - Swig_register_filebyname("begin", f_begin); - Swig_register_filebyname("runtime", f_runtime); - Swig_register_filebyname("init", f_init); - - /* Initialize some variables for the object interface */ - - cmd_tab = NewString(""); - var_tab = NewString(""); - methods_tab = NewString(""); - const_tab = NewString(""); - - Swig_banner(f_begin); - - Swig_obligatory_macros(f_runtime, "TCL"); - - /* Set the module name, namespace, and prefix */ - - module = NewStringf("%(lower)s", Getattr(n, "name")); - init_name = NewStringf("%(title)s_Init", module); - - ns_name = prefix ? Copy(prefix) : Copy(module); - if (prefix) - Append(prefix, "_"); - - - /* If shadow classing is enabled, we're going to change the module name to "_module" */ - if (itcl) { - String *filen; - filen = NewStringf("%s%s.itcl", SWIG_output_directory(), module); - - Insert(module, 0, "_"); - - if ((f_shadow = NewFile(filen, "w", SWIG_output_files())) == 0) { - FileErrorDisplay(filen); - Exit(EXIT_FAILURE); - } - f_shadow_stubs = NewString(""); - - Swig_register_filebyname("shadow", f_shadow); - Swig_register_filebyname("itcl", f_shadow); - - Swig_banner_target_lang(f_shadow, "#"); - - Printv(f_shadow, "\npackage require Itcl\n\n", NIL); - Delete(filen); - } - - /* Generate some macros used throughout code generation */ - - Printf(f_header, "#define SWIG_init %s\n", init_name); - Printf(f_header, "#define SWIG_name \"%s\"\n", module); - if (namespace_option) { - Printf(f_header, "#define SWIG_prefix \"%s::\"\n", ns_name); - Printf(f_header, "#define SWIG_namespace \"%s\"\n\n", ns_name); - } else { - Printf(f_header, "#define SWIG_prefix \"%s\"\n", prefix); - } - Printf(f_header, "#define SWIG_version \"%s\"\n", version); - - Printf(cmd_tab, "\nstatic swig_command_info swig_commands[] = {\n"); - Printf(var_tab, "\nstatic swig_var_info swig_variables[] = {\n"); - Printf(const_tab, "\nstatic swig_const_info swig_constants[] = {\n"); - - Printf(f_wrappers, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); - - /* Start emitting code */ - Language::top(n); - - /* Done. Close up the module */ - Printv(cmd_tab, tab4, "{0, 0, 0}\n", "};\n", NIL); - Printv(var_tab, tab4, "{0,0,0,0}\n", "};\n", NIL); - Printv(const_tab, tab4, "{0,0,0,0,0,0}\n", "};\n", NIL); - - Printv(f_wrappers, cmd_tab, var_tab, const_tab, NIL); - - /* Dump the pointer equivalency table */ - SwigType_emit_type_table(f_runtime, f_wrappers); - - Printf(f_wrappers, "#ifdef __cplusplus\n}\n#endif\n"); - - /* Close the init function and quit */ - Printf(f_init, "return TCL_OK;\n}\n"); - - if (!nosafe) { - Printf(f_init, "SWIGEXPORT int %(title)s_SafeInit(Tcl_Interp *interp) {\n", module); - Printf(f_init, " return SWIG_init(interp);\n"); - Printf(f_init, "}\n"); - } - - if (itcl) { - Printv(f_shadow, f_shadow_stubs, "\n", NIL); - Delete(f_shadow); - } - - /* Close all of the files */ - Dump(f_runtime, f_begin); - Printv(f_begin, f_header, f_wrappers, NIL); - Wrapper_pretty_print(f_init, f_begin); - Delete(f_header); - Delete(f_wrappers); - Delete(f_init); - Delete(f_runtime); - Delete(f_begin); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * functionWrapper() - * ------------------------------------------------------------ */ - - virtual int functionWrapper(Node *n) { - String *name = Getattr(n, "name"); /* Like to get rid of this */ - String *iname = Getattr(n, "sym:name"); - SwigType *type = Getattr(n, "type"); - ParmList *parms = Getattr(n, "parms"); - String *overname = 0; - - Parm *p; - int i; - String *tm; - Wrapper *f; - String *incode, *cleanup, *outarg, *argstr, *args; - int num_arguments = 0; - int num_required = 0; - int varargs = 0; - - char source[64]; - - if (Getattr(n, "sym:overloaded")) { - overname = Getattr(n, "sym:overname"); - } else { - if (!addSymbol(iname, n)) - return SWIG_ERROR; - } - - incode = NewString(""); - cleanup = NewString(""); - outarg = NewString(""); - argstr = NewString("\""); - args = NewString(""); - - f = NewWrapper(); - -#ifdef SWIG_USE_RESULTOBJ - Wrapper_add_local(f, "resultobj", "Tcl_Obj *resultobj = NULL"); -#endif - - - String *wname = Swig_name_wrapper(iname); - if (overname) { - Append(wname, overname); - } - Setattr(n, "wrap:name", wname); - - Printv(f->def, "SWIGINTERN int\n ", wname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", NIL); - - // Emit all of the local variables for holding arguments. - emit_parameter_variables(parms, f); - - /* Attach standard typemaps */ - emit_attach_parmmaps(parms, f); - Setattr(n, "wrap:parms", parms); - - /* Get number of require and total arguments */ - num_arguments = emit_num_arguments(parms); - num_required = emit_num_required(parms); - varargs = emit_isvarargs(parms); - - /* Unmarshal parameters */ - - for (i = 0, p = parms; i < num_arguments; i++) { - /* Skip ignored arguments */ - - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - - SwigType *pt = Getattr(p, "type"); - String *ln = Getattr(p, "lname"); - - /* Produce string representations of the source and target arguments */ - sprintf(source, "objv[%d]", i + 1); - - if (i == num_required) - Putc('|', argstr); - if ((tm = Getattr(p, "tmap:in"))) { - String *parse = Getattr(p, "tmap:in:parse"); - if (!parse) { - Replaceall(tm, "$input", source); - Setattr(p, "emit:input", source); - - if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - - Putc('o', argstr); - Printf(args, ",(void *)0"); - if (i >= num_required) { - Printf(incode, "if (objc > %d) {\n", i + 1); - } - Printf(incode, "%s\n", tm); - if (i >= num_required) { - Printf(incode, "}\n"); - } - } else { - Printf(argstr, "%s", parse); - Printf(args, ",&%s", ln); - if (Strcmp(parse, "p") == 0) { - SwigType *lt = SwigType_ltype(pt); - SwigType_remember(pt); - if (Cmp(lt, "p.void") == 0) { - Printf(args, ",(void *)0"); - } else { - Printf(args, ",SWIGTYPE%s", SwigType_manglestr(pt)); - } - Delete(lt); - } - } - p = Getattr(p, "tmap:in:next"); - continue; - } else { - Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0)); - } - p = nextSibling(p); - } - - if (!varargs) { - Putc(':', argstr); - } else { - Putc(';', argstr); - /* If variable length arguments we need to emit the in typemap here */ - if (p && (tm = Getattr(p, "tmap:in"))) { - sprintf(source, "objv[%d]", i + 1); - Printf(incode, "if (objc > %d) {\n", i); - Replaceall(tm, "$input", source); - Printv(incode, tm, "\n", NIL); - Printf(incode, "}\n"); - } - } - - Printf(argstr, "%s\"", usage_string(Char(iname), type, parms)); - - Printv(f->code, "if (SWIG_GetArgs(interp, objc, objv,", argstr, args, ") == TCL_ERROR) SWIG_fail;\n", NIL); - - Printv(f->code, incode, NIL); - - /* Insert constraint checking code */ - for (p = parms; p;) { - if ((tm = Getattr(p, "tmap:check"))) { - Printv(f->code, tm, "\n", NIL); - p = Getattr(p, "tmap:check:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert cleanup code */ - for (i = 0, p = parms; p; i++) { - if (!checkAttribute(p, "tmap:in:numinputs", "0") - && !Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) { - if (Len(tm) != 0) { - Printv(cleanup, tm, "\n", NIL); - } - p = Getattr(p, "tmap:freearg:next"); - } else { - p = nextSibling(p); - } - } - - /* Insert argument output code */ - for (i = 0, p = parms; p; i++) { - if ((tm = Getattr(p, "tmap:argout"))) { -#ifdef SWIG_USE_RESULTOBJ - Replaceall(tm, "$result", "resultobj"); -#else - Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))"); -#endif - Replaceall(tm, "$arg", Getattr(p, "emit:input")); - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(outarg, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - - /* Now write code to make the function call */ - String *actioncode = emit_action(n); - - /* Need to redo all of this code (eventually) */ - - /* Return value if necessary */ - if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) { -#ifdef SWIG_USE_RESULTOBJ - Replaceall(tm, "$result", "resultobj"); -#else - Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))"); -#endif - if (GetFlag(n, "feature:new")) { - Replaceall(tm, "$owner", "SWIG_POINTER_OWN"); - } else { - Replaceall(tm, "$owner", "0"); - } - Printf(f->code, "%s\n", tm); - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), name); - } - emit_return_variable(n, type, f); - - /* Dump output argument code */ - Printv(f->code, outarg, NIL); - - /* Dump the argument cleanup code */ - Printv(f->code, cleanup, NIL); - - /* Look for any remaining cleanup */ - if (GetFlag(n, "feature:new")) { - if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - } - } - - if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) { - Printf(f->code, "%s\n", tm); - } -#ifdef SWIG_USE_RESULTOBJ - Printv(f->code, "if (resultobj) Tcl_SetObjResult(interp, resultobj);\n", NIL); -#endif - Printv(f->code, "return TCL_OK;\n", NIL); - Printv(f->code, "fail:\n", cleanup, "return TCL_ERROR;\n", NIL); - Printv(f->code, "}\n", NIL); - - /* Substitute the cleanup code */ - Replaceall(f->code, "$cleanup", cleanup); - Replaceall(f->code, "$symname", iname); - - /* Dump out the function */ - Wrapper_print(f, f_wrappers); - - if (!Getattr(n, "sym:overloaded")) { - /* Register the function with Tcl */ - Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", Swig_name_wrapper(iname), ", NULL},\n", NIL); - } else { - if (!Getattr(n, "sym:nextSibling")) { - /* Emit overloading dispatch function */ - - int maxargs; - String *dispatch = Swig_overload_dispatch(n, "return %s(clientData, interp, objc, argv - 1);", &maxargs); - - /* Generate a dispatch wrapper for all overloaded functions */ - - Wrapper *df = NewWrapper(); - String *dname = Swig_name_wrapper(iname); - - Printv(df->def, "SWIGINTERN int\n", dname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", NIL); - Printf(df->code, "Tcl_Obj *CONST *argv = objv+1;\n"); - Printf(df->code, "int argc = objc-1;\n"); - Printv(df->code, dispatch, "\n", NIL); - Node *sibl = n; - while (Getattr(sibl, "sym:previousSibling")) - sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up - String *protoTypes = NewString(""); - do { - String *fulldecl = Swig_name_decl(sibl); - Printf(protoTypes, "\n\" %s\\n\"", fulldecl); - Delete(fulldecl); - } while ((sibl = Getattr(sibl, "sym:nextSibling"))); - Printf(df->code, "Tcl_SetResult(interp,(char *) " - "\"Wrong number or type of arguments for overloaded function '%s'.\\n\"" - "\n\" Possible C/C++ prototypes are:\\n\"%s, TCL_STATIC);\n", iname, protoTypes); - Delete(protoTypes); - Printf(df->code, "return TCL_ERROR;\n"); - Printv(df->code, "}\n", NIL); - Wrapper_print(df, f_wrappers); - Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", dname, ", NULL},\n", NIL); - DelWrapper(df); - Delete(dispatch); - Delete(dname); - } - } - - Delete(incode); - Delete(cleanup); - Delete(outarg); - Delete(argstr); - Delete(args); - DelWrapper(f); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * variableWrapper() - * ------------------------------------------------------------ */ - - virtual int variableWrapper(Node *n) { - - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - SwigType *t = Getattr(n, "type"); - - String *setname = 0; - String *setfname = 0; - Wrapper *setf = 0, *getf = 0; - int readonly = 0; - String *tm; - - if (!addSymbol(iname, n)) - return SWIG_ERROR; - - /* Create a function for getting a variable */ - int addfail = 0; - getf = NewWrapper(); - String *getname = Swig_name_get(NSPACE_TODO, iname); - String *getfname = Swig_name_wrapper(getname); - Setattr(n, "wrap:name", getfname); - Printv(getf->def, "SWIGINTERN const char *", getfname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, char *name1, char *name2, int flags) {", NIL); - Wrapper_add_local(getf, "value", "Tcl_Obj *value = 0"); - if ((tm = Swig_typemap_lookup("varout", n, name, 0))) { - Replaceall(tm, "$result", "value"); - /* Printf(getf->code, "%s\n",tm); */ - addfail = emit_action_code(n, getf->code, tm); - Printf(getf->code, "if (value) {\n"); - Printf(getf->code, "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n"); - Printf(getf->code, "Tcl_DecrRefCount(value);\n"); - Printf(getf->code, "}\n"); - Printf(getf->code, "return NULL;\n"); - if (addfail) { - Append(getf->code, "fail:\n"); - Printf(getf->code, "return \"%s\";\n", iname); - } - Printf(getf->code, "}\n"); - Wrapper_print(getf, f_wrappers); - } else { - Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0)); - DelWrapper(getf); - return SWIG_NOWRAP; - } - DelWrapper(getf); - - /* Try to create a function setting a variable */ - if (is_assignable(n)) { - setf = NewWrapper(); - setname = Swig_name_set(NSPACE_TODO, iname); - setfname = Swig_name_wrapper(setname); - Setattr(n, "wrap:name", setfname); - if (setf) { - Printv(setf->def, "SWIGINTERN const char *", setfname, - "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, char *name1, char *name2 SWIGUNUSED, int flags) {", NIL); - Wrapper_add_local(setf, "value", "Tcl_Obj *value = 0"); - Wrapper_add_local(setf, "name1o", "Tcl_Obj *name1o = 0"); - - if ((tm = Swig_typemap_lookup("varin", n, name, 0))) { - Replaceall(tm, "$input", "value"); - Printf(setf->code, "name1o = Tcl_NewStringObj(name1,-1);\n"); - Printf(setf->code, "value = Tcl_ObjGetVar2(interp, name1o, 0, flags);\n"); - Printf(setf->code, "Tcl_DecrRefCount(name1o);\n"); - Printf(setf->code, "if (!value) SWIG_fail;\n"); - /* Printf(setf->code,"%s\n", tm); */ - emit_action_code(n, setf->code, tm); - Printf(setf->code, "return NULL;\n"); - Printf(setf->code, "fail:\n"); - Printf(setf->code, "return \"%s\";\n", iname); - Printf(setf->code, "}\n"); - Wrapper_print(setf, f_wrappers); - } else { - Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0)); - readonly = 1; - } - } - DelWrapper(setf); - } else { - readonly = 1; - } - - - Printv(var_tab, tab4, "{ SWIG_prefix \"", iname, "\", 0, (swig_variable_func) ", getfname, ",", NIL); - if (readonly) { - static int readonlywrap = 0; - if (!readonlywrap) { - Wrapper *ro = NewWrapper(); - Printf(ro->def, - "SWIGINTERN const char *swig_readonly(ClientData clientData SWIGUNUSED, Tcl_Interp *interp SWIGUNUSED, char *name1 SWIGUNUSED, char *name2 SWIGUNUSED, int flags SWIGUNUSED) {"); - Printv(ro->code, "return \"Variable is read-only\";\n", "}\n", NIL); - Wrapper_print(ro, f_wrappers); - readonlywrap = 1; - DelWrapper(ro); - } - Printf(var_tab, "(swig_variable_func) swig_readonly},\n"); - } else { - Printv(var_tab, "(swig_variable_func) ", setfname, "},\n", NIL); - } - Delete(getfname); - Delete(setfname); - Delete(setname); - Delete(getname); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constantWrapper() - * ------------------------------------------------------------ */ - - virtual int constantWrapper(Node *n) { - String *name = Getattr(n, "name"); - String *iname = Getattr(n, "sym:name"); - String *nsname = !namespace_option ? Copy(iname) : NewStringf("%s::%s", ns_name, iname); - SwigType *type = Getattr(n, "type"); - String *rawval = Getattr(n, "rawval"); - String *value = rawval ? rawval : Getattr(n, "value"); - String *tm; - - if (!addSymbol(iname, n)) - return SWIG_ERROR; - if (namespace_option) - Setattr(n, "sym:name", nsname); - - /* Special hook for member pointer */ - if (SwigType_type(type) == T_MPOINTER) { - String *wname = Swig_name_wrapper(iname); - Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type, wname), value); - value = Char(wname); - } - - if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) { - Replaceall(tm, "$value", value); - Replaceall(tm, "$nsname", nsname); - Printf(const_tab, "%s,\n", tm); - } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) { - Replaceall(tm, "$value", value); - Replaceall(tm, "$nsname", nsname); - Printf(f_init, "%s\n", tm); - } else { - Delete(nsname); - Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); - return SWIG_NOWRAP; - } - Delete(nsname); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * nativeWrapper() - * ------------------------------------------------------------ */ - - virtual int nativeWrapper(Node *n) { - String *name = Getattr(n, "sym:name"); - String *funcname = Getattr(n, "wrap:name"); - if (!addSymbol(funcname, n)) - return SWIG_ERROR; - - Printf(f_init, "\t Tcl_CreateObjCommand(interp, SWIG_prefix \"%s\", (swig_wrapper_func) %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n", name, - funcname); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * classHandler() - * ------------------------------------------------------------ */ - - virtual int classHandler(Node *n) { - static Hash *emitted = NewHash(); - String *mangled_classname = 0; - String *real_classname = 0; - - have_constructor = 0; - have_destructor = 0; - destructor_action = 0; - constructor_name = 0; - - if (itcl) { - constructor = NewString(""); - destructor = NewString(""); - base_classes = NewString(""); - base_class_init = NewString(""); - methods = NewString(""); - imethods = NewString(""); - attributes = NewString(""); - attribute_traces = NewString(""); - iattribute_traces = NewString(""); - - have_base_classes = 0; - have_methods = 0; - have_attributes = 0; - } - - class_name = Getattr(n, "sym:name"); - if (!addSymbol(class_name, n)) - return SWIG_ERROR; - - real_classname = Getattr(n, "name"); - mangled_classname = Swig_name_mangle(real_classname); - - if (Getattr(emitted, mangled_classname)) - return SWIG_NOWRAP; - Setattr(emitted, mangled_classname, "1"); - - attr_tab = NewString(""); - Printf(attr_tab, "static swig_attribute swig_"); - Printv(attr_tab, mangled_classname, "_attributes[] = {\n", NIL); - - methods_tab = NewStringf(""); - Printf(methods_tab, "static swig_method swig_"); - Printv(methods_tab, mangled_classname, "_methods[] = {\n", NIL); - - /* Generate normal wrappers */ - Language::classHandler(n); - - SwigType *t = Copy(Getattr(n, "name")); - SwigType_add_pointer(t); - - // Catch all: eg. a class with only static functions and/or variables will not have 'remembered' - // SwigType_remember(t); - String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname); - SwigType_remember_clientdata(t, wrap_class); - - String *rt = Copy(getClassType()); - SwigType_add_pointer(rt); - - // Register the class structure with the type checker - /* Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_classname); */ - if (have_destructor) { - Printv(f_wrappers, "SWIGINTERN void swig_delete_", class_name, "(void *obj) {\n", NIL); - if (destructor_action) { - Printv(f_wrappers, SwigType_str(rt, "arg1"), " = (", SwigType_str(rt, 0), ") obj;\n", NIL); - Printv(f_wrappers, destructor_action, "\n", NIL); - } else { - if (CPlusPlus) { - Printv(f_wrappers, " delete (", SwigType_str(rt, 0), ") obj;\n", NIL); - } else { - Printv(f_wrappers, " free((char *) obj);\n", NIL); - } - } - Printf(f_wrappers, "}\n"); - } - - Printf(methods_tab, " {0,0}\n};\n"); - Printv(f_wrappers, methods_tab, NIL); - - Printf(attr_tab, " {0,0,0}\n};\n"); - Printv(f_wrappers, attr_tab, NIL); - - /* Handle inheritance */ - - String *base_class = NewString(""); - String *base_class_names = NewString(""); - - if (itcl) { - base_classes = NewString(""); - } - - List *baselist = Getattr(n, "bases"); - if (baselist && Len(baselist)) { - Iterator b; - int index = 0; - b = First(baselist); - while (b.item) { - String *bname = Getattr(b.item, "name"); - if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) { - b = Next(b); - continue; - } - if (itcl) { - have_base_classes = 1; - Printv(base_classes, bname, " ", NIL); - Printv(base_class_init, " ", bname, "Ptr::constructor $ptr\n", NIL); - } - String *bmangle = Swig_name_mangle(bname); - // Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL); - // Printf(base_class,"&_wrap_class_%s",bmangle); - Printf(base_class, "0"); - Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname)); - /* Put code to register base classes in init function */ - - //Printf(f_init,"/* Register base : %s */\n", bmangle); - //Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n", mangled_classname, index, SwigType_namestr(bname)); - (void)index; - b = Next(b); - index++; - Putc(',', base_class); - Delete(bmangle); - } - } - - if (itcl) { - String *ptrclass = NewString(""); - - // First, build the pointer base class - Printv(ptrclass, "itcl::class ", class_name, "Ptr {\n", NIL); - if (have_base_classes) - Printv(ptrclass, " inherit ", base_classes, "\n", NIL); - - // Define protected variables for SWIG object pointer - Printv(ptrclass, " protected variable swigobj\n", " protected variable thisown\n", NIL); - - // Define public variables - if (have_attributes) { - Printv(ptrclass, attributes, NIL); - - // base class swig_getset was being called for complex inheritance trees - if (namespace_option) { - - Printv(ptrclass, " protected method ", class_name, "_swig_getset {var name1 name2 op} {\n", NIL); - - Printv(ptrclass, - " switch -exact -- $op {\n", - " r {set $var [", ns_name, "::", class_name, "_[set var]_get $swigobj]}\n", - " w {", ns_name, "::", class_name, "_${var}_set $swigobj [set $var]}\n", " }\n", " }\n", NIL); - } else { - Printv(ptrclass, - " protected method ", class_name, "_swig_getset {var name1 name2 op} {\n", - " switch -exact -- $op {\n", - " r {set $var [", class_name, "_[set var]_get $swigobj]}\n", - " w {", class_name, "_${var}_set $swigobj [set $var]}\n", " }\n", " }\n", NIL); - } - } - // Add the constructor, which may include - // calls to base class class constructors - - Printv(ptrclass, " constructor { ptr } {\n", NIL); - if (have_base_classes) { - Printv(ptrclass, base_class_init, NIL); - Printv(ptrclass, " } {\n", NIL); - } - - Printv(ptrclass, " set swigobj $ptr\n", " set thisown 0\n", NIL); - - if (have_attributes) { - Printv(ptrclass, attribute_traces, NIL); - } - Printv(ptrclass, " }\n", NIL); - - - // Add destructor - Printv(ptrclass, " destructor {\n", - " set d_func delete_", class_name, "\n", - " if { $thisown && ([info command $d_func] != \"\") } {\n" " $d_func $swigobj\n", " }\n", " }\n", NIL); - - // Add methods - if (have_methods) { - Printv(ptrclass, imethods, NIL); - } - - // Close out the pointer class - Printv(ptrclass, "}\n\n", NIL); - Printv(f_shadow, ptrclass, NIL); - // pointer class end - - - // Create the "real" class. - Printv(f_shadow, "itcl::class ", class_name, " {\n", NIL); - Printv(f_shadow, " inherit ", class_name, "Ptr\n", NIL); - - // If we have a constructor, then use it. - // If not, then we must have an abstract class without - // any constructor. So we create a class constructor - // which will fail for this class (but not for inherited - // classes). Note that the constructor must fail before - // calling the ptrclass constructor. - - if (have_constructor) { - Printv(f_shadow, constructor, NIL); - } else { - Printv(f_shadow, " constructor { } {\n", NIL); - Printv(f_shadow, " # This constructor will fail if called directly\n", NIL); - Printv(f_shadow, " if { [info class] == \"::", class_name, "\" } {\n", NIL); - Printv(f_shadow, " error \"No constructor for class ", class_name, (Getattr(n, "abstracts") ? " - class is abstract" : ""), "\"\n", NIL); - Printv(f_shadow, " }\n", NIL); - Printv(f_shadow, " }\n", NIL); - } - - Printv(f_shadow, "}\n\n", NIL); - } - - Printv(f_wrappers, "static swig_class *swig_", mangled_classname, "_bases[] = {", base_class, "0};\n", NIL); - Printv(f_wrappers, "static const char * swig_", mangled_classname, "_base_names[] = {", base_class_names, "0};\n", NIL); - Delete(base_class); - Delete(base_class_names); - - Printv(f_wrappers, "static swig_class _wrap_class_", mangled_classname, " = { \"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL); - - if (have_constructor) { - Printf(f_wrappers, "%s", Swig_name_wrapper(Swig_name_construct(NSPACE_TODO, constructor_name))); - Delete(constructor_name); - constructor_name = 0; - } else { - Printf(f_wrappers, "0"); - } - if (have_destructor) { - Printv(f_wrappers, ", swig_delete_", class_name, NIL); - } else { - Printf(f_wrappers, ",0"); - } - Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname, "_bases,", - "swig_", mangled_classname, "_base_names, &swig_module, SWIG_TCL_HASHTABLE_INIT };\n", NIL); - - if (!itcl) { - Printv(cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, (ClientData)&_wrap_class_", mangled_classname, - "},\n", NIL); - } - - Delete(t); - Delete(mangled_classname); - return SWIG_OK; - } - - - /* ------------------------------------------------------------ - * memberfunctionHandler() - * ------------------------------------------------------------ */ - - virtual int memberfunctionHandler(Node *n) { - String *name = Getattr(n, "name"); - String *iname = GetChar(n, "sym:name"); - - String *realname, *rname; - - Language::memberfunctionHandler(n); - - realname = iname ? iname : name; - rname = Swig_name_wrapper(Swig_name_member(NSPACE_TODO, class_name, realname)); - if (!Getattr(n, "sym:nextSibling")) { - Printv(methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL); - } - - if (itcl) { - ParmList *l = Getattr(n, "parms"); - Parm *p = 0; - String *pname = NewString(""); - - // Add this member to our class handler function - Printv(imethods, tab2, "method ", realname, " [list ", NIL); - - int pnum = 0; - for (p = l; p; p = nextSibling(p)) { - - String *pn = Getattr(p, "name"); - String *dv = Getattr(p, "value"); - SwigType *pt = Getattr(p, "type"); - - Printv(pname, ",(", pt, ")", NIL); - Clear(pname); - - /* Only print an argument if not void */ - if (Cmp(pt, "void") != 0) { - if (Len(pn) > 0) { - Printv(pname, pn, NIL); - } else { - Printf(pname, "p%d", pnum); - } - - if (Len(dv) > 0) { - String *defval = NewString(dv); - if (namespace_option) { - Insert(defval, 0, "::"); - Insert(defval, 0, ns_name); - } - if (Strncmp(dv, "(", 1) == 0) { - Insert(defval, 0, "$"); - Replaceall(defval, "(", ""); - Replaceall(defval, ")", ""); - } - Printv(imethods, "[list ", pname, " ", defval, "] ", NIL); - } else { - Printv(imethods, pname, " ", NIL); - } - } - ++pnum; - } - Printv(imethods, "] ", NIL); - - if (namespace_option) { - Printv(imethods, "{ ", ns_name, "::", class_name, "_", realname, " $swigobj", NIL); - } else { - Printv(imethods, "{ ", class_name, "_", realname, " $swigobj", NIL); - } - - pnum = 0; - for (p = l; p; p = nextSibling(p)) { - - String *pn = Getattr(p, "name"); - SwigType *pt = Getattr(p, "type"); - Clear(pname); - - /* Only print an argument if not void */ - if (Cmp(pt, "void") != 0) { - if (Len(pn) > 0) { - Printv(pname, pn, NIL); - } else { - Printf(pname, "p%d", pnum); - } - Printv(imethods, " $", pname, NIL); - } - ++pnum; - } - Printv(imethods, " }\n", NIL); - have_methods = 1; - } - - Delete(rname); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * membervariableHandler() - * ------------------------------------------------------------ */ - - virtual int membervariableHandler(Node *n) { - String *symname = Getattr(n, "sym:name"); - String *rname; - - Language::membervariableHandler(n); - Printv(attr_tab, tab4, "{ \"-", symname, "\",", NIL); - rname = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname))); - Printv(attr_tab, rname, ", ", NIL); - Delete(rname); - if (!GetFlag(n, "feature:immutable")) { - rname = Swig_name_wrapper(Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname))); - Printv(attr_tab, rname, "},\n", NIL); - Delete(rname); - } else { - Printf(attr_tab, "0 },\n"); - } - - if (itcl) { - Printv(attributes, " public variable ", symname, "\n", NIL); - - Printv(attribute_traces, " trace variable ", symname, " rw [list ", class_name, "_swig_getset ", symname, "]\n", NIL); - Printv(attribute_traces, " set ", symname, "\n", NIL); - - have_attributes = 1; - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constructorHandler() - * ------------------------------------------------------------ */ - - virtual int constructorHandler(Node *n) { - Language::constructorHandler(n); - - if (itcl) { - String *name = Getattr(n, "name"); - String *iname = GetChar(n, "sym:name"); - - String *realname; - - ParmList *l = Getattr(n, "parms"); - Parm *p = 0; - - String *pname = NewString(""); - - realname = iname ? iname : name; - - if (!have_constructor) { - // Add this member to our class handler function - Printf(constructor, " constructor { "); - - // Add parameter list - int pnum = 0; - for (p = l; p; p = nextSibling(p)) { - - SwigType *pt = Getattr(p, "type"); - String *pn = Getattr(p, "name"); - String *dv = Getattr(p, "value"); - Clear(pname); - - /* Only print an argument if not void */ - if (Cmp(pt, "void") != 0) { - if (Len(pn) > 0) { - Printv(pname, pn, NIL); - } else { - Printf(pname, "p%d", pnum); - } - - if (Len(dv) > 0) { - Printv(constructor, "{", pname, " {", dv, "} } ", NIL); - } else { - Printv(constructor, pname, " ", NIL); - } - } - ++pnum; - } - Printf(constructor, "} { \n"); - - // [BRE] 08/17/00 Added test to see if we are instantiating this object - // type, or, if this constructor is being called as part of the itcl - // inheritance hierarchy. - // In the former case, we need to call the C++ constructor, in the - // latter we don't, or we end up with two C++ objects. - // Check to see if we are instantiating a 'realname' or something - // derived from it. - // - Printv(constructor, " if { [string equal -nocase \"", realname, "\" \"[namespace tail [info class]]\" ] } {\n", NIL); - - // Call to constructor wrapper and parent Ptr class - // [BRE] add -namespace/-prefix support - - if (namespace_option) { - Printv(constructor, " ", realname, "Ptr::constructor [", ns_name, "::new_", realname, NIL); - } else { - Printv(constructor, " ", realname, "Ptr::constructor [new_", realname, NIL); - } - - pnum = 0; - for (p = l; p; p = nextSibling(p)) { - - SwigType *pt = Getattr(p, "type"); - String *pn = Getattr(p, "name"); - Clear(pname); - - /* Only print an argument if not void */ - if (Cmp(pt, "void") != 0) { - if (Len(pn) > 0) { - Printv(pname, pn, NIL); - } else { - Printf(pname, "p%d", pnum); - } - Printv(constructor, " $", pname, NIL); - } - ++pnum; - } - - Printv(constructor, "]\n", " }\n", " } {\n", " set thisown 1\n", " }\n", NIL); - } - } - - if (!have_constructor) - constructor_name = NewString(Getattr(n, "sym:name")); - have_constructor = 1; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * destructorHandler() - * ------------------------------------------------------------ */ - - virtual int destructorHandler(Node *n) { - Language::destructorHandler(n); - have_destructor = 1; - destructor_action = Getattr(n, "wrap:action"); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * validIdentifier() - * ------------------------------------------------------------ */ - - virtual int validIdentifier(String *s) { - if (Strchr(s, ' ')) - return 0; - return 1; - } - - /* ------------------------------------------------------------ - * usage_string() - * ------------------------------------------------------------ */ - - char *usage_string(char *iname, SwigType *, ParmList *l) { - static String *temp = 0; - Parm *p; - int i, numopt, pcount; - - if (!temp) - temp = NewString(""); - Clear(temp); - if (namespace_option) { - Printf(temp, "%s::%s ", ns_name, iname); - } else { - Printf(temp, "%s ", iname); - } - /* Now go through and print parameters */ - i = 0; - pcount = emit_num_arguments(l); - numopt = pcount - emit_num_required(l); - for (p = l; p; p = nextSibling(p)) { - - SwigType *pt = Getattr(p, "type"); - String *pn = Getattr(p, "name"); - /* Only print an argument if not ignored */ - if (!checkAttribute(p, "tmap:in:numinputs", "0")) { - if (i >= (pcount - numopt)) - Putc('?', temp); - if (Len(pn) > 0) { - Printf(temp, "%s", pn); - } else { - Printf(temp, "%s", SwigType_str(pt, 0)); - } - if (i >= (pcount - numopt)) - Putc('?', temp); - Putc(' ', temp); - i++; - } - } - return Char(temp); - } - - String *runtimeCode() { - String *s = NewString(""); - String *serrors = Swig_include_sys("tclerrors.swg"); - if (!serrors) { - Printf(stderr, "*** Unable to open 'tclerrors.swg'\n"); - } else { - Append(s, serrors); - Delete(serrors); - } - String *sapi = Swig_include_sys("tclapi.swg"); - if (!sapi) { - Printf(stderr, "*** Unable to open 'tclapi.swg'\n"); - } else { - Append(s, sapi); - Delete(sapi); - } - String *srun = Swig_include_sys("tclrun.swg"); - if (!srun) { - Printf(stderr, "*** Unable to open 'tclrun.swg'\n"); - } else { - Append(s, srun); - Delete(srun); - } - - return s; - } - - String *defaultExternalRuntimeFilename() { - return NewString("swigtclrun.h"); - } -}; - -/* ---------------------------------------------------------------------- - * swig_tcl() - Instantiate module - * ---------------------------------------------------------------------- */ - -static Language *new_swig_tcl() { - return new TCL8(); -} -extern "C" Language *swig_tcl(void) { - return new_swig_tcl(); -} diff --git a/contrib/tools/swig/Source/Modules/typepass.cxx b/contrib/tools/swig/Source/Modules/typepass.cxx deleted file mode 100644 index 2a1dadf735d..00000000000 --- a/contrib/tools/swig/Source/Modules/typepass.cxx +++ /dev/null @@ -1,1322 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * typepass.cxx - * - * This module builds all of the internal type information by collecting - * typedef declarations as well as registering classes, structures, and unions. - * This information is needed to correctly handle shadow classes and other - * advanced features. This phase of compilation is also used to perform - * type-expansion. All types are fully qualified with namespace prefixes - * and other information needed for compilation. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" -#include "cparse.h" - -struct normal_node { - Symtab *symtab; - Hash *typescope; - List *normallist; - normal_node *next; -}; - -static normal_node *patch_list = 0; - -/* Singleton class - all non-static methods in this class are private */ -class TypePass:private Dispatcher { - Node *inclass; - Node *module; - int importmode; - String *nsname; - String *nssymname; - Hash *classhash; - List *normalize; - - TypePass() : - inclass(0), - module(0), - importmode(0), - nsname(0), - nssymname(0), - classhash(0), - normalize(0) { - } - - /* Normalize a type. Replaces type with fully qualified version */ - void normalize_type(SwigType *ty) { - SwigType *qty; - if (CPlusPlus) { - Replaceall(ty, "struct ", ""); - Replaceall(ty, "union ", ""); - Replaceall(ty, "class ", ""); - } - - qty = SwigType_typedef_qualified(ty); - /* Printf(stdout,"%s --> %s\n", ty, qty); */ - Clear(ty); - Append(ty, qty); - Delete(qty); - } - - /* Normalize a parameter list */ - - void normalize_parms(ParmList *p) { - while (p) { - SwigType *ty = Getattr(p, "type"); - normalize_type(ty); - /* This is a check for a function type */ - { - SwigType *qty = SwigType_typedef_resolve_all(ty); - if (SwigType_isfunction(qty)) { - SwigType_add_pointer(ty); - } - Delete(qty); - } - - String *value = Getattr(p, "value"); - if (value) { - Node *n = Swig_symbol_clookup(value, 0); - if (n) { - String *q = Swig_symbol_qualified(n); - if (q && Len(q)) { - String *vb = Swig_scopename_last(value); - Clear(value); - Printf(value, "%s::%s", SwigType_namestr(q), vb); - Delete(q); - } - } - } - if (value && SwigType_istemplate(value)) { - String *nv = SwigType_namestr(value); - Setattr(p, "value", nv); - } - p = nextSibling(p); - } - } - - void normalize_later(ParmList *p) { - while (p) { - SwigType *ty = Getattr(p, "type"); - Append(normalize, ty); - p = nextSibling(p); - } - } - - /* Walk through entries in normalize list and patch them up */ - void normalize_list() { - Hash *currentsym = Swig_symbol_current(); - - normal_node *nn = patch_list; - normal_node *np; - while (nn) { - Swig_symbol_setscope(nn->symtab); - SwigType_set_scope(nn->typescope); - Iterator t; - for (t = First(nn->normallist); t.item; t = Next(t)) { - normalize_type(t.item); - } - Delete(nn->normallist); - np = nn->next; - delete(nn); - nn = np; - } - Swig_symbol_setscope(currentsym); - } - - /* generate C++ inheritance type-relationships */ - void cplus_inherit_types_impl(Node *first, Node *cls, String *clsname, const char *bases, const char *baselist, int ispublic, String *cast = 0) { - - if (first == cls) - return; /* The Marcelo check */ - if (!cls) - cls = first; - List *alist = 0; - List *ilist = Getattr(cls, bases); - if (!ilist) { - List *nlist = Getattr(cls, baselist); - if (nlist) { - int len = Len(nlist); - int i; - for (i = 0; i < len; i++) { - Node *bcls = 0; - int clsforward = 0; - String *bname = Getitem(nlist, i); - String *sname = bname; - String *tname = 0; - - /* Try to locate the base class. We look in the symbol table and we chase - typedef declarations to get to the base class if necessary */ - Symtab *st = Getattr(cls, "sym:symtab"); - - if (SwigType_istemplate(bname)) { - tname = SwigType_typedef_resolve_all(bname); - sname = tname; - } - while (1) { - String *qsname = SwigType_typedef_qualified(sname); - bcls = Swig_symbol_clookup(qsname, st); - Delete(qsname); - if (bcls) { - if (Strcmp(nodeType(bcls), "class") != 0) { - /* Not a class. The symbol could be a typedef. */ - if (checkAttribute(bcls, "storage", "typedef")) { - SwigType *decl = Getattr(bcls, "decl"); - if (!decl || !(Len(decl))) { - sname = Getattr(bcls, "type"); - st = Getattr(bcls, "sym:symtab"); - if (SwigType_istemplate(sname)) { - if (tname) - Delete(tname); - tname = SwigType_typedef_resolve_all(sname); - sname = tname; - } - continue; - } - // A case when both outer and nested classes inherit from the same parent. Constructor may be found instead of the class itself. - } else if (GetFlag(cls, "nested") && checkAttribute(bcls, "nodeType", "constructor")) { - bcls = Getattr(bcls, "parentNode"); - if (Getattr(bcls, "typepass:visit")) { - if (!Getattr(bcls, "feature:onlychildren")) { - if (!ilist) - ilist = alist = NewList(); - Append(ilist, bcls); - } else { - if (!GetFlag(bcls, "feature:ignore")) { - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname)); - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname)); - } - } - } - break; - } - if (Strcmp(nodeType(bcls), "classforward") != 0) { - Swig_error(Getfile(bname), Getline(bname), "'%s' is not a valid base class.\n", SwigType_namestr(bname)); - Swig_error(Getfile(bcls), Getline(bcls), "See definition of '%s'.\n", SwigType_namestr(bname)); - } else { - Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bname), Getline(bname), "Base class '%s' is incomplete.\n", SwigType_namestr(bname)); - Swig_warning(WARN_TYPE_INCOMPLETE, Getfile(bcls), Getline(bcls), "Only forward declaration '%s' was found.\n", SwigType_namestr(bname)); - clsforward = 1; - } - bcls = 0; - } else { - if (Getattr(bcls, "typepass:visit")) { - if (!Getattr(bcls, "feature:onlychildren")) { - if (!ilist) - ilist = alist = NewList(); - Append(ilist, bcls); - } else { - if (!GetFlag(bcls, "feature:ignore")) { - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' has no name as it is an empty template instantiated with '%%template()'. Ignored.\n", SwigType_namestr(bname)); - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "The %%template directive must be written before '%s' is used as a base class and be declared with a name.\n", SwigType_namestr(bname)); - } - } - } else { - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Base class '%s' undefined.\n", SwigType_namestr(bname)); - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bcls), Getline(bcls), "'%s' must be defined before it is used as a base class.\n", SwigType_namestr(bname)); - } - } - } - break; - } - - if (tname) - Delete(tname); - if (!bcls) { - if (!clsforward && !GetFlag(cls, "feature:ignore")) { - if (ispublic && !Getmeta(bname, "already_warned")) { - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Nothing known about base class '%s'. Ignored.\n", SwigType_namestr(bname)); - if (Strchr(bname, '<')) { - Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Maybe you forgot to instantiate '%s' using %%template.\n", SwigType_namestr(bname)); - } - Setmeta(bname, "already_warned", "1"); - } - } - SwigType_inherit(clsname, bname, cast, 0); - } - } - } - if (ilist) { - Setattr(cls, bases, ilist); - } - } - if (alist) - Delete(alist); - - if (!ilist) - return; - int len = Len(ilist); - int i; - for (i = 0; i < len; i++) { - Node *n = Getitem(ilist, i); - String *bname = Getattr(n, "name"); - Node *bclass = n; /* Getattr(n,"class"); */ - Hash *scopes = Getattr(bclass, "typescope"); - SwigType_inherit(clsname, bname, cast, 0); - if (ispublic && !GetFlag(bclass, "feature:ignore")) { - String *smartptr = Getattr(first, "feature:smartptr"); - if (smartptr) { - SwigType *smart = Swig_cparse_smartptr(first); - if (smart) { - /* Record a (fake) inheritance relationship between smart pointer - and smart pointer to base class, so that smart pointer upcasts - are automatically generated. */ - SwigType *bsmart = Copy(smart); - - // TODO: SwigType_typedef_resolve_all on a String instead of SwigType is incorrect for templates - SwigType *rclsname = SwigType_typedef_resolve_all(clsname); - SwigType *rbname = SwigType_typedef_resolve_all(bname); - int replace_count = Replaceall(bsmart, rclsname, rbname); - if (replace_count == 0) { - // If no replacement made, it will be because rclsname is fully resolved, but the - // type in the smartptr feature used a typedef or not fully resolved name. - String *firstname = Getattr(first, "name"); - Replaceall(bsmart, firstname, rbname); - } - // The code above currently creates a smartptr of the base class by substitution, replacing Derived - // with Base resulting in something like: 'smartptr< Derived >' from 'smartptr< Base >'. Instead - // the feature:smartptr should be used as it also contains 'smartptr< Base >' as specified by the user. - // A similar fix should also be done in upcastsCode in java.cxx, csharp.cxx and writeClassUpcast in d.cxx. - // Printf(stdout, "smartcomparison %s <=> %s\n", SwigType_namestr(bsmart), Getattr(bclass, "feature:smartptr")); - - Delete(rclsname); - Delete(rbname); - String *smartnamestr = SwigType_namestr(smart); - String *bsmartnamestr = SwigType_namestr(bsmart); - /* construct casting code */ - String *convcode = NewStringf("\n *newmemory = SWIG_CAST_NEW_MEMORY;\n return (void *) new %s(*(%s *)$from);\n", bsmartnamestr, smartnamestr); - Delete(bsmartnamestr); - Delete(smartnamestr); - /* setup inheritance relationship between smart pointer templates */ - SwigType_inherit(smart, bsmart, 0, convcode); - if (!GetFlag(bclass, "feature:smartptr")) - Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name"))); - Delete(convcode); - Delete(bsmart); - } - Delete(smart); - } else { - if (GetFlag(bclass, "feature:smartptr")) - Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Derived class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(first, "name")), SwigType_namestr(Getattr(bclass, "name"))); - } - } - if (!importmode) { - String *btype = Copy(bname); - SwigType_add_pointer(btype); - SwigType_remember(btype); - Delete(btype); - } - if (scopes) { - SwigType_inherit_scope(scopes); - } - /* Set up inheritance in the symbol table */ - Symtab *st = Getattr(cls, "symtab"); - Symtab *bst = Getattr(bclass, "symtab"); - if (st == bst) { - Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(cls), Getline(cls), "Recursive scope inheritance of '%s'.\n", SwigType_namestr(Getattr(cls, "name"))); - continue; - } - Symtab *s = Swig_symbol_current(); - Swig_symbol_setscope(st); - Swig_symbol_inherit(bst); - Swig_symbol_setscope(s); - - /* Recursively hit base classes */ - String *namestr = SwigType_namestr(Getattr(bclass, "name")); - String *newcast = NewStringf("(%s *)%s", namestr, cast); - Delete(namestr); - cplus_inherit_types_impl(first, bclass, clsname, bases, baselist, ispublic, newcast); - Delete(newcast); - } - } - - void append_list(List *lb, List *la) { - if (la && lb) { - for (Iterator bi = First(la); bi.item; bi = Next(bi)) { - Append(lb, bi.item); - } - } - } - - void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) { - cplus_inherit_types_impl(first, cls, clsname, "bases", "baselist", 1, cast); - cplus_inherit_types_impl(first, cls, clsname, "protectedbases", "protectedbaselist", 0, cast); - cplus_inherit_types_impl(first, cls, clsname, "privatebases", "privatebaselist", 0, cast); - - if (!cls) - cls = first; - - List *allbases = NewList(); - append_list(allbases, Getattr(cls, "bases")); - append_list(allbases, Getattr(cls, "protectedbases")); - append_list(allbases, Getattr(cls, "privatebases")); - if (Len(allbases)) { - Setattr(cls, "allbases", allbases); - } - Delete(allbases); - } - - /* ------------------------------------------------------------ - * top() - * ------------------------------------------------------------ */ - - virtual int top(Node *n) { - importmode = 0; - module = Getattr(n, "module"); - inclass = 0; - normalize = 0; - nsname = 0; - nssymname = 0; - classhash = Getattr(n, "classes"); - emit_children(n); - normalize_list(); - SwigType_set_scope(0); - return SWIG_OK; - } - - - /* ------------------------------------------------------------ - * moduleDirective() - * ------------------------------------------------------------ */ - - virtual int moduleDirective(Node *n) { - if (!module) { - module = n; - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * importDirective() - * ------------------------------------------------------------ */ - - virtual int importDirective(Node *n) { - String *oldmodule = module; - int oldimport = importmode; - importmode = 1; - module = 0; - emit_children(n); - importmode = oldimport; - module = oldmodule; - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * includeDirective() - * externDirective() - * extendDirective() - * ------------------------------------------------------------ */ - - virtual int includeDirective(Node *n) { - return emit_children(n); - } - virtual int externDeclaration(Node *n) { - return emit_children(n); - } - virtual int extendDirective(Node *n) { - return emit_children(n); - } - - /* ------------------------------------------------------------ - * classDeclaration() - * ------------------------------------------------------------ */ - - virtual int classDeclaration(Node *n) { - String *name = Getattr(n, "name"); - String *tdname = Getattr(n, "tdname"); - String *unnamed = Getattr(n, "unnamed"); - String *storage = Getattr(n, "storage"); - String *kind = Getattr(n, "kind"); - save_value<Node*> oldinclass(inclass); - List *olist = normalize; - Symtab *symtab; - String *nname = 0; - String *fname = 0; - String *scopename = 0; - String *template_default_expanded = 0; - - normalize = NewList(); - - if (name) { - if (SwigType_istemplate(name)) { - // We need to fully resolve the name and expand default template parameters to make templates work correctly */ - Node *cn; - SwigType *resolved_name = SwigType_typedef_resolve_all(name); - SwigType *deftype_name = Swig_symbol_template_deftype(resolved_name, 0); - fname = Copy(resolved_name); - if (!Equal(resolved_name, deftype_name)) - template_default_expanded = Copy(deftype_name); - if (!Equal(fname, name) && (cn = Swig_symbol_clookup_local(fname, 0))) { - if ((n == cn) - || (Strcmp(nodeType(cn), "template") == 0) - || (Getattr(cn, "feature:onlychildren") != 0) - || (Getattr(n, "feature:onlychildren") != 0)) { - Swig_symbol_cadd(fname, n); - if (template_default_expanded) - Swig_symbol_cadd(template_default_expanded, n); - SwigType_typedef_class(fname); - scopename = Copy(fname); - } else { - Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Template '%s' was already wrapped,\n", SwigType_namestr(name)); - Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn, "name"))); - scopename = 0; - } - } else { - Swig_symbol_cadd(fname, n); - SwigType_typedef_class(fname); - scopename = Copy(fname); - } - Delete(deftype_name); - Delete(resolved_name); - } else { - if ((CPlusPlus) || (unnamed)) { - SwigType_typedef_class(name); - } else { - SwigType_typedef_class(NewStringf("%s %s", kind, name)); - } - scopename = Copy(name); - } - } else { - scopename = 0; - } - - Setattr(n, "typepass:visit", "1"); - - /* Need to set up a typedef if unnamed */ - if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) { - SwigType_typedef(unnamed, tdname); - } - // name of the outer class should already be patched to contain its outer classes names, but not to contain namespaces - // namespace name (if present) is added after processing child nodes - if (Getattr(n, "nested:outer") && name) { - String *outerName = Getattr(Getattr(n, "nested:outer"), "name"); - name = NewStringf("%s::%s", outerName, name); - Setattr(n, "name", name); - if (tdname) { - tdname = NewStringf("%s::%s", outerName, tdname); - Setattr(n, "tdname", tdname); - } - } - - if (nsname && name) { - nname = NewStringf("%s::%s", nsname, name); - String *tdname = Getattr(n, "tdname"); - if (tdname) { - tdname = NewStringf("%s::%s", nsname, tdname); - Setattr(n, "tdname", tdname); - } - } - if (nssymname) { - if (GetFlag(n, "feature:nspace")) - Setattr(n, "sym:nspace", nssymname); - } - SwigType_new_scope(scopename); - SwigType_attach_symtab(Getattr(n, "symtab")); - - /* Inherit type definitions into the class */ - if (name && !(GetFlag(n, "nested") && !checkAttribute(n, "access", "public") && - (GetFlag(n, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None))) { - cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name)); - } - - inclass = n; - symtab = Swig_symbol_setscope(Getattr(n, "symtab")); - emit_children(n); - Swig_symbol_setscope(symtab); - - Hash *ts = SwigType_pop_scope(); - Setattr(n, "typescope", ts); - Delete(ts); - Setattr(n, "module", module); - - // When a fully qualified templated type with default parameters is used in the parsed code, - // the following additional symbols and scopes are needed for successful lookups - if (template_default_expanded) { - Swig_symbol_alias(template_default_expanded, Getattr(n, "symtab")); - SwigType_scope_alias(template_default_expanded, Getattr(n, "typescope")); - } - - /* Normalize deferred types */ - { - normal_node *nn = new normal_node(); - nn->normallist = normalize; - nn->symtab = Getattr(n, "symtab"); - nn->next = patch_list; - nn->typescope = Getattr(n, "typescope"); - patch_list = nn; - } - - normalize = olist; - - /* If in a namespace, patch the class name */ - if (nname) { - Setattr(n, "name", nname); - Delete(nname); - } - Delete(fname); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * templateDeclaration() - * ------------------------------------------------------------ */ - - virtual int templateDeclaration(Node *n) { - String *name = Getattr(n, "name"); - String *ttype = Getattr(n, "templatetype"); - if (Strcmp(ttype, "class") == 0) { - String *rname = SwigType_typedef_resolve_all(name); - SwigType_typedef_class(rname); - Delete(rname); - } else if (Strcmp(ttype, "classforward") == 0) { - String *rname = SwigType_typedef_resolve_all(name); - SwigType_typedef_class(rname); - Delete(rname); - /* SwigType_typedef_class(name); */ - } else if (Strcmp(ttype, "cdecl") == 0) { - String *rname = SwigType_typedef_resolve_all(name); - SwigType_typedef_class(rname); - Delete(rname); - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * lambdaDeclaration() - * ------------------------------------------------------------ */ - - virtual int lambdaDeclaration(Node *) { - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * classforwardDeclaration() - * ------------------------------------------------------------ */ - - virtual int classforwardDeclaration(Node *n) { - - /* Can't do inside a C struct because it breaks C nested structure wrapping */ - if ((!inclass) || (CPlusPlus)) { - String *name = Getattr(n, "name"); - SwigType_typedef_class(name); - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * namespaceDeclaration() - * ------------------------------------------------------------ */ - - virtual int namespaceDeclaration(Node *n) { - Symtab *symtab; - String *name = Getattr(n, "name"); - String *alias = Getattr(n, "alias"); - List *olist = normalize; - normalize = NewList(); - if (alias) { - Typetab *ts = Getattr(n, "typescope"); - if (!ts) { - /* Create an empty scope for the alias */ - Node *ns = Getattr(n, "namespace"); - SwigType_scope_alias(name, Getattr(ns, "typescope")); - ts = Getattr(ns, "typescope"); - Setattr(n, "typescope", ts); - } - /* Namespace alias */ - return SWIG_OK; - } else { - if (name) { - Node *nn = Swig_symbol_clookup(name, n); - Hash *ts = 0; - if (nn) - ts = Getattr(nn, "typescope"); - if (!ts) { - SwigType_new_scope(name); - SwigType_attach_symtab(Getattr(n, "symtab")); - } else { - SwigType_set_scope(ts); - } - } - String *oldnsname = nsname; - String *oldnssymname = nssymname; - nsname = Swig_symbol_qualified(Getattr(n, "symtab")); - nssymname = Swig_symbol_qualified_language_scopename(Getattr(n, "symtab")); - symtab = Swig_symbol_setscope(Getattr(n, "symtab")); - emit_children(n); - Swig_symbol_setscope(symtab); - - if (name) { - Hash *ts = SwigType_pop_scope(); - Setattr(n, "typescope", ts); - Delete(ts); - } - - /* Normalize deferred types */ - { - normal_node *nn = new normal_node(); - nn->normallist = normalize; - nn->symtab = Getattr(n, "symtab"); - nn->next = patch_list; - nn->typescope = Getattr(n, "typescope"); - patch_list = nn; - } - normalize = olist; - - Delete(nssymname); - nssymname = oldnssymname; - Delete(nsname); - nsname = oldnsname; - return SWIG_OK; - } - } - - /* ------------------------------------------------------------ - * cDeclaration() - * ------------------------------------------------------------ */ - - virtual int cDeclaration(Node *n) { - if (NoExcept) { - Delattr(n, "throws"); - } - - /* Normalize types. */ - SwigType *ty = Getattr(n, "type"); - if (!ty) { - return SWIG_OK; - } - normalize_type(ty); - SwigType *decl = Getattr(n, "decl"); - if (decl) { - normalize_type(decl); - } - normalize_parms(Getattr(n, "parms")); - normalize_parms(Getattr(n, "throws")); - if (GetFlag(n, "conversion_operator")) { - /* The call to the operator in the generated wrapper must be fully qualified in order to compile */ - SwigType *name = Getattr(n, "name"); - SwigType *qualifiedname = Swig_symbol_string_qualify(name, 0); - Clear(name); - Append(name, qualifiedname); - Delete(qualifiedname); - } - - if (checkAttribute(n, "storage", "typedef")) { - String *name = Getattr(n, "name"); - ty = Getattr(n, "type"); - decl = Getattr(n, "decl"); - SwigType *t = Copy(ty); - { - /* If the typename is qualified, make sure the scopename is fully qualified when making a typedef */ - if (Swig_scopename_check(t) && strncmp(Char(t), "::", 2)) { - String *base, *prefix, *qprefix; - base = Swig_scopename_last(t); - prefix = Swig_scopename_prefix(t); - qprefix = SwigType_typedef_qualified(prefix); - Delete(t); - t = NewStringf("%s::%s", qprefix, base); - Delete(base); - Delete(prefix); - Delete(qprefix); - } - } - SwigType_push(t, decl); - if (CPlusPlus) { - Replaceall(t, "struct ", ""); - Replaceall(t, "union ", ""); - Replaceall(t, "class ", ""); - } - SwigType_typedef(t, name); - } - /* If namespaces are active. We need to patch the name with a namespace prefix */ - if (nsname && !inclass) { - String *name = Getattr(n, "name"); - if (name) { - String *nname = NewStringf("%s::%s", nsname, name); - Setattr(n, "name", nname); - Delete(nname); - } - } - clean_overloaded(n); - return SWIG_OK; - } - - - /* ------------------------------------------------------------ - * constructorDeclaration() - * ------------------------------------------------------------ */ - - virtual int constructorDeclaration(Node *n) { - if (NoExcept) { - Delattr(n, "throws"); - } - - normalize_parms(Getattr(n, "parms")); - normalize_parms(Getattr(n, "throws")); - - clean_overloaded(n); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * destructorDeclaration() - * ------------------------------------------------------------ */ - - virtual int destructorDeclaration(Node *) { - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * constantDirective() - * ------------------------------------------------------------ */ - - virtual int constantDirective(Node *n) { - SwigType *ty = Getattr(n, "type"); - if (ty) { - Setattr(n, "type", SwigType_typedef_qualified(ty)); - } - return SWIG_OK; - } - - - /* ------------------------------------------------------------ - * enumDeclaration() - * ------------------------------------------------------------ */ - - virtual int enumDeclaration(Node *n) { - String *name = Getattr(n, "name"); - - if (name) { - String *scope = 0; - - // Add a typedef to the type table so that we can use 'enum Name' as well as just 'Name' - if (nsname || inclass) { - - // But first correct the name and tdname to contain the fully qualified scopename - if (nsname && inclass) { - scope = NewStringf("%s::%s", nsname, Getattr(inclass, "name")); - } else if (nsname) { - scope = NewStringf("%s", nsname); - } else if (inclass) { - scope = NewStringf("%s", Getattr(inclass, "name")); - } - - String *nname = NewStringf("%s::%s", scope, name); - Setattr(n, "name", nname); - - String *tdname = Getattr(n, "tdname"); - if (tdname) { - tdname = NewStringf("%s::%s", scope, tdname); - Setattr(n, "tdname", tdname); - } - - SwigType *t = NewStringf("enum %s", nname); - SwigType_typedef(t, name); - } else { - SwigType *t = NewStringf("enum %s", name); - SwigType_typedef(t, name); - } - Delete(scope); - } - - String *tdname = Getattr(n, "tdname"); - String *unnamed = Getattr(n, "unnamed"); - String *storage = Getattr(n, "storage"); - - // Construct enumtype - for declaring an enum of this type with SwigType_ltype() etc - String *enumtype = 0; - if (unnamed && tdname && (Cmp(storage, "typedef") == 0)) { - enumtype = Copy(Getattr(n, "tdname")); - } else if (name) { - enumtype = NewStringf("%s%s", CPlusPlus ? "" : "enum ", Getattr(n, "name")); - } else { - // anonymous enums - enumtype = Copy(Getattr(n, "type")); - } - Setattr(n, "enumtype", enumtype); - - if (nssymname) { - if (GetFlag(n, "feature:nspace")) - Setattr(n, "sym:nspace", nssymname); - } - - // This block of code is for dealing with %ignore on an enum item where the target language - // attempts to use the C enum value in the target language itself and expects the previous enum value - // to be one more than the previous value... the previous enum item might not exist if it is ignored! - // - It sets the first non-ignored enum item with the "firstenumitem" attribute. - // - It adds an enumvalue attribute if the previous enum item is ignored - { - Node *c; - int count = 0; - String *previous = 0; - bool previous_ignored = false; - bool firstenumitem = false; - for (c = firstChild(n); c; c = nextSibling(c)) { - assert(strcmp(Char(nodeType(c)), "enumitem") == 0); - - bool reset; - String *enumvalue = Getattr(c, "enumvalue"); - if (GetFlag(c, "feature:ignore") || !Getattr(c, "sym:name")) { - reset = enumvalue ? true : false; - previous_ignored = true; - } else { - if (!enumvalue && previous_ignored) { - if (previous) - Setattr(c, "enumvalue", NewStringf("(%s) + %d", previous, count+1)); - else - Setattr(c, "enumvalue", NewStringf("%d", count)); - SetFlag(c, "virtenumvalue"); // identify enumvalue as virtual, ie not from the parsed source - } - if (!firstenumitem) { - SetFlag(c, "firstenumitem"); - firstenumitem = true; - } - reset = true; - previous_ignored = false; - } - if (reset) { - previous = enumvalue ? enumvalue : Getattr(c, "name"); - count = 0; - } else { - count++; - } - } - } - - emit_children(n); - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * enumvalueDeclaration() - * ------------------------------------------------------------ */ - - virtual int enumvalueDeclaration(Node *n) { - String *name = Getattr(n, "name"); - String *value = Getattr(n, "value"); - String *scopedenum = Getattr(parentNode(n), "scopedenum"); - if (!value) - value = name; - if (Strcmp(value, name) == 0) { - String *new_value; - if ((nsname || inclass || scopedenum) && cparse_cplusplus) { - new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value); - } else { - new_value = NewString(value); - } - if ((nsname || inclass || scopedenum) && !cparse_cplusplus) { - String *cppvalue = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value); - Setattr(n, "cppvalue", cppvalue); /* for target languages that always generate C++ code even when wrapping C code */ - } - Setattr(n, "value", new_value); - Delete(new_value); - } - Node *next = nextSibling(n); - - // Make up an enumvalue if one was not specified in the parsed code (not designed to be used on enum items and %ignore - enumvalue will be set instead) - if (!GetFlag(n, "feature:ignore")) { - if (Getattr(n, "_last") && !Getattr(n, "enumvalue")) { // Only the first enum item has _last set (Note: first non-ignored enum item has firstenumitem set) - Setattr(n, "enumvalueex", "0"); - } - if (next && !Getattr(next, "enumvalue")) { - Setattr(next, "enumvalueex", NewStringf("%s + 1", Getattr(n, "sym:name"))); - } - } - - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * enumforwardDeclaration() - * ------------------------------------------------------------ */ - - virtual int enumforwardDeclaration(Node *n) { - - // Use enumDeclaration() to do all the hard work. - // Note that no children can be emitted in a forward declaration as there aren't any. - int result = enumDeclaration(n); - if (result == SWIG_OK) { - // Detect when the real enum matching the forward enum declaration has not been parsed/declared - SwigType *ty = SwigType_typedef_resolve_all(Getattr(n, "type")); - Replaceall(ty, "enum ", ""); - Node *nn = Swig_symbol_clookup(ty, 0); - - String *nodetype = nn ? nodeType(nn) : 0; - if (nodetype) { - if (Equal(nodetype, "enumforward")) { - SetFlag(nn, "enumMissing"); - } // if a real enum was declared this would be an "enum" node type - } - Delete(ty); - } - return result; - } - -#ifdef DEBUG_OVERLOADED - static void show_overloaded(Node *n) { - Node *c = Getattr(n, "sym:overloaded"); - Node *checkoverloaded = c; - Printf(stdout, "-------------------- overloaded start %s sym:overloaded():%p -------------------------------\n", Getattr(n, "name"), c); - while (c) { - if (Getattr(c, "error")) { - c = Getattr(c, "sym:nextSibling"); - continue; - } - if (Getattr(c, "sym:overloaded") != checkoverloaded) { - Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded); - Swig_print_node(c); - Exit(EXIT_FAILURE); - } - - String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl"); - Printf(stdout, " show_overloaded %s::%s(%s) [%s] nodeType:%s\n", parentNode(c) ? Getattr(parentNode(c), "name") : "NOPARENT", Getattr(c, "name"), decl, Getattr(c, "sym:overname"), nodeType(c)); - if (!Getattr(c, "sym:overloaded")) { - Printf(stdout, "sym:overloaded error.....%p\n", c); - Swig_print_node(c); - Exit(EXIT_FAILURE); - } - c = Getattr(c, "sym:nextSibling"); - } - Printf(stdout, "-------------------- overloaded end %s -------------------------------\n", Getattr(n, "name")); - } -#endif - - /* ------------------------------------------------------------ - * usingDeclaration() - * ------------------------------------------------------------ */ - - virtual int usingDeclaration(Node *n) { - if (Getattr(n, "namespace")) { - /* using namespace id */ - - /* For a namespace import. We set up inheritance in the type system */ - Node *ns = Getattr(n, "node"); - if (ns) { - Typetab *ts = Getattr(ns, "typescope"); - if (ts) { - SwigType_using_scope(ts); - } - } - return SWIG_OK; - } else { - Node *ns; - /* using id */ - Symtab *stab = Getattr(n, "sym:symtab"); - if (stab) { - String *uname = Getattr(n, "uname"); - ns = Swig_symbol_clookup(uname, stab); - if (!ns && SwigType_istemplate(uname)) { - String *tmp = Swig_symbol_template_deftype(uname, 0); - if (!Equal(tmp, uname)) { - ns = Swig_symbol_clookup(tmp, stab); - } - Delete(tmp); - } - } else { - ns = 0; - } - if (!ns) { - if (is_public(n)) { - Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n, "uname"))); - } - } else { - /* Only a single symbol is being used. There are only a few symbols that - we actually care about. These are typedef, class declarations, and enum */ - String *ntype = nodeType(ns); - if (Strcmp(ntype, "cdecl") == 0) { - if (checkAttribute(ns, "storage", "typedef")) { - /* A typedef declaration */ - String *uname = Getattr(n, "uname"); - SwigType_typedef_using(uname); - } else { - /* A normal C declaration. */ - if ((inclass) && (!GetFlag(n, "feature:ignore")) && (Getattr(n, "sym:name"))) { - Node *c = ns; - Node *unodes = 0, *last_unodes = 0; - int ccount = 0; - String *symname = Getattr(n, "sym:name"); - - // The overloaded functions in scope may not yet have had their parameters normalized yet (in cDeclaration). - // Happens if the functions were declared after the using declaration. So use a normalized copy. - List *n_decl_list = NewList(); - Node *over = Getattr(n, "sym:overloaded"); - while (over) { - String *odecl = Copy(Getattr(over, "decl")); - if (odecl) { - normalize_type(odecl); - Append(n_decl_list, odecl); - Delete(odecl); - } - over = Getattr(over, "sym:nextSibling"); - } - - while (c) { - if (Strcmp(nodeType(c), "cdecl") == 0) { - if (!(Swig_storage_isstatic(c) - || checkAttribute(c, "storage", "typedef") - || checkAttribute(c, "storage", "friend") - || (Getattr(c, "feature:extend") && !Getattr(c, "code")) - || GetFlag(c, "feature:ignore"))) { - - String *csymname = Getattr(c, "sym:name"); - if (!csymname || (Strcmp(csymname, symname) == 0)) { - String *decl = Getattr(c, "decl"); - int match = 0; - - for (Iterator it = First(n_decl_list); it.item; it = Next(it)) { - String *odecl = it.item; - if (Cmp(decl, odecl) == 0) { - match = 1; - break; - } - } - if (match) { - /* Don't generate a method if the method is overridden in this class, - * for example don't generate another m(bool) should there be a Base::m(bool) : - * struct Derived : Base { - * void m(bool); - * using Base::m; - * }; - */ - c = Getattr(c, "csym:nextSibling"); - continue; - } - - Node *nn = copyNode(c); - Setfile(nn, Getfile(n)); - Setline(nn, Getline(n)); - Delattr(nn, "access"); // access might be different from the method in the base class - Setattr(nn, "access", Getattr(n, "access")); - if (!Getattr(nn, "sym:name")) - Setattr(nn, "sym:name", symname); - Symtab *st = Getattr(n, "sym:symtab"); - assert(st); - Setattr(nn, "sym:symtab", st); - - if (!GetFlag(nn, "feature:ignore")) { - ParmList *parms = CopyParmList(Getattr(c, "parms")); - int is_pointer = SwigType_ispointer_return(Getattr(nn, "decl")); - int is_void = checkAttribute(nn, "type", "void") && !is_pointer; - Setattr(nn, "parms", parms); - Delete(parms); - if (Getattr(n, "feature:extend")) { - String *ucode = is_void ? NewStringf("{ self->%s(", Getattr(n, "uname")) : NewStringf("{ return self->%s(", Getattr(n, "uname")); - - for (ParmList *p = parms; p;) { - Append(ucode, Getattr(p, "name")); - p = nextSibling(p); - if (p) - Append(ucode, ","); - } - Append(ucode, "); }"); - Setattr(nn, "code", ucode); - Delete(ucode); - } - ParmList *throw_parm_list = Getattr(c, "throws"); - if (throw_parm_list) - Setattr(nn, "throws", CopyParmList(throw_parm_list)); - ccount++; - if (!last_unodes) { - last_unodes = nn; - unodes = nn; - } else { - Setattr(nn, "previousSibling", last_unodes); - Setattr(last_unodes, "nextSibling", nn); - Setattr(nn, "sym:previousSibling", last_unodes); - Setattr(last_unodes, "sym:nextSibling", nn); - Setattr(nn, "sym:overloaded", unodes); - Setattr(unodes, "sym:overloaded", unodes); - last_unodes = nn; - } - } else { - Delete(nn); - } - } else { - Swig_warning(WARN_LANG_USING_NAME_DIFFERENT, Getfile(n), Getline(n), "Using declaration %s, with name '%s', is not actually using\n", SwigType_namestr(Getattr(n, "uname")), symname); - Swig_warning(WARN_LANG_USING_NAME_DIFFERENT, Getfile(c), Getline(c), "the method from %s, with name '%s', as the names are different.\n", Swig_name_decl(c), csymname); - } - } - } - c = Getattr(c, "csym:nextSibling"); - } - if (unodes) { - set_firstChild(n, unodes); - if (ccount > 1) { - if (!Getattr(n, "sym:overloaded")) { - Setattr(n, "sym:overloaded", n); - Setattr(n, "sym:overname", "_SWIG_0"); - } - } - } - - /* Hack the parse tree symbol table for overloaded methods. Replace the "using" node with the - * list of overloaded methods we have just added in as child nodes to the "using" node. - * The node will still exist, it is just the symbol table linked list of overloaded methods - * which is hacked. */ - if (Getattr(n, "sym:overloaded")) { - int cnt = 0; - Node *ps = Getattr(n, "sym:previousSibling"); - Node *ns = Getattr(n, "sym:nextSibling"); - Node *fc = firstChild(n); - Node *firstoverloaded = Getattr(n, "sym:overloaded"); -#ifdef DEBUG_OVERLOADED - show_overloaded(firstoverloaded); -#endif - - if (firstoverloaded == n) { - // This 'using' node we are cutting out was the first node in the overloaded list. - // Change the first node in the list - Delattr(firstoverloaded, "sym:overloaded"); - firstoverloaded = fc ? fc : ns; - - // Correct all the sibling overloaded methods (before adding in new methods) - Node *nnn = ns; - while (nnn) { - Setattr(nnn, "sym:overloaded", firstoverloaded); - nnn = Getattr(nnn, "sym:nextSibling"); - } - } - - if (!fc) { - // Remove from overloaded list ('using' node does not actually end up adding in any methods) - if (ps) { - Setattr(ps, "sym:nextSibling", ns); - } - if (ns) { - Setattr(ns, "sym:previousSibling", ps); - } - } else { - // The 'using' node results in methods being added in - slot in these methods here - Node *pp = fc; - while (pp) { - Node *ppn = Getattr(pp, "sym:nextSibling"); - Setattr(pp, "sym:overloaded", firstoverloaded); - Setattr(pp, "sym:overname", NewStringf("%s_%d", Getattr(n, "sym:overname"), cnt++)); - if (ppn) - pp = ppn; - else - break; - } - if (ps) { - Setattr(ps, "sym:nextSibling", fc); - Setattr(fc, "sym:previousSibling", ps); - } - if (ns) { - Setattr(ns, "sym:previousSibling", pp); - Setattr(pp, "sym:nextSibling", ns); - } - } - Delattr(n, "sym:previousSibling"); - Delattr(n, "sym:nextSibling"); - Delattr(n, "sym:overloaded"); - Delattr(n, "sym:overname"); - clean_overloaded(firstoverloaded); -#ifdef DEBUG_OVERLOADED - show_overloaded(firstoverloaded); -#endif - } - Delete(n_decl_list); - } - } - } else if ((Strcmp(ntype, "class") == 0) || ((Strcmp(ntype, "classforward") == 0))) { - /* We install the using class name as kind of a typedef back to the original class */ - String *uname = Getattr(n, "uname"); - /* Import into current type scope */ - SwigType_typedef_using(uname); - } else if (Strcmp(ntype, "enum") == 0) { - SwigType_typedef_using(Getattr(n, "uname")); - } else if (Strcmp(ntype, "template") == 0) { - SwigType_typedef_using(Getattr(n, "uname")); - } - } - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * typemapDirective() - * ------------------------------------------------------------ */ - - virtual int typemapDirective(Node *n) { - if (inclass || nsname) { - Node *items = firstChild(n); - while (items) { - Parm *pattern = Getattr(items, "pattern"); - Parm *parms = Getattr(items, "parms"); - normalize_later(pattern); - normalize_later(parms); - items = nextSibling(items); - } - } - return SWIG_OK; - } - - - /* ------------------------------------------------------------ - * typemapcopyDirective() - * ------------------------------------------------------------ */ - - virtual int typemapcopyDirective(Node *n) { - if (inclass || nsname) { - Node *items = firstChild(n); - ParmList *pattern = Getattr(n, "pattern"); - normalize_later(pattern); - while (items) { - ParmList *npattern = Getattr(items, "pattern"); - normalize_later(npattern); - items = nextSibling(items); - } - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * applyDirective() - * ------------------------------------------------------------ */ - - virtual int applyDirective(Node *n) { - if (inclass || nsname) { - ParmList *pattern = Getattr(n, "pattern"); - normalize_later(pattern); - Node *items = firstChild(n); - while (items) { - Parm *apattern = Getattr(items, "pattern"); - normalize_later(apattern); - items = nextSibling(items); - } - } - return SWIG_OK; - } - - /* ------------------------------------------------------------ - * clearDirective() - * ------------------------------------------------------------ */ - - virtual int clearDirective(Node *n) { - if (inclass || nsname) { - Node *p; - for (p = firstChild(n); p; p = nextSibling(p)) { - ParmList *pattern = Getattr(p, "pattern"); - normalize_later(pattern); - } - } - return SWIG_OK; - } - -public: - static void pass(Node *n) { - TypePass t; - t.top(n); - } -}; - -void Swig_process_types(Node *n) { - if (!n) - return; - TypePass::pass(n); -} - diff --git a/contrib/tools/swig/Source/Modules/utils.cxx b/contrib/tools/swig/Source/Modules/utils.cxx deleted file mode 100644 index de6f87d8c3a..00000000000 --- a/contrib/tools/swig/Source/Modules/utils.cxx +++ /dev/null @@ -1,218 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * utils.cxx - * - * Various utility functions. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" - -int is_public(Node *n) { - String *access = Getattr(n, "access"); - return !access || !Cmp(access, "public"); -} - -int is_private(Node *n) { - String *access = Getattr(n, "access"); - return access && !Cmp(access, "private"); -} - -int is_protected(Node *n) { - String *access = Getattr(n, "access"); - return access && !Cmp(access, "protected"); -} - -static int is_member_director_helper(Node *parentnode, Node *member) { - int parent_nodirector = GetFlag(parentnode, "feature:nodirector"); - if (parent_nodirector) - return 0; - int parent_director = Swig_director_mode() && GetFlag(parentnode, "feature:director"); - int cdecl_director = parent_director || GetFlag(member, "feature:director"); - int cdecl_nodirector = GetFlag(member, "feature:nodirector"); - return cdecl_director && !cdecl_nodirector && !GetFlag(member, "feature:extend"); -} - -int is_member_director(Node *parentnode, Node *member) { - if (parentnode && checkAttribute(member, "storage", "virtual")) { - return is_member_director_helper(parentnode, member); - } else { - return 0; - } -} - -int is_member_director(Node *member) { - return is_member_director(Getattr(member, "parentNode"), member); -} - -// Identifies the additional protected members that are generated when the allprotected option is used. -// This does not include protected virtual methods as they are turned on with the dirprot option. -int is_non_virtual_protected_access(Node *n) { - int result = 0; - if (Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode() && is_protected(n) && !checkAttribute(n, "storage", "virtual")) { - Node *parentNode = Getattr(n, "parentNode"); - // When vtable is empty, the director class does not get emitted, so a check for an empty vtable should be done. - // However, vtable is set in Language and so is not yet set when methods in Typepass call clean_overloaded() - // which calls is_non_virtual_protected_access. So commented out below. - // Moving the director vtable creation into Typepass should solve this problem. - if (is_member_director_helper(parentNode, n) /* && Getattr(parentNode, "vtable")*/) - result = 1; - } - return result; -} - -/* Clean overloaded list. Removes templates, ignored, and errors */ - -void clean_overloaded(Node *n) { - Node *nn = Getattr(n, "sym:overloaded"); - Node *first = 0; - while (nn) { - String *ntype = nodeType(nn); - if ((GetFlag(nn, "feature:ignore")) || - (Getattr(nn, "error")) || - (Strcmp(ntype, "template") == 0) || - ((Strcmp(ntype, "cdecl") == 0) && is_protected(nn) && !is_member_director(nn) && !is_non_virtual_protected_access(n))) { - /* Remove from overloaded list */ - Node *ps = Getattr(nn, "sym:previousSibling"); - Node *ns = Getattr(nn, "sym:nextSibling"); - if (ps) { - Setattr(ps, "sym:nextSibling", ns); - } - if (ns) { - Setattr(ns, "sym:previousSibling", ps); - } - Delattr(nn, "sym:previousSibling"); - Delattr(nn, "sym:nextSibling"); - Delattr(nn, "sym:overloaded"); - nn = ns; - continue; - } else { - if (!first) - first = nn; - Setattr(nn, "sym:overloaded", first); - } - nn = Getattr(nn, "sym:nextSibling"); - } - if (!first || (first && !Getattr(first, "sym:nextSibling"))) { - if (Getattr(n, "sym:overloaded")) - Delattr(n, "sym:overloaded"); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_set_max_hash_expand() - * - * Controls how many Hash objects are displayed when displaying nested Hash objects. - * Makes DohSetMaxHashExpand an externally callable function (for debugger). - * ----------------------------------------------------------------------------- */ - -void Swig_set_max_hash_expand(int count) { - SetMaxHashExpand(count); -} - -extern "C" { - -/* ----------------------------------------------------------------------------- - * Swig_get_max_hash_expand() - * - * Returns how many Hash objects are displayed when displaying nested Hash objects. - * Makes DohGetMaxHashExpand an externally callable function (for debugger). - * ----------------------------------------------------------------------------- */ - -int Swig_get_max_hash_expand() { - return GetMaxHashExpand(); -} - -/* ----------------------------------------------------------------------------- - * Swig_to_doh_string() - * - * DOH version of Swig_to_string() - * ----------------------------------------------------------------------------- */ - -static String *Swig_to_doh_string(DOH *object, int count) { - int old_count = Swig_get_max_hash_expand(); - if (count >= 0) - Swig_set_max_hash_expand(count); - - String *debug_string = object ? NewStringf("%s", object) : NewString("NULL"); - - Swig_set_max_hash_expand(old_count); - return debug_string; -} - -/* ----------------------------------------------------------------------------- - * Swig_to_doh_string_with_location() - * - * DOH version of Swig_to_string_with_location() - * ----------------------------------------------------------------------------- */ - -static String *Swig_to_doh_string_with_location(DOH *object, int count) { - int old_count = Swig_get_max_hash_expand(); - if (count >= 0) - Swig_set_max_hash_expand(count); - - String *debug_string = Swig_stringify_with_location(object); - - Swig_set_max_hash_expand(old_count); - return debug_string; -} - -/* ----------------------------------------------------------------------------- - * Swig_to_string() - * - * Swig debug - return C string representation of any DOH type. - * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 - * Note: leaks memory. - * ----------------------------------------------------------------------------- */ - -const char *Swig_to_string(DOH *object, int count) { - return Char(Swig_to_doh_string(object, count)); -} - -/* ----------------------------------------------------------------------------- - * Swig_to_string_with_location() - * - * Swig debug - return C string representation of any DOH type, within [] brackets - * for Hash and List types, prefixed by line and file information. - * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 - * Note: leaks memory. - * ----------------------------------------------------------------------------- */ - -const char *Swig_to_string_with_location(DOH *object, int count) { - return Char(Swig_to_doh_string_with_location(object, count)); -} - -/* ----------------------------------------------------------------------------- - * Swig_print() - * - * Swig debug - display string representation of any DOH type. - * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 - * ----------------------------------------------------------------------------- */ - -void Swig_print(DOH *object, int count) { - String *output = Swig_to_doh_string(object, count); - Printf(stdout, "%s\n", output); - Delete(output); -} - -/* ----------------------------------------------------------------------------- - * Swig_to_string_with_location() - * - * Swig debug - display string representation of any DOH type, within [] brackets - * for Hash and List types, prefixed by line and file information. - * Nested Hash types expand count is value of Swig_get_max_hash_expand when count<0 - * ----------------------------------------------------------------------------- */ - -void Swig_print_with_location(DOH *object, int count) { - String *output = Swig_to_doh_string_with_location(object, count); - Printf(stdout, "%s\n", output); - Delete(output); -} - -} // extern "C" - diff --git a/contrib/tools/swig/Source/Modules/xml.cxx b/contrib/tools/swig/Source/Modules/xml.cxx deleted file mode 100644 index ed4213cc5c3..00000000000 --- a/contrib/tools/swig/Source/Modules/xml.cxx +++ /dev/null @@ -1,326 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * xml.cxx - * - * An Xml parse tree generator. - * ----------------------------------------------------------------------------- */ - -#include "swigmod.h" - -static const char *usage = "\ -XML Options (available with -xml)\n\ - -xmllang <lang> - Typedef language\n\ - -xmllite - More lightweight version of XML\n\ - ------\n\ - deprecated (use -o): -xml <output.xml> - Use <output.xml> as output file (extension .xml mandatory)\n"; - -static File *out = 0; -static int xmllite = 0; - - -class XML:public Language { -public: - - int indent_level; - long id; - - XML() :indent_level(0) , id(0) { - } - - virtual ~ XML() { - } - - virtual void main(int argc, char *argv[]) { - SWIG_typemap_lang("xml"); - for (int iX = 0; iX < argc; iX++) { - if (strcmp(argv[iX], "-xml") == 0) { - char *extension = 0; - if (iX + 1 >= argc) - continue; - extension = argv[iX + 1] + strlen(argv[iX + 1]) - 4; - if (strcmp(extension, ".xml")) - continue; - iX++; - Swig_mark_arg(iX); - String *outfile = NewString(argv[iX]); - out = NewFile(outfile, "w", SWIG_output_files()); - if (!out) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - continue; - } - if (strcmp(argv[iX], "-xmllang") == 0) { - Swig_mark_arg(iX); - iX++; - SWIG_typemap_lang(argv[iX]); - Swig_mark_arg(iX); - continue; - } - if (strcmp(argv[iX], "-help") == 0) { - fputs(usage, stdout); - } - if (strcmp(argv[iX], "-xmllite") == 0) { - Swig_mark_arg(iX); - xmllite = 1; - } - } - - // Add a symbol to the parser for conditional compilation - Preprocessor_define("SWIGXML 1", 0); - } - - /* Top of the parse tree */ - - virtual int top(Node *n) { - if (out == 0) { - String *outfile = Getattr(n, "outfile"); - String *ext = Swig_file_extension(outfile); - // If there's an extension, ext will include the ".". - Delslice(outfile, Len(outfile) - Len(ext), DOH_END); - Delete(ext); - Append(outfile, ".xml"); - out = NewFile(outfile, "w", SWIG_output_files()); - if (!out) { - FileErrorDisplay(outfile); - Exit(EXIT_FAILURE); - } - } - Printf(out, "<?xml version=\"1.0\" ?> \n"); - Xml_print_tree(n); - return SWIG_OK; - } - - void print_indent(int l) { - int i; - for (i = 0; i < indent_level; i++) { - Printf(out, " "); - } - if (l) { - Printf(out, " "); - } - } - - void Xml_print_tree(DOH *obj) { - while (obj) { - Xml_print_node(obj); - obj = nextSibling(obj); - } - } - - void Xml_print_attributes(Node *obj) { - String *k; - indent_level += 4; - print_indent(0); - Printf(out, "<attributelist id=\"%ld\" addr=\"%p\">\n", ++id, obj); - indent_level += 4; - Iterator ki; - ki = First(obj); - while (ki.key) { - k = ki.key; - if ((Cmp(k, "nodeType") == 0) - || (Cmp(k, "firstChild") == 0) - || (Cmp(k, "lastChild") == 0) - || (Cmp(k, "parentNode") == 0) - || (Cmp(k, "nextSibling") == 0) - || (Cmp(k, "previousSibling") == 0) - || (*(Char(k)) == '$')) { - /* Do nothing */ - } else if (Cmp(k, "module") == 0) { - Xml_print_module(Getattr(obj, k)); - } else if (Cmp(k, "baselist") == 0) { - Xml_print_baselist(Getattr(obj, k)); - } else if (!xmllite && Cmp(k, "typescope") == 0) { - Xml_print_typescope(Getattr(obj, k)); - } else if (!xmllite && Cmp(k, "typetab") == 0) { - Xml_print_typetab(Getattr(obj, k)); - } else if (Cmp(k, "kwargs") == 0) { - Xml_print_kwargs(Getattr(obj, k)); - } else if (Cmp(k, "parms") == 0 || Cmp(k, "pattern") == 0) { - Xml_print_parmlist(Getattr(obj, k)); - } else if (Cmp(k, "catchlist") == 0 || Cmp(k, "templateparms") == 0) { - Xml_print_parmlist(Getattr(obj, k), Char(k)); - } else { - DOH *o; - print_indent(0); - if (DohIsString(Getattr(obj, k))) { - String *ck = NewString(k); - o = Str(Getattr(obj, k)); - Replaceall(ck, ":", "_"); - Replaceall(ck, "<", "<"); - /* Do first to avoid aliasing errors. */ - Replaceall(o, "&", "&"); - Replaceall(o, "<", "<"); - Replaceall(o, "\"", """); - Replaceall(o, "\\", "\\\\"); - Replaceall(o, "\n", " "); - Printf(out, "<attribute name=\"%s\" value=\"%s\" id=\"%ld\" addr=\"%p\" />\n", ck, o, ++id, o); - Delete(o); - Delete(ck); - } else { - o = Getattr(obj, k); - String *ck = NewString(k); - Replaceall(ck, ":", "_"); - Printf(out, "<attribute name=\"%s\" value=\"%p\" id=\"%ld\" addr=\"%p\" />\n", ck, o, ++id, o); - Delete(ck); - } - } - ki = Next(ki); - } - indent_level -= 4; - print_indent(0); - Printf(out, "</attributelist>\n"); - indent_level -= 4; - } - - void Xml_print_node(Node *obj) { - Node *cobj; - - print_indent(0); - Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", nodeType(obj), ++id, obj); - Xml_print_attributes(obj); - cobj = firstChild(obj); - if (cobj) { - indent_level += 4; - Printf(out, "\n"); - Xml_print_tree(cobj); - indent_level -= 4; - } else { - print_indent(1); - Printf(out, "\n"); - } - print_indent(0); - Printf(out, "</%s>\n", nodeType(obj)); - } - - - void Xml_print_parmlist(ParmList *p, const char* markup = "parmlist") { - - print_indent(0); - Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", markup, ++id, p); - indent_level += 4; - while (p) { - print_indent(0); - Printf(out, "<parm id=\"%ld\">\n", ++id); - Xml_print_attributes(p); - print_indent(0); - Printf(out, "</parm>\n"); - p = nextSibling(p); - } - indent_level -= 4; - print_indent(0); - Printf(out, "</%s>\n", markup); - } - - void Xml_print_baselist(List *p) { - - print_indent(0); - Printf(out, "<baselist id=\"%ld\" addr=\"%p\">\n", ++id, p); - indent_level += 4; - Iterator s; - for (s = First(p); s.item; s = Next(s)) { - print_indent(0); - String *item_name = Xml_escape_string(s.item); - Printf(out, "<base name=\"%s\" id=\"%ld\" addr=\"%p\" />\n", item_name, ++id, s.item); - Delete(item_name); - } - indent_level -= 4; - print_indent(0); - Printf(out, "</baselist>\n"); - } - - String *Xml_escape_string(String *str) { - String *escaped_str = 0; - if (str) { - escaped_str = NewString(str); - Replaceall(escaped_str, "&", "&"); - Replaceall(escaped_str, "<", "<"); - Replaceall(escaped_str, "\"", """); - Replaceall(escaped_str, "\\", "\\\\"); - Replaceall(escaped_str, "\n", " "); - } - return escaped_str; - } - - void Xml_print_module(Node *p) { - - print_indent(0); - Printf(out, "<attribute name=\"module\" value=\"%s\" id=\"%ld\" addr=\"%p\" />\n", Getattr(p, "name"), ++id, p); - } - - void Xml_print_kwargs(Hash *p) { - Xml_print_hash(p, "kwargs"); - } - - void Xml_print_typescope(Hash *p) { - - Xml_print_hash(p, "typescope"); - } - - void Xml_print_typetab(Hash *p) { - - Xml_print_hash(p, "typetab"); - } - - - void Xml_print_hash(Hash *p, const char *markup) { - - print_indent(0); - Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", markup, ++id, p); - Xml_print_attributes(p); - indent_level += 4; - Iterator n = First(p); - while (n.key) { - print_indent(0); - Printf(out, "<%ssitem id=\"%ld\" addr=\"%p\">\n", markup, ++id, n.item); - Xml_print_attributes(n.item); - print_indent(0); - Printf(out, "</%ssitem>\n", markup); - n = Next(n); - } - indent_level -= 4; - print_indent(0); - Printf(out, "</%s>\n", markup); - } - -}; - -/* ----------------------------------------------------------------------------- - * Swig_print_xml - * - * Dump an XML version of the parse tree. This is different from using the -xml - * language module normally as it allows the real language module to process the - * tree first, possibly stuffing in new attributes, so the XML that is output ends - * up being a post-processing version of the tree. - * ----------------------------------------------------------------------------- */ - -void Swig_print_xml(DOH *obj, String *filename) { - XML xml; - xmllite = 1; - - if (!filename) { - out = stdout; - } else { - out = NewFile(filename, "w", SWIG_output_files()); - if (!out) { - FileErrorDisplay(filename); - Exit(EXIT_FAILURE); - } - } - - Printf(out, "<?xml version=\"1.0\" ?> \n"); - xml.Xml_print_tree(obj); -} - -static Language *new_swig_xml() { - return new XML(); -} -extern "C" Language *swig_xml(void) { - return new_swig_xml(); -} diff --git a/contrib/tools/swig/Source/Preprocessor/cpp.c b/contrib/tools/swig/Source/Preprocessor/cpp.c deleted file mode 100644 index a80434323c1..00000000000 --- a/contrib/tools/swig/Source/Preprocessor/cpp.c +++ /dev/null @@ -1,2111 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * cpp.c - * - * An implementation of a C preprocessor plus some support for additional - * SWIG directives. - * - * - SWIG directives such as %include, %extern, and %import are handled - * - A new macro %define ... %enddef can be used for multiline macros - * - No preprocessing is performed in %{ ... %} blocks - * - Lines beginning with %# are stripped down to #... and passed through. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "preprocessor.h" -#include <ctype.h> - -static Hash *cpp = 0; /* C preprocessor data */ -static int include_all = 0; /* Follow all includes */ -static int ignore_missing = 0; -static int import_all = 0; /* Follow all includes, but as %import statements */ -static int imported_depth = 0; /* Depth of %imported files */ -static int single_include = 1; /* Only include each file once */ -static Hash *included_files = 0; -static List *dependencies = 0; -static Scanner *id_scan = 0; -static int error_as_warning = 0; /* Understand the cpp #error directive as a special #warning */ -static int expand_defined_operator = 0; -static int macro_level = 0; -static int macro_start_line = 0; -static const String * macro_start_file = 0; - -/* Test a character to see if it starts an identifier */ -#define isidentifier(c) ((isalpha(c)) || (c == '_') || (c == '$')) - -/* Test a character to see if it valid in an identifier (after the first letter) */ -#define isidchar(c) ((isalnum(c)) || (c == '_') || (c == '$')) - -static DOH *Preprocessor_replace(DOH *); - -/* Skip whitespace */ -static void skip_whitespace(String *s, String *out) { - int c; - while ((c = Getc(s)) != EOF) { - if (!isspace(c)) { - Ungetc(c, s); - break; - } else if (out) - Putc(c, out); - } -} - -/* Skip to a specified character taking line breaks into account */ -static int skip_tochar(String *s, int ch, String *out) { - int c; - while ((c = Getc(s)) != EOF) { - if (out) - Putc(c, out); - if (c == ch) - break; - if (c == '\\') { - c = Getc(s); - if ((c != EOF) && (out)) - Putc(c, out); - } - } - if (c == EOF) - return -1; - return 0; -} - -static void copy_location(const DOH *s1, DOH *s2) { - Setfile(s2, Getfile((DOH *) s1)); - Setline(s2, Getline((DOH *) s1)); -} - -static String *cpp_include(const_String_or_char_ptr fn, int sysfile) { - String *s = sysfile ? Swig_include_sys(fn) : Swig_include(fn); - if (s && single_include) { - String *file = Getfile(s); - if (Getattr(included_files, file)) { - Delete(s); - return 0; - } - Setattr(included_files, file, file); - } - if (!s) { - if (ignore_missing) { - Swig_warning(WARN_PP_MISSING_FILE, Getfile(fn), Getline(fn), "Unable to find '%s'\n", fn); - } else { - Swig_error(Getfile(fn), Getline(fn), "Unable to find '%s'\n", fn); - } - } else { - String *lf; - Seek(s, 0, SEEK_SET); - if (!dependencies) { - dependencies = NewList(); - } - lf = Copy(Swig_last_file()); - Append(dependencies, lf); - Delete(lf); - } - return s; -} - -static int is_digits(const String *str) { - const char *s = Char(str); - int isdigits = (*s != 0); - while (*s) { - if (!isdigit((int)*s)) { - isdigits = 0; - break; - } - s++; - } - return isdigits; -} - -List *Preprocessor_depend(void) { - return dependencies; -} - -/* ----------------------------------------------------------------------------- - * void Preprocessor_cpp_init() - Initialize the preprocessor - * ----------------------------------------------------------------------------- */ -static String *kpp_args = 0; -static String *kpp_define = 0; -static String *kpp_defined = 0; -static String *kpp_elif = 0; -static String *kpp_else = 0; -static String *kpp_endif = 0; -static String *kpp_expanded = 0; -static String *kpp_if = 0; -static String *kpp_ifdef = 0; -static String *kpp_ifndef = 0; -static String *kpp_name = 0; -static String *kpp_swigmacro = 0; -static String *kpp_symbols = 0; -static String *kpp_undef = 0; -static String *kpp_value = 0; -static String *kpp_varargs = 0; -static String *kpp_error = 0; -static String *kpp_warning = 0; -static String *kpp_line = 0; -static String *kpp_include = 0; -static String *kpp_pragma = 0; -static String *kpp_level = 0; - -static String *kpp_dline = 0; -static String *kpp_ddefine = 0; -static String *kpp_dinclude = 0; -static String *kpp_dimport = 0; -static String *kpp_dbeginfile = 0; -static String *kpp_dextern = 0; - -static String *kpp_LINE = 0; -static String *kpp_FILE = 0; - -static String *kpp_hash_if = 0; -static String *kpp_hash_elif = 0; - -void Preprocessor_init(void) { - Hash *s; - - kpp_args = NewString("args"); - kpp_define = NewString("define"); - kpp_defined = NewString("defined"); - kpp_else = NewString("else"); - kpp_elif = NewString("elif"); - kpp_endif = NewString("endif"); - kpp_expanded = NewString("*expanded*"); - kpp_if = NewString("if"); - kpp_ifdef = NewString("ifdef"); - kpp_ifndef = NewString("ifndef"); - kpp_name = NewString("name"); - kpp_swigmacro = NewString("swigmacro"); - kpp_symbols = NewString("symbols"); - kpp_undef = NewString("undef"); - kpp_value = NewString("value"); - kpp_error = NewString("error"); - kpp_warning = NewString("warning"); - kpp_pragma = NewString("pragma"); - kpp_level = NewString("level"); - kpp_line = NewString("line"); - kpp_include = NewString("include"); - kpp_varargs = NewString("varargs"); - - kpp_dinclude = NewString("%include"); - kpp_dimport = NewString("%import"); - kpp_dbeginfile = NewString("%beginfile"); - kpp_dextern = NewString("%extern"); - kpp_ddefine = NewString("%define"); - kpp_dline = NewString("%line"); - - - kpp_LINE = NewString("__LINE__"); - kpp_FILE = NewString("__FILE__"); - - kpp_hash_if = NewString("#if"); - kpp_hash_elif = NewString("#elif"); - - cpp = NewHash(); - s = NewHash(); - Setattr(cpp, kpp_symbols, s); - Delete(s); - Preprocessor_expr_init(); /* Initialize the expression evaluator */ - included_files = NewHash(); - - id_scan = NewScanner(); - -} - -void Preprocessor_delete(void) { - Delete(kpp_args); - Delete(kpp_define); - Delete(kpp_defined); - Delete(kpp_else); - Delete(kpp_elif); - Delete(kpp_endif); - Delete(kpp_expanded); - Delete(kpp_if); - Delete(kpp_ifdef); - Delete(kpp_ifndef); - Delete(kpp_name); - Delete(kpp_swigmacro); - Delete(kpp_symbols); - Delete(kpp_undef); - Delete(kpp_value); - Delete(kpp_error); - Delete(kpp_warning); - Delete(kpp_pragma); - Delete(kpp_level); - Delete(kpp_line); - Delete(kpp_include); - Delete(kpp_varargs); - - Delete(kpp_dinclude); - Delete(kpp_dimport); - Delete(kpp_dbeginfile); - Delete(kpp_dextern); - Delete(kpp_ddefine); - Delete(kpp_dline); - - Delete(kpp_LINE); - Delete(kpp_FILE); - - Delete(kpp_hash_if); - Delete(kpp_hash_elif); - - Delete(cpp); - Delete(included_files); - Preprocessor_expr_delete(); - DelScanner(id_scan); - - Delete(dependencies); - - Delete(Swig_add_directory(0)); -} - -/* ----------------------------------------------------------------------------- - * void Preprocessor_include_all() - Instruct preprocessor to include all files - * ----------------------------------------------------------------------------- */ -void Preprocessor_include_all(int a) { - include_all = a; -} - -void Preprocessor_import_all(int a) { - import_all = a; -} - -void Preprocessor_ignore_missing(int a) { - ignore_missing = a; -} - -void Preprocessor_error_as_warning(int a) { - error_as_warning = a; -} - - -/* ----------------------------------------------------------------------------- - * Preprocessor_define() - * - * Defines a new C preprocessor symbol. swigmacro specifies whether or not the macro has - * SWIG macro semantics. - * ----------------------------------------------------------------------------- */ - - -String *Macro_vararg_name(const_String_or_char_ptr str, const_String_or_char_ptr line) { - String *argname; - String *varargname; - char *s, *dots; - - argname = Copy(str); - s = Char(argname); - dots = strchr(s, '.'); - if (!dots) { - Delete(argname); - return NULL; - } - - if (strcmp(dots, "...") != 0) { - Swig_error(Getfile(line), Getline(line), "Illegal macro argument name '%s'\n", str); - Delete(argname); - return NULL; - } - if (dots == s) { - varargname = NewString("__VA_ARGS__"); - } else { - *dots = '\0'; - varargname = NewString(s); - } - Delete(argname); - return varargname; -} - -Hash *Preprocessor_define(const_String_or_char_ptr _str, int swigmacro) { - String *macroname = 0, *argstr = 0, *macrovalue = 0, *file = 0, *s = 0; - Hash *macro = 0, *symbols = 0, *m1; - List *arglist = 0; - int c, line; - int varargs = 0; - String *str; - - assert(cpp); - assert(_str); - - /* First make sure that string is actually a string */ - if (DohCheck(_str)) { - s = Copy(_str); - copy_location(_str, s); - str = s; - } else { - str = NewString((char *) _str); - } - Seek(str, 0, SEEK_SET); - line = Getline(str); - file = Getfile(str); - - /* Skip over any leading whitespace */ - skip_whitespace(str, 0); - - /* Now look for a macro name */ - macroname = NewStringEmpty(); - copy_location(str, macroname); - while ((c = Getc(str)) != EOF) { - if (c == '(') { - argstr = NewStringEmpty(); - copy_location(str, argstr); - /* It is a macro. Go extract its argument string */ - while ((c = Getc(str)) != EOF) { - if (c == ')') - break; - else - Putc(c, argstr); - } - if (c != ')') { - Swig_error(Getfile(argstr), Getline(argstr), "Missing \')\' in macro parameters\n"); - goto macro_error; - } - break; - } else if (isidchar(c) || (c == '%')) { - Putc(c, macroname); - } else if (isspace(c)) { - break; - } else if (c == '\\') { - c = Getc(str); - if (c != '\n') { - Ungetc(c, str); - Ungetc('\\', str); - break; - } - } else { - Ungetc(c, str); - break; - } - } - if (!swigmacro) - skip_whitespace(str, 0); - macrovalue = NewStringEmpty(); - copy_location(str, macrovalue); - while ((c = Getc(str)) != EOF) { - Putc(c, macrovalue); - } - - /* If there are any macro arguments, convert into a list */ - if (argstr) { - String *argname, *varargname; - arglist = NewList(); - Seek(argstr, 0, SEEK_SET); - argname = NewStringEmpty(); - while ((c = Getc(argstr)) != EOF) { - if (c == ',') { - varargname = Macro_vararg_name(argname, argstr); - if (varargname) { - Delete(varargname); - Swig_error(Getfile(argstr), Getline(argstr), "Variable length macro argument must be last parameter\n"); - } else { - Append(arglist, argname); - } - Delete(argname); - argname = NewStringEmpty(); - } else if (isidchar(c) || (c == '.')) { - Putc(c, argname); - } else if (!(isspace(c) || (c == '\\'))) { - Delete(argname); - Swig_error(Getfile(argstr), Getline(argstr), "Illegal character in macro argument name\n"); - goto macro_error; - } - } - if (Len(argname)) { - /* Check for varargs */ - varargname = Macro_vararg_name(argname, argstr); - if (varargname) { - Append(arglist, varargname); - Delete(varargname); - varargs = 1; - } else { - Append(arglist, argname); - } - } - Delete(argname); - } - - if (!swigmacro) { - Replace(macrovalue, "\\\n", " ", DOH_REPLACE_NOQUOTE); - } - - /* Look for special # substitutions. We only consider # that appears - outside of quotes and comments */ - - { - int state = 0; - char *cc = Char(macrovalue); - while (*cc) { - switch (state) { - case 0: - if (*cc == '#') - *cc = '\001'; - else if (*cc == '/') - state = 10; - else if (*cc == '\'') - state = 20; - else if (*cc == '\"') - state = 30; - break; - case 10: - if (*cc == '*') - state = 11; - else if (*cc == '/') - state = 15; - else { - state = 0; - cc--; - } - break; - case 11: - if (*cc == '*') - state = 12; - break; - case 12: - if (*cc == '/') - state = 0; - else if (*cc != '*') - state = 11; - break; - case 15: - if (*cc == '\n') - state = 0; - break; - case 20: - if (*cc == '\'') - state = 0; - if (*cc == '\\') - state = 21; - break; - case 21: - state = 20; - break; - case 30: - if (*cc == '\"') - state = 0; - if (*cc == '\\') - state = 31; - break; - case 31: - state = 30; - break; - default: - break; - } - cc++; - } - } - - /* Get rid of whitespace surrounding # */ - /* Replace(macrovalue,"#","\001",DOH_REPLACE_NOQUOTE); */ - while (strstr(Char(macrovalue), "\001 ")) { - Replace(macrovalue, "\001 ", "\001", DOH_REPLACE_ANY); - } - while (strstr(Char(macrovalue), " \001")) { - Replace(macrovalue, " \001", "\001", DOH_REPLACE_ANY); - } - /* Replace '##' with a special token */ - Replace(macrovalue, "\001\001", "\002", DOH_REPLACE_ANY); - /* Replace '#@' with a special token */ - Replace(macrovalue, "\001@", "\004", DOH_REPLACE_ANY); - /* Replace '##@' with a special token */ - Replace(macrovalue, "\002@", "\005", DOH_REPLACE_ANY); - - /* Go create the macro */ - macro = NewHash(); - Setattr(macro, kpp_name, macroname); - - if (arglist) { - Setattr(macro, kpp_args, arglist); - Delete(arglist); - if (varargs) { - Setattr(macro, kpp_varargs, "1"); - } - } - Setattr(macro, kpp_value, macrovalue); - Setline(macro, line); - Setfile(macro, file); - if (swigmacro) { - Setattr(macro, kpp_swigmacro, "1"); - } - symbols = Getattr(cpp, kpp_symbols); - if ((m1 = Getattr(symbols, macroname))) { - if (!Checkattr(m1, kpp_value, macrovalue)) { - Swig_error(Getfile(macroname), Getline(macroname), "Macro '%s' redefined,\n", macroname); - Swig_error(Getfile(m1), Getline(m1), "previous definition of '%s'.\n", macroname); - goto macro_error; - } - } else { - Setattr(symbols, macroname, macro); - Delete(macro); - } - - Delete(macroname); - Delete(macrovalue); - - Delete(str); - Delete(argstr); - return macro; - -macro_error: - Delete(str); - Delete(argstr); - Delete(arglist); - Delete(macroname); - Delete(macrovalue); - return 0; -} - -/* ----------------------------------------------------------------------------- - * Preprocessor_undef() - * - * Undefines a macro. - * ----------------------------------------------------------------------------- */ -void Preprocessor_undef(const_String_or_char_ptr str) { - Hash *symbols; - assert(cpp); - symbols = Getattr(cpp, kpp_symbols); - Delattr(symbols, str); -} - -/* ----------------------------------------------------------------------------- - * find_args() - * - * Isolates macro arguments and returns them in a list. For each argument, - * leading and trailing whitespace is stripped (ala K&R, pg. 230). - * ----------------------------------------------------------------------------- */ -static List *find_args(String *s, int ismacro, String *macro_name) { - List *args; - String *str; - int c, level; - long pos; - - /* Create a new list */ - args = NewList(); - copy_location(s, args); - - /* First look for a '(' */ - pos = Tell(s); - skip_whitespace(s, 0); - - /* Now see if the next character is a '(' */ - c = Getc(s); - if (c != '(') { - /* Not a macro, bail out now! */ - assert(pos != -1); - (void)Seek(s, pos, SEEK_SET); - Delete(args); - return 0; - } - c = Getc(s); - /* Okay. This appears to be a macro so we will start isolating arguments */ - while (c != EOF) { - if (isspace(c)) { - skip_whitespace(s, 0); /* Skip leading whitespace */ - c = Getc(s); - } - str = NewStringEmpty(); - copy_location(s, str); - level = 0; - while (c != EOF) { - if (c == '\"') { - Putc(c, str); - skip_tochar(s, '\"', str); - c = Getc(s); - continue; - } else if (c == '\'') { - Putc(c, str); - skip_tochar(s, '\'', str); - c = Getc(s); - continue; - } else if (c == '/') { - /* Ensure comments are ignored by eating up the characters */ - c = Getc(s); - /* Handle / * ... * / type comments (multi-line) */ - if (c == '*') { - while ((c = Getc(s)) != EOF) { - if (c == '*') { - c = Getc(s); - if (c == '/' || c == EOF) - break; - } - } - c = Getc(s); - continue; - } - /* Handle // ... type comments (single-line) */ - if (c == '/') { - while ((c = Getc(s)) != EOF) { - if (c == '\n') { - break; - } - } - c = Getc(s); - continue; - } - /* ensure char is available in the stream as this was not a comment*/ - Ungetc(c, s); - c = '/'; - } - if ((c == ',') && (level == 0)) - break; - if ((c == ')') && (level == 0)) - break; - Putc(c, str); - if (c == '(') - level++; - if (c == ')') - level--; - c = Getc(s); - } - if (level > 0) { - goto unterm; - } - Chop(str); - Append(args, str); - Delete(str); - if (c == ')') - return args; - c = Getc(s); - } -unterm: - if (ismacro) - Swig_error(Getfile(args), Getline(args), "Unterminated call invoking macro '%s'\n", macro_name); - else - Swig_error(Getfile(args), Getline(args), "Unterminated call to '%s'\n", macro_name); - return args; -} - -/* ----------------------------------------------------------------------------- - * DOH *get_filename() - * - * Read a filename from str. A filename can be enclosed in quotes, angle brackets, - * or bare. - * ----------------------------------------------------------------------------- */ - -static String *get_filename(String *str, int *sysfile) { - String *fn; - int c; - - fn = NewStringEmpty(); - copy_location(str, fn); - c = Getc(str); - *sysfile = 0; - if (c == '\"') { - while (((c = Getc(str)) != EOF) && (c != '\"')) - Putc(c, fn); - } else if (c == '<') { - *sysfile = 1; - while (((c = Getc(str)) != EOF) && (c != '>')) - Putc(c, fn); - } else { - String *preprocessed_str; - Putc(c, fn); - while (((c = Getc(str)) != EOF) && (!isspace(c))) - Putc(c, fn); - if (isspace(c)) - Ungetc(c, str); - preprocessed_str = Preprocessor_replace(fn); - Seek(preprocessed_str, 0, SEEK_SET); - Delete(fn); - - fn = NewStringEmpty(); - copy_location(preprocessed_str, fn); - c = Getc(preprocessed_str); - if (c == '\"') { - while (((c = Getc(preprocessed_str)) != EOF) && (c != '\"')) - Putc(c, fn); - } else if (c == '<') { - *sysfile = 1; - while (((c = Getc(preprocessed_str)) != EOF) && (c != '>')) - Putc(c, fn); - } else { - fn = Copy(preprocessed_str); - } - Delete(preprocessed_str); - } - Swig_filename_unescape(fn); - Swig_filename_correct(fn); - Seek(fn, 0, SEEK_SET); - return fn; -} - -static String *get_options(String *str) { - int c; - c = Getc(str); - if (c == '(') { - String *opt; - int level = 1; - opt = NewString("("); - while (((c = Getc(str)) != EOF)) { - Putc(c, opt); - switch (c) { - case ')': - level--; - if (!level) - return opt; - break; - case '(': - level++; - break; - case '"': - /* Skip over quoted strings */ - while (1) { - c = Getc(str); - if (c == EOF) - goto bad; - Putc(c, opt); - if (c == '"') - break; - if (c == '\\') { - c = Getc(str); - if (c == EOF) - goto bad; - Putc(c, opt); - } - } - break; - } - } -bad: - Delete(opt); - return 0; - } else { - Ungetc(c, str); - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * expand_macro() - * - * Perform macro expansion and return a new string. Returns NULL if some sort - * of error occurred. - * name - name of the macro - * args - arguments passed to the macro - * line_file - only used for line/file name when reporting errors - * ----------------------------------------------------------------------------- */ - -static String *expand_macro(String *name, List *args, String *line_file) { - String *ns; - DOH *symbols, *macro, *margs, *mvalue, *temp, *tempa, *e; - int i, l; - int isvarargs = 0; - - symbols = Getattr(cpp, kpp_symbols); - if (!symbols) - return 0; - - /* See if the name is actually defined */ - macro = Getattr(symbols, name); - if (!macro) - return 0; - - if (macro_level == 0) { - /* Store the start of the macro should the macro contain __LINE__ and __FILE__ for expansion */ - macro_start_line = Getline(args ? args : line_file); - macro_start_file = Getfile(args ? args : line_file); - } - macro_level++; - - if (Getattr(macro, kpp_expanded)) { - ns = NewStringEmpty(); - Append(ns, name); - if (args) { - int lenargs = Len(args); - if (lenargs) - Putc('(', ns); - for (i = 0; i < lenargs; i++) { - Append(ns, Getitem(args, i)); - if (i < (lenargs - 1)) - Putc(',', ns); - } - if (i) - Putc(')', ns); - } - macro_level--; - return ns; - } - - /* Get macro arguments and value */ - mvalue = Getattr(macro, kpp_value); - assert(mvalue); - margs = Getattr(macro, kpp_args); - - if (args && Getattr(macro, kpp_varargs)) { - isvarargs = 1; - /* Variable length argument macro. We need to collect all of the extra arguments into a single argument */ - if (Len(args) >= (Len(margs) - 1)) { - int i; - int vi, na; - String *vararg = NewStringEmpty(); - vi = Len(margs) - 1; - na = Len(args); - for (i = vi; i < na; i++) { - Append(vararg, Getitem(args, i)); - if ((i + 1) < na) { - Append(vararg, ","); - } - } - /* Remove arguments */ - for (i = vi; i < na; i++) { - Delitem(args, vi); - } - Append(args, vararg); - Delete(vararg); - } - } - - if (args && margs && Len(margs) == 0 && Len(args) == 1 && Len(Getitem(args, 0)) == 0) { - /* FOO() can invoke a macro defined as FOO(X) as well as one defined FOO(). - * - * Handle this by removing the only argument if it's empty and the macro - * expects no arguments. - * - * We don't need to worry about varargs here - a varargs macro will always have - * Len(margs) >= 1, since the varargs are put in the final macro argument. - */ - Delitem(args, 0); - } - - /* If there are arguments, see if they match what we were given */ - if (args && (!margs || Len(margs) != Len(args))) { - if (margs && Len(margs) > (1 + isvarargs)) - Swig_error(macro_start_file, macro_start_line, "Macro '%s' expects %d arguments\n", name, Len(margs) - isvarargs); - else if (margs && Len(margs) == (1 + isvarargs)) - Swig_error(macro_start_file, macro_start_line, "Macro '%s' expects 1 argument\n", name); - else - Swig_error(macro_start_file, macro_start_line, "Macro '%s' expects no arguments\n", name); - macro_level--; - return 0; - } - - /* If the macro expects arguments, but none were supplied, we leave it in place */ - if (!args && margs) { - macro_level--; - return NewString(name); - } - - /* Copy the macro value */ - ns = Copy(mvalue); - copy_location(mvalue, ns); - - /* Tag the macro as being expanded. This is to avoid recursion in - macro expansion */ - - temp = NewStringEmpty(); - tempa = NewStringEmpty(); - if (args && margs) { - l = Len(margs); - for (i = 0; i < l; i++) { - DOH *arg, *aname; - String *reparg; - arg = Getitem(args, i); /* Get an argument value */ - reparg = Preprocessor_replace(arg); - aname = Getitem(margs, i); /* Get macro argument name */ - if (strstr(Char(ns), "\001")) { - /* Try to replace a quoted version of the argument */ - Clear(temp); - Clear(tempa); - Printf(temp, "\001%s", aname); - Printf(tempa, "\"%s\"", arg); - Replace(ns, temp, tempa, DOH_REPLACE_ID_END); - } - if (strstr(Char(ns), "\002")) { - /* Look for concatenation tokens */ - Clear(temp); - Clear(tempa); - Printf(temp, "\002%s", aname); - Append(tempa, "\002\003"); - Replace(ns, temp, tempa, DOH_REPLACE_ID_END); - Clear(temp); - Clear(tempa); - Printf(temp, "%s\002", aname); - Append(tempa, "\003\002"); - Replace(ns, temp, tempa, DOH_REPLACE_ID_BEGIN); - } - - /* Non-standard macro expansion. The value `x` is replaced by a quoted - version of the argument except that if the argument is already quoted - nothing happens */ - - if (strchr(Char(ns), '`')) { - String *rep; - char *c; - Clear(temp); - Printf(temp, "`%s`", aname); - c = Char(arg); - if (*c == '\"') { - rep = arg; - } else { - Clear(tempa); - Printf(tempa, "\"%s\"", arg); - rep = tempa; - } - Replace(ns, temp, rep, DOH_REPLACE_ANY); - } - - /* Non-standard mangle expansions. - The #@Name is replaced by mangle_arg(Name). */ - if (strstr(Char(ns), "\004")) { - String *marg = Swig_string_mangle(arg); - Clear(temp); - Printf(temp, "\004%s", aname); - Replace(ns, temp, marg, DOH_REPLACE_ID_END); - Delete(marg); - } - if (strstr(Char(ns), "\005")) { - String *marg = Swig_string_mangle(arg); - Clear(temp); - Clear(tempa); - Printf(temp, "\005%s", aname); - Printf(tempa, "\"%s\"", marg); - Replace(ns, temp, tempa, DOH_REPLACE_ID_END); - Delete(marg); - } - - if (isvarargs && i == l - 1 && Len(arg) == 0) { - /* Zero length varargs macro argument. We search for commas that might appear before and nuke them */ - char *a, *s, *t, *name; - int namelen; - s = Char(ns); - name = Char(aname); - namelen = Len(aname); - a = strstr(s, name); - while (a) { - char ca = a[namelen]; - if (!isidchar((int) ca)) { - /* Matched the entire vararg name, not just a prefix */ - if (a > s) { - t = a - 1; - if (*t == '\002') { - t--; - while (t >= s) { - if (isspace((int) *t)) - t--; - else if (*t == ',') { - *t = ' '; - } else - break; - } - } - } - } - a = strstr(a + namelen, name); - } - } - /* Replace(ns, aname, arg, DOH_REPLACE_ID); */ - Replace(ns, aname, reparg, DOH_REPLACE_ID); /* Replace expanded args */ - Replace(ns, "\003", arg, DOH_REPLACE_ANY); /* Replace unexpanded arg */ - Delete(reparg); - } - } - Replace(ns, "\002", "", DOH_REPLACE_ANY); /* Get rid of concatenation tokens */ - Replace(ns, "\001", "#", DOH_REPLACE_ANY); /* Put # back (non-standard C) */ - Replace(ns, "\004", "#@", DOH_REPLACE_ANY); /* Put # back (non-standard C) */ - - /* Expand this macro even further */ - Setattr(macro, kpp_expanded, "1"); - - e = Preprocessor_replace(ns); - - Delattr(macro, kpp_expanded); - Delete(ns); - - if (Getattr(macro, kpp_swigmacro)) { - String *g; - String *f = NewStringEmpty(); - Seek(e, 0, SEEK_SET); - copy_location(macro, e); - g = Preprocessor_parse(e); - -#if 0 - /* Drop the macro in place, but with a marker around it */ - Printf(f, "/*@%s,%d,%s@*/%s/*@@*/", Getfile(macro), Getline(macro), name, g); -#else - /* Use simplified around markers to properly count lines in cscanner.c */ - if (strchr(Char(g), '\n')) { - Printf(f, "/*@SWIG:%s,%d,%s@*/%s/*@SWIG@*/", Getfile(macro), Getline(macro), name, g); -#if 0 - Printf(f, "/*@SWIG:%s@*/%s/*@SWIG@*/", name, g); -#endif - } else { - Append(f, g); - } -#endif - - Delete(g); - Delete(e); - e = f; - } - macro_level--; - Delete(temp); - Delete(tempa); - return e; -} - -/* ----------------------------------------------------------------------------- - * DOH *Preprocessor_replace(DOH *s) - * - * Performs a macro substitution on a string s. Returns a new string with - * substitutions applied. This function works by walking down s and looking - * for identifiers. When found, a check is made to see if they are macros - * which are then expanded. - * ----------------------------------------------------------------------------- */ - -/* #define SWIG_PUT_BUFF */ - -static DOH *Preprocessor_replace(DOH *s) { - DOH *ns, *symbols, *m; - int c, i, state = 0; - String *id = NewStringEmpty(); - - assert(cpp); - symbols = Getattr(cpp, kpp_symbols); - - ns = NewStringEmpty(); - copy_location(s, ns); - Seek(s, 0, SEEK_SET); - - /* Try to locate identifiers in s and replace them with macro replacements */ - while ((c = Getc(s)) != EOF) { - switch (state) { - case 0: - if (isidentifier(c)) { - Clear(id); - Putc(c, id); - state = 4; - } else if (c == '%') { - Clear(id); - Putc(c, id); - state = 2; - } else if (c == '#') { - Clear(id); - Putc(c, id); - state = 4; - } else if (c == '\"') { - Putc(c, ns); - skip_tochar(s, '\"', ns); - } else if (c == '\'') { - Putc(c, ns); - skip_tochar(s, '\'', ns); - } else if (c == '/') { - Putc(c, ns); - state = 10; - } else if (c == '\\') { - Putc(c, ns); - c = Getc(s); - if (c == '\n') { - Putc(c, ns); - } else { - Ungetc(c, s); - } - } else if (c == '\n') { - Putc(c, ns); - expand_defined_operator = 0; - } else { - Putc(c, ns); - } - break; - case 2: - /* Found '%#' */ - if (c == '#') { - Putc(c, id); - state = 4; - } else { - Ungetc(c, s); - state = 4; - } - break; - case 4: /* An identifier */ - if (isidchar(c)) { - Putc(c, id); - state = 4; - } else { - /* We found the end of a valid identifier */ - Ungetc(c, s); - /* See if this is the special "defined" operator */ - if (Equal(kpp_defined, id)) { - if (expand_defined_operator) { - int lenargs = 0; - DOH *args = 0; - /* See whether or not a parenthesis has been used */ - skip_whitespace(s, 0); - c = Getc(s); - if (c == '(') { - Ungetc(c, s); - args = find_args(s, 0, kpp_defined); - } else if (isidchar(c)) { - DOH *arg = NewStringEmpty(); - args = NewList(); - Putc(c, arg); - while (((c = Getc(s)) != EOF)) { - if (!isidchar(c)) { - Ungetc(c, s); - break; - } - Putc(c, arg); - } - if (Len(arg)) - Append(args, arg); - Delete(arg); - } else { - Seek(s, -1, SEEK_CUR); - } - lenargs = Len(args); - if ((!args) || (!lenargs)) { - /* This is not a defined() operator. */ - Append(ns, id); - state = 0; - break; - } - for (i = 0; i < lenargs; i++) { - DOH *o = Getitem(args, i); - if (!Getattr(symbols, o)) { - break; - } - } - if (i < lenargs) - Putc('0', ns); - else - Putc('1', ns); - Delete(args); - } else { - Append(ns, id); - } - state = 0; - break; - } else if (Equal(kpp_LINE, id)) { - Printf(ns, "%d", macro_level > 0 ? macro_start_line : Getline(s)); - state = 0; - break; - } else if (Equal(kpp_FILE, id)) { - String *fn = Copy(macro_level > 0 ? macro_start_file : Getfile(s)); - Replaceall(fn, "\\", "\\\\"); - Printf(ns, "\"%s\"", fn); - Delete(fn); - state = 0; - break; - } else if (Equal(kpp_hash_if, id) || Equal(kpp_hash_elif, id)) { - expand_defined_operator = 1; - Append(ns, id); - /* - } else if (Equal("%#if", id) || Equal("%#ifdef", id)) { - Swig_warning(998, Getfile(s), Getline(s), "Found: %s preprocessor directive.\n", id); - Append(ns, id); - } else if (Equal("#ifdef", id) || Equal("#ifndef", id)) { - Swig_warning(998, Getfile(s), Getline(s), "The %s preprocessor directive does not work in macros, try #if instead.\n", id); - Append(ns, id); - */ - } else if ((m = Getattr(symbols, id))) { - /* See if the macro is defined in the preprocessor symbol table */ - DOH *args = 0; - DOH *e; - int macro_additional_lines = 0; - /* See if the macro expects arguments */ - if (Getattr(m, kpp_args)) { - /* Yep. We need to go find the arguments and do a substitution */ - int line = Getline(s); - args = find_args(s, 1, id); - macro_additional_lines = Getline(s) - line; - assert(macro_additional_lines >= 0); - } else { - args = 0; - } - e = expand_macro(id, args, s); - if (e) { - Append(ns, e); - } - while (macro_additional_lines--) { - Putc('\n', ns); - } - Delete(e); - Delete(args); - } else { - Append(ns, id); - } - state = 0; - } - break; - case 10: - if (c == '/') - state = 11; - else if (c == '*') - state = 12; - else { - Ungetc(c, s); - state = 0; - break; - } - Putc(c, ns); - break; - case 11: - /* in C++ comment */ - Putc(c, ns); - if (c == '\n') { - expand_defined_operator = 0; - state = 0; - } - break; - case 12: - /* in C comment */ - Putc(c, ns); - if (c == '*') - state = 13; - break; - case 13: - Putc(c, ns); - if (c == '/') - state = 0; - else if (c != '*') - state = 12; - break; - default: - state = 0; - break; - } - } - - /* Identifier at the end */ - if (state == 2 || state == 4) { - /* See if this is the special "defined" operator */ - if (Equal(kpp_defined, id)) { - Swig_error(Getfile(s), Getline(s), "No arguments given to defined()\n"); - } else if (Equal(kpp_LINE, id)) { - Printf(ns, "%d", macro_level > 0 ? macro_start_line : Getline(s)); - } else if (Equal(kpp_FILE, id)) { - String *fn = Copy(macro_level > 0 ? macro_start_file : Getfile(s)); - Replaceall(fn, "\\", "\\\\"); - Printf(ns, "\"%s\"", fn); - Delete(fn); - } else if (Getattr(symbols, id)) { - DOH *e; - /* Yes. There is a macro here */ - /* See if the macro expects arguments */ - e = expand_macro(id, 0, s); - if (e) - Append(ns, e); - Delete(e); - } else { - Append(ns, id); - } - } - Delete(id); - return ns; -} - - -/* ----------------------------------------------------------------------------- - * int checkpp_id(DOH *s) - * - * Checks the string s to see if it contains any unresolved identifiers. This - * function contains the heuristic that determines whether or not a macro - * definition passes through the preprocessor as a constant declaration. - * ----------------------------------------------------------------------------- */ -static int checkpp_id(DOH *s) { - int c; - int hastok = 0; - Scanner *scan = id_scan; - - Seek(s, 0, SEEK_SET); - - Scanner_clear(scan); - s = Copy(s); - Seek(s, SEEK_SET, 0); - Scanner_push(scan, s); - while ((c = Scanner_token(scan))) { - hastok = 1; - if ((c == SWIG_TOKEN_ID) || (c == SWIG_TOKEN_LBRACE) || (c == SWIG_TOKEN_RBRACE)) - return 1; - } - if (!hastok) - return 1; - return 0; -} - -/* addline(). Utility function for adding lines to a chunk */ -static void addline(DOH *s1, DOH *s2, int allow) { - if (allow) { - Append(s1, s2); - } else { - char *c = Char(s2); - while (*c) { - if (*c == '\n') - Putc('\n', s1); - c++; - } - } -} - -static void add_chunk(DOH *ns, DOH *chunk, int allow) { - DOH *echunk; - Seek(chunk, 0, SEEK_SET); - if (allow) { - echunk = Preprocessor_replace(chunk); - addline(ns, echunk, allow); - Delete(echunk); - } else { - addline(ns, chunk, 0); - } - Clear(chunk); -} - -/* - push/pop_imported(): helper functions for defining and undefining - SWIGIMPORTED (when %importing a file). - */ -static void push_imported(void) { - if (imported_depth == 0) { - Preprocessor_define("SWIGIMPORTED 1", 0); - } - ++imported_depth; -} - -static void pop_imported(void) { - --imported_depth; - if (imported_depth == 0) { - Preprocessor_undef("SWIGIMPORTED"); - } -} - - -/* ----------------------------------------------------------------------------- - * Preprocessor_parse() - * - * Parses the string s. Returns a new string containing the preprocessed version. - * - * Parsing rules : - * 1. Lines starting with # are C preprocessor directives - * 2. Macro expansion inside strings is not allowed - * 3. All code inside false conditionals is changed to blank lines - * 4. Code in %{, %} is not parsed because it may need to be - * included inline (with all preprocessor directives included). - * ----------------------------------------------------------------------------- */ - -String *Preprocessor_parse(String *s) { - String *ns; /* New string containing the preprocessed text */ - String *chunk, *decl; - Hash *symbols; - String *id = 0, *value = 0, *comment = 0; - int i, state, e, c; - int start_line = 0; - int allow = 1; - int level = 0; - int dlevel = 0; - int filelevel = 0; - int mask = 0; - int start_level = 0; - int cpp_lines = 0; - int cond_lines[256]; - - /* Blow away all carriage returns */ - Replace(s, "\015", "", DOH_REPLACE_ANY); - - ns = NewStringEmpty(); /* Return result */ - - decl = NewStringEmpty(); - id = NewStringEmpty(); - value = NewStringEmpty(); - comment = NewStringEmpty(); - chunk = NewStringEmpty(); - copy_location(s, chunk); - copy_location(s, ns); - symbols = Getattr(cpp, kpp_symbols); - - state = 0; - while ((c = Getc(s)) != EOF) { - switch (state) { - case 0: /* Initial state - in first column */ - /* Look for C preprocessor directives. Otherwise, go directly to state 1 */ - if (c == '#') { - copy_location(s, chunk); - add_chunk(ns, chunk, allow); - cpp_lines = 1; - state = 40; - } else if (isspace(c)) { - Putc(c, chunk); - skip_whitespace(s, chunk); - } else { - state = 1; - Ungetc(c, s); - } - break; - case 1: /* Non-preprocessor directive */ - /* Look for SWIG directives */ - if (c == '%') { - state = 100; - break; - } - Putc(c, chunk); - if (c == '\n') - state = 0; - else if (c == '\"') { - start_line = Getline(s); - if (skip_tochar(s, '\"', chunk) < 0) { - Swig_error(Getfile(s), start_line, "Unterminated string constant\n"); - } - } else if (c == '\'') { - start_line = Getline(s); - if (skip_tochar(s, '\'', chunk) < 0) { - Swig_error(Getfile(s), start_line, "Unterminated character constant\n"); - } - } else if (c == '/') - state = 30; /* Comment */ - break; - - case 30: /* Possibly a comment string of some sort */ - start_line = Getline(s); - Putc(c, chunk); - if (c == '/') - state = 31; - else if (c == '*') - state = 32; - else - state = 1; - break; - case 31: - Putc(c, chunk); - if (c == '\n') - state = 0; - break; - case 32: - Putc(c, chunk); - if (c == '*') - state = 33; - break; - case 33: - Putc(c, chunk); - if (c == '/') - state = 1; - else if (c != '*') - state = 32; - break; - - case 40: /* Start of a C preprocessor directive */ - if (c == '\n') { - Putc('\n', chunk); - state = 0; - } else if (isspace(c)) { - state = 40; - } else { - /* Got the start of a preprocessor directive */ - Ungetc(c, s); - Clear(id); - copy_location(s, id); - state = 41; - } - break; - - case 41: /* Build up the name of the preprocessor directive */ - if ((isspace(c) || (!isidchar(c)))) { - Clear(value); - Clear(comment); - if (c == '\n') { - Ungetc(c, s); - state = 50; - } else { - state = 42; - if (!isspace(c)) { - Ungetc(c, s); - } - } - - copy_location(s, value); - break; - } - Putc(c, id); - break; - - case 42: /* Strip any leading space after the preprocessor directive (before preprocessor value) */ - if (isspace(c)) { - if (c == '\n') { - Ungetc(c, s); - state = 50; - } - break; - } - state = 43; - /* FALL THRU */ - - case 43: - /* Get preprocessor value */ - if (c == '\n') { - Ungetc(c, s); - state = 50; - } else if (c == '/') { - state = 45; - } else if (c == '\"') { - Putc(c, value); - skip_tochar(s, '\"', value); - } else if (c == '\'') { - Putc(c, value); - skip_tochar(s, '\'', value); - } else { - Putc(c, value); - if (c == '\\') - state = 44; - } - break; - - case 44: - if (c == '\n') { - Putc(c, value); - cpp_lines++; - } else { - Ungetc(c, s); - } - state = 43; - break; - - /* States 45-48 are used to remove, but retain comments from macro values. The comments - will be placed in the output in an alternative form */ - - case 45: - if (c == '/') - state = 46; - else if (c == '*') - state = 47; - else if (c == '\n') { - Putc('/', value); - Ungetc(c, s); - state = 50; - } else { - Putc('/', value); - Putc(c, value); - state = 43; - } - break; - case 46: /* in C++ comment */ - if (c == '\n') { - Ungetc(c, s); - state = 50; - } else - Putc(c, comment); - break; - case 47: /* in C comment */ - if (c == '*') - state = 48; - else - Putc(c, comment); - break; - case 48: - if (c == '/') - state = 43; - else if (c == '*') - Putc(c, comment); - else { - Putc('*', comment); - Putc(c, comment); - state = 47; - } - break; - case 50: - /* Check for various preprocessor directives */ - Chop(value); - if (Equal(id, kpp_define)) { - if (allow) { - DOH *m, *v, *v1; - Seek(value, 0, SEEK_SET); - m = Preprocessor_define(value, 0); - if ((m) && !(Getattr(m, kpp_args))) { - v = Copy(Getattr(m, kpp_value)); - copy_location(m, v); - if (Len(v)) { - Swig_error_silent(1); - v1 = Preprocessor_replace(v); - Swig_error_silent(0); - /* Printf(stdout,"checking '%s'\n", v1); */ - if (!checkpp_id(v1)) { - if (Len(comment) == 0) - Printf(ns, "%%constant %s = %s;\n", Getattr(m, kpp_name), v1); - else - Printf(ns, "%%constant %s = %s; /*%s*/\n", Getattr(m, kpp_name), v1, comment); - cpp_lines--; - } - Delete(v1); - } - Delete(v); - } - } - } else if (Equal(id, kpp_undef)) { - if (allow) - Preprocessor_undef(value); - } else if (Equal(id, kpp_ifdef)) { - cond_lines[level] = Getline(id); - level++; - if (allow) { - start_level = level; - if (Len(value) > 0) { - /* See if the identifier is in the hash table */ - if (!Getattr(symbols, value)) - allow = 0; - } else { - Swig_error(Getfile(s), Getline(id), "Missing identifier for #ifdef.\n"); - allow = 0; - } - mask = 1; - } - } else if (Equal(id, kpp_ifndef)) { - cond_lines[level] = Getline(id); - level++; - if (allow) { - start_level = level; - if (Len(value) > 0) { - /* See if the identifier is in the hash table */ - if (Getattr(symbols, value)) - allow = 0; - } else { - Swig_error(Getfile(s), Getline(id), "Missing identifier for #ifndef.\n"); - allow = 0; - } - mask = 1; - } - } else if (Equal(id, kpp_else)) { - if (level <= 0) { - Swig_error(Getfile(s), Getline(id), "Misplaced #else.\n"); - } else { - cond_lines[level - 1] = Getline(id); - if (Len(value) != 0) - Swig_warning(WARN_PP_UNEXPECTED_TOKENS, Getfile(s), Getline(id), "Unexpected tokens after #else directive.\n"); - if (allow) { - allow = 0; - mask = 0; - } else if (level == start_level) { - allow = 1 * mask; - } - } - } else if (Equal(id, kpp_endif)) { - level--; - if (level < 0) { - Swig_error(Getfile(id), Getline(id), "Extraneous #endif.\n"); - level = 0; - } else { - if (level < start_level) { - if (Len(value) != 0) - Swig_warning(WARN_PP_UNEXPECTED_TOKENS, Getfile(s), Getline(id), "Unexpected tokens after #endif directive.\n"); - allow = 1; - start_level--; - } - } - } else if (Equal(id, kpp_if)) { - cond_lines[level] = Getline(id); - level++; - if (allow) { - int val; - String *sval; - expand_defined_operator = 1; - sval = Preprocessor_replace(value); - start_level = level; - Seek(sval, 0, SEEK_SET); - /* Printf(stdout,"Evaluating '%s'\n", sval); */ - if (Len(sval) > 0) { - val = Preprocessor_expr(sval, &e); - if (e) { - const char *msg = Preprocessor_expr_error(); - Seek(value, 0, SEEK_SET); - Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Could not evaluate expression '%s'\n", value); - if (msg) - Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "%s\n", msg); - allow = 0; - } else { - if (val == 0) - allow = 0; - } - } else { - Swig_error(Getfile(s), Getline(id), "Missing expression for #if.\n"); - allow = 0; - } - expand_defined_operator = 0; - mask = 1; - } - } else if (Equal(id, kpp_elif)) { - if (level == 0) { - Swig_error(Getfile(s), Getline(id), "Misplaced #elif.\n"); - } else { - cond_lines[level - 1] = Getline(id); - if (allow) { - allow = 0; - mask = 0; - } else if (level == start_level) { - int val; - String *sval; - expand_defined_operator = 1; - sval = Preprocessor_replace(value); - Seek(sval, 0, SEEK_SET); - if (Len(sval) > 0) { - val = Preprocessor_expr(sval, &e); - if (e) { - const char *msg = Preprocessor_expr_error(); - Seek(value, 0, SEEK_SET); - Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Could not evaluate expression '%s'\n", value); - if (msg) - Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "%s\n", msg); - allow = 0; - } else { - if (val) - allow = 1 * mask; - else - allow = 0; - } - } else { - Swig_error(Getfile(s), Getline(id), "Missing expression for #elif.\n"); - allow = 0; - } - expand_defined_operator = 0; - } - } - } else if (Equal(id, kpp_warning)) { - if (allow) { - Swig_warning(WARN_PP_CPP_WARNING, Getfile(s), Getline(id), "CPP #warning, \"%s\".\n", value); - } - } else if (Equal(id, kpp_error)) { - if (allow) { - if (error_as_warning) { - Swig_warning(WARN_PP_CPP_ERROR, Getfile(s), Getline(id), "CPP #error \"%s\".\n", value); - } else { - Swig_error(Getfile(s), Getline(id), "CPP #error \"%s\". Use the -cpperraswarn option to continue swig processing.\n", value); - } - } - } else if (Equal(id, kpp_line)) { - } else if (Equal(id, kpp_include)) { - if (((include_all) || (import_all)) && (allow)) { - String *s1, *s2, *fn; - String *dirname; - int sysfile = 0; - if (include_all && import_all) { - Swig_warning(WARN_PP_INCLUDEALL_IMPORTALL, Getfile(s), Getline(id), "Both includeall and importall are defined: using includeall.\n"); - import_all = 0; - } - Seek(value, 0, SEEK_SET); - fn = get_filename(value, &sysfile); - s1 = cpp_include(fn, sysfile); - if (s1) { - if (include_all) - Printf(ns, "%%includefile \"%s\" %%beginfile\n", Swig_filename_escape(Swig_last_file())); - else if (import_all) { - Printf(ns, "%%importfile \"%s\" %%beginfile\n", Swig_filename_escape(Swig_last_file())); - push_imported(); - } - - /* See if the filename has a directory component */ - dirname = Swig_file_dirname(Swig_last_file()); - if (sysfile || !Len(dirname)) { - Delete(dirname); - dirname = 0; - } - if (dirname) { - int len = Len(dirname); - Delslice(dirname, len - 1, len); /* Kill trailing directory delimiter */ - Swig_push_directory(dirname); - } - s2 = Preprocessor_parse(s1); - addline(ns, s2, allow); - Append(ns, "%endoffile"); - if (dirname) { - Swig_pop_directory(); - } - if (import_all) { - pop_imported(); - } - Delete(s2); - Delete(dirname); - Delete(s1); - } - Delete(fn); - } - } else if (Equal(id, kpp_pragma)) { - if (Strncmp(value, "SWIG ", 5) == 0) { - char *c = Char(value) + 5; - while (*c && (isspace((int) *c))) - c++; - if (*c) { - if (strncmp(c, "nowarn=", 7) == 0) { - String *val = NewString(c + 7); - String *nowarn = Preprocessor_replace(val); - Swig_warnfilter(nowarn, 1); - Delete(nowarn); - Delete(val); - } else if (strncmp(c, "cpperraswarn=", 13) == 0) { - error_as_warning = atoi(c + 13); - } else { - Swig_error(Getfile(s), Getline(id), "Unknown SWIG pragma: %s\n", c); - } - } - } - } else if (Equal(id, kpp_level)) { - Swig_error(Getfile(s), Getline(id), "cpp debug: level = %d, startlevel = %d\n", level, start_level); - } else if (Equal(id, "")) { - /* Null directive */ - } else if (is_digits(id)) { - /* A gcc linemarker of the form '# linenum filename flags' (resulting from running gcc -E) */ - } else { - /* Ignore unknown preprocessor directives which are inside an inactive - * conditional (github issue #394). */ - if (allow) - Swig_error(Getfile(s), Getline(id), "Unknown SWIG preprocessor directive: %s (if this is a block of target language code, delimit it with %%{ and %%})\n", id); - } - for (i = 0; i < cpp_lines; i++) - Putc('\n', ns); - state = 0; - break; - - /* SWIG directives */ - case 100: - /* %{,%} block */ - if (c == '{') { - start_line = Getline(s); - copy_location(s, chunk); - add_chunk(ns, chunk, allow); - Putc('%', chunk); - Putc(c, chunk); - state = 105; - } - /* %#cpp - an embedded C preprocessor directive (we strip off the %) */ - else if (c == '#') { - add_chunk(ns, chunk, allow); - Putc(c, chunk); - state = 107; - } else if (isidentifier(c)) { - Clear(decl); - Putc('%', decl); - Putc(c, decl); - state = 110; - } else { - Putc('%', chunk); - Putc(c, chunk); - state = 1; - } - break; - - case 105: - Putc(c, chunk); - if (c == '%') - state = 106; - break; - - case 106: - Putc(c, chunk); - if (c == '}') { - state = 1; - addline(ns, chunk, allow); - Clear(chunk); - copy_location(s, chunk); - } else { - state = 105; - } - break; - - case 107: - Putc(c, chunk); - if (c == '\n') { - addline(ns, chunk, allow); - Clear(chunk); - state = 0; - } else if (c == '\\') { - state = 108; - } - break; - - case 108: - Putc(c, chunk); - state = 107; - break; - - case 110: - if (!isidchar(c)) { - Ungetc(c, s); - /* Look for common SWIG directives */ - if (Equal(decl, kpp_dinclude) || Equal(decl, kpp_dimport) || Equal(decl, kpp_dextern)) { - /* Got some kind of file inclusion directive, eg: %import(option1="value1") "filename" */ - if (allow) { - DOH *s1, *s2, *fn, *opt; - String *options_whitespace = NewStringEmpty(); - String *filename_whitespace = NewStringEmpty(); - int sysfile = 0; - - if (Equal(decl, kpp_dextern)) { - Swig_warning(WARN_DEPRECATED_EXTERN, Getfile(s), Getline(s), "%%extern is deprecated. Use %%import instead.\n"); - Clear(decl); - Append(decl, "%%import"); - } - skip_whitespace(s, options_whitespace); - opt = get_options(s); - - skip_whitespace(s, filename_whitespace); - fn = get_filename(s, &sysfile); - s1 = cpp_include(fn, sysfile); - if (s1) { - String *dirname; - copy_location(s, chunk); - add_chunk(ns, chunk, allow); - Printf(ns, "%sfile%s%s%s\"%s\" %%beginfile\n", decl, options_whitespace, opt, filename_whitespace, Swig_filename_escape(Swig_last_file())); - if (Equal(decl, kpp_dimport)) { - push_imported(); - } - dirname = Swig_file_dirname(Swig_last_file()); - if (sysfile || !Len(dirname)) { - Delete(dirname); - dirname = 0; - } - if (dirname) { - int len = Len(dirname); - Delslice(dirname, len - 1, len); /* Kill trailing directory delimiter */ - Swig_push_directory(dirname); - } - s2 = Preprocessor_parse(s1); - if (dirname) { - Swig_pop_directory(); - } - if (Equal(decl, kpp_dimport)) { - pop_imported(); - } - addline(ns, s2, allow); - Append(ns, "%endoffile"); - Delete(s2); - Delete(dirname); - Delete(s1); - } - Delete(fn); - Delete(filename_whitespace); - Delete(options_whitespace); - } - state = 1; - } else if (Equal(decl, kpp_dbeginfile)) { - /* Got an internal directive marking the beginning of an included file: %beginfile ... %endoffile */ - filelevel++; - start_line = Getline(s); - copy_location(s, chunk); - add_chunk(ns, chunk, allow); - Append(chunk, decl); - state = 120; - } else if (Equal(decl, kpp_dline)) { - /* Got a line directive */ - state = 1; - } else if (Equal(decl, kpp_ddefine)) { - /* Got a define directive */ - dlevel++; - copy_location(s, chunk); - add_chunk(ns, chunk, allow); - Clear(value); - copy_location(s, value); - state = 150; - } else { - Append(chunk, decl); - state = 1; - } - } else { - Putc(c, decl); - } - break; - - /* Searching for the end of a %beginfile block */ - case 120: - Putc(c, chunk); - if (c == '%') { - const char *bf = "beginfile"; - const char *ef = "endoffile"; - char statement[10]; - int i = 0; - for (i = 0; i < 9;) { - c = Getc(s); - Putc(c, chunk); - statement[i++] = (char)c; - if (strncmp(statement, bf, i) && strncmp(statement, ef, i)) - break; - } - c = Getc(s); - Ungetc(c, s); - if ((i == 9) && (isspace(c))) { - if (strncmp(statement, bf, i) == 0) { - ++filelevel; - } else if (strncmp(statement, ef, i) == 0) { - --filelevel; - if (!filelevel) { - /* Reached end of included file */ - addline(ns, chunk, allow); - Clear(chunk); - copy_location(s, chunk); - state = 1; - } - } - } - } - break; - - /* Searching for the end of a %define statement */ - case 150: - Putc(c, value); - if (c == '%') { - const char *ed = "enddef"; - const char *df = "define"; - char statement[7]; - int i = 0; - for (i = 0; i < 6;) { - c = Getc(s); - Putc(c, value); - statement[i++] = (char)c; - if (strncmp(statement, ed, i) && strncmp(statement, df, i)) - break; - } - c = Getc(s); - Ungetc(c, s); - if ((i == 6) && (isspace(c))) { - if (strncmp(statement, df, i) == 0) { - ++dlevel; - } else { - if (strncmp(statement, ed, i) == 0) { - --dlevel; - if (!dlevel) { - /* Got the macro */ - for (i = 0; i < 7; i++) { - Delitem(value, DOH_END); - } - if (allow) { - Seek(value, 0, SEEK_SET); - Preprocessor_define(value, 1); - } - addline(ns, value, 0); - state = 0; - } - } - } - } - } - break; - default: - Printf(stderr, "cpp: Invalid parser state %d\n", state); - Exit(EXIT_FAILURE); - } - } - while (level > 0) { - Swig_error(Getfile(s), cond_lines[level - 1], "Missing #endif for conditional starting here\n"); - level--; - } - if (state == 120) { - Swig_error(Getfile(s), start_line, "Missing %%endoffile for file inclusion block starting here\n"); - } - if (state == 150) { - Seek(value, 0, SEEK_SET); - Swig_error(Getfile(s), Getline(value), "Missing %%enddef for macro starting here\n", Getline(value)); - } - if ((state >= 105) && (state < 107)) { - Swig_error(Getfile(s), start_line, "Unterminated %%{ ... %%} block\n"); - } - if ((state >= 30) && (state < 40)) { - Swig_error(Getfile(s), start_line, "Unterminated comment\n"); - } - - copy_location(s, chunk); - add_chunk(ns, chunk, allow); - - /* DelScope(scp); */ - Delete(decl); - Delete(id); - Delete(value); - Delete(comment); - Delete(chunk); - - return ns; -} diff --git a/contrib/tools/swig/Source/Preprocessor/expr.c b/contrib/tools/swig/Source/Preprocessor/expr.c deleted file mode 100644 index 95e05cf5624..00000000000 --- a/contrib/tools/swig/Source/Preprocessor/expr.c +++ /dev/null @@ -1,496 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * expr.c - * - * Integer arithmetic expression evaluator used to handle expressions - * encountered during preprocessing. - * - * Note that this is used for expressions in `#if` and the like, but not - * for expressions in `#define` which SWIG wraps as constants - for those - * we inject a `%constant` directive which is handled by the parser in - * `Source/CParse/parser.y`. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "preprocessor.h" - -static Scanner *scan = 0; - -typedef struct { - /* One of the EXPR_xxx values defined below. */ - int op; - /* op == EXPR_OP: value is the token specifying which operator. - * - * op == EXPR_VALUE && svalue == NULL: Numeric expression value. - * - * Otherwise unused. - */ - long value; - /* op == EXPR_VALUE: If non-NULL, string expression value; if NULL see value. - * - * Otherwise unused. - */ - String *svalue; -} exprval; - -#define EXPR_TOP 1 -#define EXPR_VALUE 2 -#define EXPR_OP 3 -#define EXPR_GROUP 4 - -/* Special token values used here to distinguish from SWIG_TOKEN_MINUS - * and SWIG_TOKEN_PLUS (which we use here for a two argument versions). - */ -#define OP_UMINUS 100 -#define OP_UPLUS 101 - -static exprval stack[256]; /* Parsing stack */ -static int sp = 0; /* Stack pointer */ -static int prec[256]; /* Precedence rules */ -static int expr_init = 0; /* Initialization flag */ -static const char *errmsg = 0; /* Parsing error */ - -/* Initialize the precedence table for various operators. Low values have higher precedence */ -static void init_precedence(void) { - prec[SWIG_TOKEN_NOT] = 10; - prec[SWIG_TOKEN_LNOT] = 10; - prec[OP_UMINUS] = 10; - prec[OP_UPLUS] = 10; - prec[SWIG_TOKEN_STAR] = 20; - prec[SWIG_TOKEN_SLASH] = 20; - prec[SWIG_TOKEN_PERCENT] = 20; - prec[SWIG_TOKEN_PLUS] = 30; - prec[SWIG_TOKEN_MINUS] = 30; - prec[SWIG_TOKEN_LSHIFT] = 40; - prec[SWIG_TOKEN_RSHIFT] = 40; - prec[SWIG_TOKEN_LESSTHAN] = 50; - prec[SWIG_TOKEN_GREATERTHAN] = 50; - prec[SWIG_TOKEN_LTEQUAL] = 50; - prec[SWIG_TOKEN_GTEQUAL] = 50; - prec[SWIG_TOKEN_EQUALTO] = 60; - prec[SWIG_TOKEN_NOTEQUAL] = 60; - prec[SWIG_TOKEN_AND] = 70; - prec[SWIG_TOKEN_XOR] = 80; - prec[SWIG_TOKEN_OR] = 90; - prec[SWIG_TOKEN_LAND] = 100; - prec[SWIG_TOKEN_LOR] = 110; - expr_init = 1; -} - -#define UNARY_OP(token) (((token) == SWIG_TOKEN_NOT) || \ - ((token) == SWIG_TOKEN_LNOT) || \ - ((token) == OP_UMINUS) || \ - ((token) == OP_UPLUS)) - -/* Reduce a single operator on the stack */ -/* return 0 on failure, 1 on success */ -static int reduce_op(void) { - long op_token = stack[sp - 1].value; - assert(sp > 0); - assert(stack[sp - 1].op == EXPR_OP); - /* do some basic checking first: */ - if (stack[sp].op != EXPR_VALUE) { - errmsg = "Right-hand side is not value"; - return 0; - } - if (UNARY_OP(op_token)) { - if (stack[sp].svalue) { - errmsg = "Syntax error: attempt to apply unary operator to string"; - return 0; - } - } else { - /* binary operator: */ - if (sp == 1) { - /* top of stack: don't attempt to use sp-2! */ - errmsg = "Missing left-hand side for binary operator"; - return 0; - } - if (stack[sp].op != EXPR_VALUE) { - errmsg = "Left-hand side of binary operator is not a value"; - return 0; - } - if ((!stack[sp - 2].svalue) != (!stack[sp].svalue)) { - errmsg = "Can't mix strings and integers in expression"; - return 0; - } - } - if (stack[sp].svalue) { - /* A binary string expression */ - switch (stack[sp - 1].value) { - case SWIG_TOKEN_EQUALTO: - stack[sp - 2].value = (Strcmp(stack[sp - 2].svalue, stack[sp].svalue) == 0); - Delete(stack[sp - 2].svalue); - Delete(stack[sp].svalue); - sp -= 2; - break; - case SWIG_TOKEN_NOTEQUAL: - stack[sp - 2].value = (Strcmp(stack[sp - 2].svalue, stack[sp].svalue) != 0); - Delete(stack[sp - 2].svalue); - Delete(stack[sp].svalue); - sp -= 2; - break; - default: - errmsg = "Syntax error: bad binary operator for strings"; - return 0; - break; - } - } else { - switch (op_token) { - case SWIG_TOKEN_STAR: - stack[sp - 2].value = stack[sp - 2].value * stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_EQUALTO: - stack[sp - 2].value = stack[sp - 2].value == stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_NOTEQUAL: - stack[sp - 2].value = stack[sp - 2].value != stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_PLUS: - stack[sp - 2].value = stack[sp - 2].value + stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_MINUS: - stack[sp - 2].value = stack[sp - 2].value - stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_AND: - stack[sp - 2].value = stack[sp - 2].value & stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_LAND: - stack[sp - 2].value = stack[sp - 2].value && stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_OR: - stack[sp - 2].value = stack[sp - 2].value | stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_LOR: - stack[sp - 2].value = stack[sp - 2].value || stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_XOR: - stack[sp - 2].value = stack[sp - 2].value ^ stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_LESSTHAN: - stack[sp - 2].value = stack[sp - 2].value < stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_GREATERTHAN: - stack[sp - 2].value = stack[sp - 2].value > stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_LTEQUAL: - stack[sp - 2].value = stack[sp - 2].value <= stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_GTEQUAL: - stack[sp - 2].value = stack[sp - 2].value >= stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_NOT: - stack[sp - 1].value = ~stack[sp].value; - sp--; - break; - case SWIG_TOKEN_LNOT: - stack[sp - 1].value = !stack[sp].value; - sp--; - break; - case OP_UMINUS: - stack[sp - 1].value = -stack[sp].value; - sp--; - break; - case OP_UPLUS: - stack[sp - 1].value = stack[sp].value; - sp--; - break; - case SWIG_TOKEN_SLASH: - if (stack[sp].value != 0) { - stack[sp - 2].value = stack[sp - 2].value / stack[sp].value; - sp -= 2; - } else { - errmsg = "Division by zero in expression"; - return 0; - } - break; - case SWIG_TOKEN_PERCENT: - if (stack[sp].value != 0) { - stack[sp - 2].value = stack[sp - 2].value % stack[sp].value; - sp -= 2; - } else { - errmsg = "Modulo by zero in expression"; - return 0; - } - break; - case SWIG_TOKEN_LSHIFT: - stack[sp - 2].value = stack[sp - 2].value << stack[sp].value; - sp -= 2; - break; - case SWIG_TOKEN_RSHIFT: - stack[sp - 2].value = stack[sp - 2].value >> stack[sp].value; - sp -= 2; - break; - default: - errmsg = "Syntax error: bad operator"; - return 0; - break; - } - } - stack[sp].op = EXPR_VALUE; - stack[sp].svalue = 0; /* ensure it's not a string! */ - return 1; -} - -/* ----------------------------------------------------------------------------- - * Preprocessor_expr_init() - * - * Initialize the expression evaluator - * ----------------------------------------------------------------------------- */ - -void Preprocessor_expr_init(void) { - if (!expr_init) - init_precedence(); - if (!scan) - scan = NewScanner(); -} - -void Preprocessor_expr_delete(void) { - DelScanner(scan); -} - - -/* ----------------------------------------------------------------------------- - * Tokenizer - * ----------------------------------------------------------------------------- */ - -static int expr_token(Scanner * s) { - int t; - while (1) { - t = Scanner_token(s); - if (!((t == SWIG_TOKEN_BACKSLASH) || (t == SWIG_TOKEN_ENDLINE) || (t == SWIG_TOKEN_COMMENT))) - break; - } - return t; -} - -/* ----------------------------------------------------------------------------- - * Preprocessor_expr() - * - * Evaluates an arithmetic expression. Returns the result and sets an error code. - * ----------------------------------------------------------------------------- */ - -int Preprocessor_expr(DOH *s, int *error) { - int token = 0; - int op = 0; - - sp = 0; - assert(s); - assert(scan); - - Seek(s, 0, SEEK_SET); - /* Printf(stdout,"evaluating : '%s'\n", s); */ - *error = 0; - Scanner_clear(scan); - Scanner_push(scan, s); - - /* Put initial state onto the stack */ - stack[sp].op = EXPR_TOP; - - while (1) { - /* Look at the top of the stack */ - switch (stack[sp].op) { - case EXPR_TOP: - /* EXPR_TOP is a place-holder which can only appear on the top of the - * stack. We can reduce it to any expression - a number, a string, an - * unary operator, or another expression enclosed in parentheses. - */ - token = expr_token(scan); - if (!token) { - errmsg = "Expected an expression"; - *error = 1; - return 0; - } - if ((token == SWIG_TOKEN_INT) || (token == SWIG_TOKEN_UINT) || (token == SWIG_TOKEN_LONG) || (token == SWIG_TOKEN_ULONG)) { - /* A number. Reduce EXPR_TOP to an EXPR_VALUE */ - char *c = Char(Scanner_text(scan)); - if (c[0] == '0' && (c[1] == 'b' || c[1] == 'B')) { - /* strtol() doesn't handle binary constants */ - stack[sp].value = (long) strtol(c + 2, 0, 2); - } else { - stack[sp].value = (long) strtol(c, 0, 0); - } - stack[sp].svalue = 0; - stack[sp].op = EXPR_VALUE; - } else if ((token == SWIG_TOKEN_MINUS) || (token == SWIG_TOKEN_PLUS) || (token == SWIG_TOKEN_LNOT) || (token == SWIG_TOKEN_NOT)) { - if (token == SWIG_TOKEN_MINUS) - token = OP_UMINUS; - else if (token == SWIG_TOKEN_PLUS) - token = OP_UPLUS; - stack[sp].value = token; - stack[sp].op = EXPR_OP; - sp++; - stack[sp].op = EXPR_TOP; - } else if (token == SWIG_TOKEN_LPAREN) { - stack[sp].op = EXPR_GROUP; - sp++; - stack[sp].op = EXPR_TOP; - } else if (token == SWIG_TOKEN_ENDLINE) { - } else if (token == SWIG_TOKEN_STRING) { - stack[sp].svalue = NewString(Scanner_text(scan)); - stack[sp].op = EXPR_VALUE; - } else if (token == SWIG_TOKEN_ID) { - /* Defined macros have been expanded already so this is an unknown - * macro, which gets treated as zero. - */ - stack[sp].value = 0; - stack[sp].svalue = 0; - stack[sp].op = EXPR_VALUE; - } else if ((token == SWIG_TOKEN_FLOAT) || (token == SWIG_TOKEN_DOUBLE)) { - errmsg = "Floating point constant in preprocessor expression"; - *error = 1; - return 0; - } else - goto syntax_error; - break; - case EXPR_VALUE: - /* A value is on top of the stack. We may reduce or evaluate depending - * on what the next token is. - */ - token = expr_token(scan); - if (!token) { - /* End of input. Might have to reduce if an operator is on stack */ - while (sp > 0) { - if (stack[sp - 1].op == EXPR_OP) { - if (!reduce_op()) - goto reduce_error; - } else if (stack[sp - 1].op == EXPR_GROUP) { - errmsg = "Missing \')\'"; - *error = 1; - return 0; - } else - goto syntax_error; - } - return stack[sp].value; - } - /* Token must be an operator */ - switch (token) { - case SWIG_TOKEN_STAR: - case SWIG_TOKEN_EQUALTO: - case SWIG_TOKEN_NOTEQUAL: - case SWIG_TOKEN_PLUS: - case SWIG_TOKEN_MINUS: - case SWIG_TOKEN_AND: - case SWIG_TOKEN_LAND: - case SWIG_TOKEN_OR: - case SWIG_TOKEN_LOR: - case SWIG_TOKEN_XOR: - case SWIG_TOKEN_LESSTHAN: - case SWIG_TOKEN_GREATERTHAN: - case SWIG_TOKEN_LTEQUAL: - case SWIG_TOKEN_GTEQUAL: - case SWIG_TOKEN_SLASH: - case SWIG_TOKEN_PERCENT: - case SWIG_TOKEN_LSHIFT: - case SWIG_TOKEN_RSHIFT: - if ((sp == 0) || (stack[sp - 1].op == EXPR_GROUP)) { - /* No possibility of reduce. Push operator and expression */ - sp++; - stack[sp].op = EXPR_OP; - stack[sp].value = token; - sp++; - stack[sp].op = EXPR_TOP; - } else { - if (stack[sp - 1].op != EXPR_OP) - goto syntax_error_expected_operator; - op = stack[sp - 1].value; /* Previous operator */ - - /* Now, depending on the precedence relationship between the last operator and the current - we will reduce or push */ - - if (prec[op] <= prec[token]) { - /* Reduce the previous operator */ - if (!reduce_op()) - goto reduce_error; - } - sp++; - stack[sp].op = EXPR_OP; - stack[sp].value = token; - sp++; - stack[sp].op = EXPR_TOP; - } - break; - case SWIG_TOKEN_RPAREN: - if (sp == 0) - goto extra_rparen; - - /* Might have to reduce operators first */ - while ((sp > 0) && (stack[sp - 1].op == EXPR_OP)) { - if (!reduce_op()) - goto reduce_error; - } - if ((sp == 0) || (stack[sp - 1].op != EXPR_GROUP)) - goto extra_rparen; - stack[sp - 1].op = EXPR_VALUE; - stack[sp - 1].value = stack[sp].value; - stack[sp - 1].svalue = stack[sp].svalue; - sp--; - break; - case SWIG_TOKEN_LTEQUALGT: - goto spaceship_not_allowed; - default: - goto syntax_error_expected_operator; - break; - } - break; - - default: - fprintf(stderr, "Internal error in expression evaluator.\n"); - Exit(EXIT_FAILURE); - } - } - -syntax_error: - errmsg = "Syntax error"; - *error = 1; - return 0; - -syntax_error_expected_operator: - errmsg = "Syntax error: expected operator"; - *error = 1; - return 0; - -reduce_error: - /* errmsg has been set by reduce_op */ - *error = 1; - return 0; - -extra_rparen: - errmsg = "Extra \')\'"; - *error = 1; - return 0; - -spaceship_not_allowed: - errmsg = "Spaceship operator (<=>) not allowed in preprocessor expression"; - *error = 1; - return 0; -} - -/* ----------------------------------------------------------------------------- - * Preprocessor_expr_error() - * - * Return error message set by the evaluator (if any) - * ----------------------------------------------------------------------------- */ - -const char *Preprocessor_expr_error(void) { - return errmsg; -} diff --git a/contrib/tools/swig/Source/Preprocessor/preprocessor.h b/contrib/tools/swig/Source/Preprocessor/preprocessor.h deleted file mode 100644 index c1a30da7937..00000000000 --- a/contrib/tools/swig/Source/Preprocessor/preprocessor.h +++ /dev/null @@ -1,40 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * preprocessor.h - * - * SWIG preprocessor module. - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_PREPROCESSOR_H -#define SWIG_PREPROCESSOR_H - -#include "swigwarn.h" - -#ifdef __cplusplus -extern "C" { -#endif - extern int Preprocessor_expr(String *s, int *error); - extern const char *Preprocessor_expr_error(void); - extern Hash *Preprocessor_define(const_String_or_char_ptr str, int swigmacro); - extern void Preprocessor_undef(const_String_or_char_ptr name); - extern void Preprocessor_init(void); - extern void Preprocessor_delete(void); - extern String *Preprocessor_parse(String *s); - extern void Preprocessor_include_all(int); - extern void Preprocessor_import_all(int); - extern void Preprocessor_ignore_missing(int); - extern void Preprocessor_error_as_warning(int); - extern List *Preprocessor_depend(void); - extern void Preprocessor_expr_init(void); - extern void Preprocessor_expr_delete(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/contrib/tools/swig/Source/README b/contrib/tools/swig/Source/README deleted file mode 100644 index 08893330889..00000000000 --- a/contrib/tools/swig/Source/README +++ /dev/null @@ -1,15 +0,0 @@ -SWIG Source directory - - Source/DOH - A core set of basic datatypes including - strings, lists, hashes, and files. Used - extensively by the rest of SWIG. - - Source/Swig - Swig core. Type-system, utility functions. - - Source/Preprocessor - SWIG C Preprocessor - - Source/CParse - SWIG C Parser (still messy) - - Source/Modules - Language modules. - - Source/Include - Include files. diff --git a/contrib/tools/swig/Source/Swig/cwrap.c b/contrib/tools/swig/Source/Swig/cwrap.c deleted file mode 100644 index b7d01bc1175..00000000000 --- a/contrib/tools/swig/Source/Swig/cwrap.c +++ /dev/null @@ -1,1661 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * cwrap.c - * - * This file defines a variety of wrapping rules for C/C++ handling including - * the naming of local variables, calling conventions, and so forth. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "cparse.h" - -extern int UseWrapperSuffix; - -static const char *cresult_variable_name = "result"; - -static Parm *nonvoid_parms(Parm *p) { - if (p) { - SwigType *t = Getattr(p, "type"); - if (SwigType_type(t) == T_VOID) - return 0; - } - return p; -} - -/* ----------------------------------------------------------------------------- - * Swig_cresult_name_set() - * - * Change the name of the variable used to hold the return value from C/C++ wrapper functions - * from the default "result". - * ----------------------------------------------------------------------------- */ - -void Swig_cresult_name_set(const char *new_name) { - cresult_variable_name = new_name; -} - -/* ----------------------------------------------------------------------------- - * Swig_cresult_name() - * - * Get the name of the variable used to hold the return value from C/C++ wrapper functions - * ----------------------------------------------------------------------------- */ - -const char *Swig_cresult_name(void) { - return cresult_variable_name; -} - -/* ----------------------------------------------------------------------------- - * Swig_cparm_name() - * - * Generates a name for the ith argument in an argument list - * ----------------------------------------------------------------------------- */ - -String *Swig_cparm_name(Parm *p, int i) { - String *name = NewStringf("arg%d", i + 1); - if (p) { - Setattr(p, "lname", name); - } - - return name; -} - -/* ----------------------------------------------------------------------------- - * Swig_clocal() - * - * Creates a string that declares a C local variable type. Converts references - * and user defined types to pointers. - * ----------------------------------------------------------------------------- */ - -static String *Swig_clocal(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr value) { - String *decl; - - decl = NewStringEmpty(); - - switch (SwigType_type(t)) { - case T_REFERENCE: - if (value) { - String *lstrname = SwigType_lstr(t, name); - String *lstr = SwigType_lstr(t, 0); - Printf(decl, "%s = (%s) &%s_defvalue", lstrname, lstr, name); - Delete(lstrname); - Delete(lstr); - } else { - String *lstrname = SwigType_lstr(t, name); - Printf(decl, "%s = 0", lstrname); - Delete(lstrname); - } - break; - case T_RVALUE_REFERENCE: - if (value) { - String *lstrname = SwigType_lstr(t, name); - String *lstr = SwigType_lstr(t, 0); - Printf(decl, "%s = (%s) &%s_defrvalue", lstrname, lstr, name); - Delete(lstrname); - Delete(lstr); - } else { - String *lstrname = SwigType_lstr(t, name); - Printf(decl, "%s = 0", lstrname); - Delete(lstrname); - } - break; - case T_VOID: - break; - case T_VARARGS: - Printf(decl, "void *%s = 0", name); - break; - - default: - if (value) { - String *lcaststr = SwigType_lcaststr(t, value); - String *lstr = SwigType_lstr(t, 0); - String *lstrn = SwigType_lstr(t, name); - Printf(decl, "%s = (%s) %s", lstrn, lstr, lcaststr); - Delete(lcaststr); - Delete(lstr); - Delete(lstrn); - } else { - String *lstrname = SwigType_lstr(t, name); - Append(decl, lstrname); - Delete(lstrname); - } - } - return decl; -} - -/* ----------------------------------------------------------------------------- - * Swig_wrapped_var_convert() - * - * Converts a member variable for use in the get and set wrapper methods. - * This function only converts user defined types to pointers. - * ----------------------------------------------------------------------------- */ - -String *Swig_wrapped_var_type(SwigType *t, int varcref) { - SwigType *ty; - - if (!Strstr(t, "enum $unnamed")) { - ty = Copy(t); - } else { - /* Change the type for unnamed enum instance variables */ - ty = NewString("int"); - } - - if (SwigType_isclass(t)) { - if (varcref) { - if (cparse_cplusplus) { - if (!SwigType_isconst(ty)) - SwigType_add_qualifier(ty, "const"); - SwigType_add_reference(ty); - } else { - return Copy(ty); - } - } else { - SwigType_add_pointer(ty); - } - } - return ty; -} - -String *Swig_wrapped_member_var_type(SwigType *t, int varcref) { - SwigType *ty; - - if (!Strstr(t, "enum $unnamed")) { - ty = Copy(t); - } else { - /* Change the type for unnamed enum instance variables */ - ty = NewString("int"); - } - if (SwigType_isclass(t)) { - if (varcref) { - if (cparse_cplusplus) { - if (!SwigType_isconst(ty)) - SwigType_add_qualifier(ty, "const"); - SwigType_add_reference(ty); - } else { - return Copy(ty); - } - } else { - SwigType_add_pointer(ty); - } - } - return ty; -} - - -static String *Swig_wrapped_var_deref(SwigType *t, const_String_or_char_ptr name, int varcref) { - if (SwigType_isclass(t)) { - if (varcref) { - if (cparse_cplusplus) { - return NewStringf("*%s", name); - } else { - return NewStringf("%s", name); - } - } else { - return NewStringf("*%s", name); - } - } else { - return SwigType_rcaststr(t, name); - } -} - -static String *Swig_wrapped_var_assign(SwigType *t, const_String_or_char_ptr name, int varcref) { - if (SwigType_isclass(t)) { - if (varcref) { - return NewStringf("%s", name); - } else { - return NewStringf("&%s", name); - } - } else { - return SwigType_lcaststr(t, name); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_cargs() - * - * Emit all of the local variables for a list of parameters. Returns the - * number of parameters. - * Default values for the local variables are only emitted if the compact default - * argument behaviour is required. - * ----------------------------------------------------------------------------- */ -int Swig_cargs(Wrapper *w, ParmList *p) { - int i = 0; - int compactdefargs = ParmList_is_compactdefargs(p); - - while (p != 0) { - String *lname = Swig_cparm_name(p, i); - SwigType *pt = Getattr(p, "type"); - if ((SwigType_type(pt) != T_VOID)) { - String *local = 0; - String *type = Getattr(p, "type"); - /* default values only emitted if in compact default args mode */ - String *pvalue = (compactdefargs) ? Getattr(p, "value") : 0; - - /* When using compactdefaultargs, the code generated initialises a variable via a constructor call that accepts the - * default value as a parameter. The default constructor is not called and therefore SwigValueWrapper is not needed. */ - SwigType *altty = pvalue ? 0 : SwigType_alttype(type, 0); - - int tycode = SwigType_type(type); - if (tycode == T_REFERENCE) { - if (pvalue) { - SwigType *tvalue; - String *defname, *defvalue, *rvalue, *qvalue; - rvalue = SwigType_typedef_resolve_all(pvalue); - qvalue = SwigType_typedef_qualified(rvalue); - defname = NewStringf("%s_defvalue", lname); - tvalue = Copy(type); - SwigType_del_reference(tvalue); - tycode = SwigType_type(tvalue); - if (tycode != T_USER) { - /* plain primitive type, we copy the def value */ - String *lstr = SwigType_lstr(tvalue, defname); - defvalue = NewStringf("%s = %s", lstr, qvalue); - Delete(lstr); - } else { - /* user type, we copy the reference value */ - String *str = SwigType_str(type, defname); - defvalue = NewStringf("%s = %s", str, qvalue); - Delete(str); - } - Wrapper_add_localv(w, defname, defvalue, NIL); - Delete(tvalue); - Delete(rvalue); - Delete(qvalue); - Delete(defname); - Delete(defvalue); - } - } else if (tycode == T_RVALUE_REFERENCE) { - if (pvalue) { - SwigType *tvalue; - String *defname, *defvalue, *rvalue, *qvalue; - rvalue = SwigType_typedef_resolve_all(pvalue); - qvalue = SwigType_typedef_qualified(rvalue); - defname = NewStringf("%s_defrvalue", lname); - tvalue = Copy(type); - SwigType_del_rvalue_reference(tvalue); - tycode = SwigType_type(tvalue); - if (tycode != T_USER) { - /* plain primitive type, we copy the def value */ - String *lstr = SwigType_lstr(tvalue, defname); - defvalue = NewStringf("%s = %s", lstr, qvalue); - Delete(lstr); - } else { - /* user type, we copy the reference value */ - String *str = SwigType_str(type, defname); - defvalue = NewStringf("%s = %s", str, qvalue); - Delete(str); - } - Wrapper_add_localv(w, defname, defvalue, NIL); - Delete(tvalue); - Delete(rvalue); - Delete(qvalue); - Delete(defname); - Delete(defvalue); - } - } else if (!pvalue && ((tycode == T_POINTER) || (tycode == T_STRING) || (tycode == T_WSTRING))) { - pvalue = (String *) "0"; - } - if (!altty) { - local = Swig_clocal(pt, lname, pvalue); - } else { - local = Swig_clocal(altty, lname, pvalue); - Delete(altty); - } - Wrapper_add_localv(w, lname, local, NIL); - Delete(local); - i++; - } - Delete(lname); - p = nextSibling(p); - } - return (i); -} - -/* ----------------------------------------------------------------------------- - * Swig_cresult() - * - * This function generates the C code needed to set the result of a C - * function call. - * ----------------------------------------------------------------------------- */ - -String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr decl) { - String *fcall; - - fcall = NewStringEmpty(); - switch (SwigType_type(t)) { - case T_VOID: - break; - case T_REFERENCE: - { - String *lstr = SwigType_lstr(t, 0); - Printf(fcall, "%s = (%s) &", name, lstr); - Delete(lstr); - } - break; - case T_RVALUE_REFERENCE: - { - String *const_lvalue_str; - String *lstr = SwigType_lstr(t, 0); - SwigType *tt = Copy(t); - SwigType_del_rvalue_reference(tt); - SwigType_add_qualifier(tt, "const"); - SwigType_add_reference(tt); - const_lvalue_str = SwigType_rcaststr(tt, 0); - - Printf(fcall, "%s = (%s) &%s", name, lstr, const_lvalue_str); - - Delete(const_lvalue_str); - Delete(tt); - Delete(lstr); - } - break; - case T_USER: - Printf(fcall, "%s = ", name); - break; - - default: - /* Normal return value */ - { - String *lstr = SwigType_lstr(t, 0); - Printf(fcall, "%s = (%s)", name, lstr); - Delete(lstr); - } - break; - } - - /* Now print out function call */ - Append(fcall, decl); - - /* A sick hack */ - { - char *c = Char(decl) + Len(decl) - 1; - if (!((*c == ';') || (*c == '}'))) - Append(fcall, ";"); - } - - return fcall; -} - -/* ----------------------------------------------------------------------------- - * Swig_cfunction_call() - * - * Creates a string that calls a C function using the local variable rules - * defined above. - * - * name(arg0, arg1, arg2, ... argn) - * - * ----------------------------------------------------------------------------- */ - -String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms) { - String *func; - int i = 0; - int comma = 0; - Parm *p = parms; - String *nname; - - func = NewStringEmpty(); - nname = SwigType_namestr(name); - - /* - SWIGTEMPLATEDISAMBIGUATOR is compiler dependent (swiglabels.swg), - - SUN Studio 9 requires 'template', - - gcc-3.4 forbids the use of 'template'. - the rest seems not caring very much, - */ - if (SwigType_istemplate(name)) { - String *prefix = Swig_scopename_prefix(nname); - if (!prefix || Len(prefix) == 0) { - Printf(func, "%s(", nname); - } else { - String *last = Swig_scopename_last(nname); - Printf(func, "%s::SWIGTEMPLATEDISAMBIGUATOR %s(", prefix, last); - Delete(last); - } - Delete(prefix); - } else { - Printf(func, "%s(", nname); - } - Delete(nname); - - while (p) { - SwigType *pt = Getattr(p, "type"); - if ((SwigType_type(pt) != T_VOID)) { - SwigType *rpt = SwigType_typedef_resolve_all(pt); - String *pname = Swig_cparm_name(p, i); - String *rcaststr = SwigType_rcaststr(rpt, pname); - - if (comma) { - Append(func, ","); - } - - if (cparse_cplusplus && SwigType_type(rpt) == T_USER) - Printv(func, "SWIG_STD_MOVE(", rcaststr, ")", NIL); - else - Printv(func, rcaststr, NIL); - - Delete(rpt); - Delete(pname); - Delete(rcaststr); - comma = 1; - i++; - } - p = nextSibling(p); - } - Append(func, ")"); - return func; -} - -/* ----------------------------------------------------------------------------- - * Swig_cmethod_call() - * - * Generates a string that calls a C++ method from a list of parameters. - * - * arg0->name(arg1, arg2, arg3, ..., argn) - * - * self is an argument that defines how to handle the first argument. Normally, - * it should be set to "this->". With C++ proxy classes enabled, it could be - * set to "(*this)->" or some similar sequence. - * ----------------------------------------------------------------------------- */ - -static String *Swig_cmethod_call(const_String_or_char_ptr name, ParmList *parms, const_String_or_char_ptr self, String *explicit_qualifier, SwigType *director_type) { - String *func, *nname; - int i = 0; - Parm *p = parms; - SwigType *pt; - int comma = 0; - - func = NewStringEmpty(); - if (!p) - return func; - - if (!self) - self = "(this)->"; - Append(func, self); - - if (SwigType_istemplate(name) && (strncmp(Char(name), "operator ", 9) == 0)) { - /* fix for template + operators and compilers like gcc 3.3.5 */ - String *tprefix = SwigType_templateprefix(name); - nname = tprefix; - } else { - nname = SwigType_namestr(name); - } - - if (director_type) { - const char *pname = "darg"; - String *rcaststr = SwigType_rcaststr(director_type, pname); - Replaceall(func, "this", rcaststr); - Delete(rcaststr); - } else { - pt = Getattr(p, "type"); - - /* If the method is invoked through a dereferenced pointer, we don't add any casts - (needed for smart pointers). Otherwise, we cast to the appropriate type */ - - if (Strstr(func, "*this")) { - String *pname = Swig_cparm_name(p, 0); - Replaceall(func, "this", pname); - Delete(pname); - } else { - String *pname = Swig_cparm_name(p, 0); - String *rcaststr = SwigType_rcaststr(pt, pname); - Replaceall(func, "this", rcaststr); - Delete(rcaststr); - Delete(pname); - } - - /* - SWIGTEMPLATEDESIMBUAGATOR is compiler dependent (swiglabels.swg), - - SUN Studio 9 requires 'template', - - gcc-3.4 forbids the use of 'template' (correctly implementing the ISO C++ standard) - the others don't seem to care, - */ - if (SwigType_istemplate(name)) - Printf(func, "SWIGTEMPLATEDISAMBIGUATOR "); - - if (explicit_qualifier) { - Printv(func, explicit_qualifier, "::", NIL); - } - } - - Printf(func, "%s(", nname); - - i++; - p = nextSibling(p); - while (p) { - pt = Getattr(p, "type"); - if ((SwigType_type(pt) != T_VOID)) { - String *pname = Swig_cparm_name(p, i); - String *rcaststr = SwigType_rcaststr(pt, pname); - if (comma) - Append(func, ","); - Append(func, rcaststr); - Delete(rcaststr); - Delete(pname); - comma = 1; - i++; - } - p = nextSibling(p); - } - Append(func, ")"); - Delete(nname); - return func; -} - -/* ----------------------------------------------------------------------------- - * Swig_cconstructor_call() - * - * Creates a string that calls a C constructor function. - * - * calloc(1,sizeof(name)); - * ----------------------------------------------------------------------------- */ - -String *Swig_cconstructor_call(const_String_or_char_ptr name) { - DOH *func; - - func = NewStringEmpty(); - Printf(func, "calloc(1, sizeof(%s))", name); - return func; -} - - -/* ----------------------------------------------------------------------------- - * Swig_cppconstructor_call() - * - * Creates a string that calls a C function using the local variable rules - * defined above. - * - * name(arg0, arg1, arg2, ... argn) - * - * ----------------------------------------------------------------------------- */ - -String *Swig_cppconstructor_base_call(const_String_or_char_ptr name, ParmList *parms, int skip_self) { - String *func; - String *nname; - int i = 0; - int comma = 0; - Parm *p = parms; - SwigType *pt; - if (skip_self) { - if (p) - p = nextSibling(p); - i++; - } - nname = SwigType_namestr(name); - func = NewStringEmpty(); - Printf(func, "new %s(", nname); - while (p) { - pt = Getattr(p, "type"); - if ((SwigType_type(pt) != T_VOID)) { - String *rcaststr = 0; - String *pname = 0; - if (comma) - Append(func, ","); - if (!Getattr(p, "arg:byname")) { - pname = Swig_cparm_name(p, i); - i++; - } else { - pname = Getattr(p, "value"); - if (pname) - pname = Copy(pname); - else - pname = Copy(Getattr(p, "name")); - } - rcaststr = SwigType_rcaststr(pt, pname); - Append(func, rcaststr); - Delete(rcaststr); - comma = 1; - Delete(pname); - } - p = nextSibling(p); - } - Append(func, ")"); - Delete(nname); - return func; -} - -String *Swig_cppconstructor_call(const_String_or_char_ptr name, ParmList *parms) { - return Swig_cppconstructor_base_call(name, parms, 0); -} - -String *Swig_cppconstructor_nodirector_call(const_String_or_char_ptr name, ParmList *parms) { - return Swig_cppconstructor_base_call(name, parms, 1); -} - -String *Swig_cppconstructor_director_call(const_String_or_char_ptr name, ParmList *parms) { - return Swig_cppconstructor_base_call(name, parms, 0); -} - -/* ----------------------------------------------------------------------------- - * recursive_flag_search() - * - * This function searches for the class attribute 'attr' in the class - * 'n' or recursively in its bases. - * - * If you define SWIG_FAST_REC_SEARCH, the method will set the found - * 'attr' in the target class 'n'. If not, the method will set the - * 'noattr' one. This prevents of having to navigate the entire - * hierarchy tree every time, so, it is an O(1) method... or something - * like that. However, it populates all the parsed classes with the - * 'attr' and/or 'noattr' attributes. - * - * If you undefine the SWIG_FAST_REC_SEARCH no attribute will be set - * while searching. This could be slower for large projects with very - * large hierarchy trees... or maybe not. But it will be cleaner. - * - * Maybe later a swig option can be added to switch at runtime. - * - * ----------------------------------------------------------------------------- */ - -/* #define SWIG_FAST_REC_SEARCH 1 */ -static String *recursive_flag_search(Node *n, const String *attr, const String *noattr) { - String *f = 0; - n = Swig_methodclass(n); - if (GetFlag(n, noattr)) { - return 0; - } - f = GetFlagAttr(n, attr); - if (f) { - return f; - } else { - List *bl = Getattr(n, "bases"); - if (bl) { - Iterator bi; - for (bi = First(bl); bi.item; bi = Next(bi)) { - f = recursive_flag_search(bi.item, attr, noattr); - if (f) { -#ifdef SWIG_FAST_REC_SEARCH - SetFlagAttr(n, attr, f); -#endif - return f; - } - } - } - } -#ifdef SWIG_FAST_REC_SEARCH - SetFlag(n, noattr); -#endif - return 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_unref_call() - * - * Find the "feature:unref" call, if any. - * ----------------------------------------------------------------------------- */ - -String *Swig_unref_call(Node *n) { - String *unref = recursive_flag_search(n, "feature:unref", "feature:nounref"); - if (unref) { - String *pname = Swig_cparm_name(0, 0); - unref = NewString(unref); - Replaceall(unref, "$this", pname); - Replaceall(unref, "$self", pname); - Delete(pname); - } - return unref; -} - -/* ----------------------------------------------------------------------------- - * Swig_ref_call() - * - * Find the "feature:ref" call, if any. - * ----------------------------------------------------------------------------- */ - -String *Swig_ref_call(Node *n, const String *lname) { - String *ref = recursive_flag_search(n, "feature:ref", "feature:noref"); - if (ref) { - ref = NewString(ref); - Replaceall(ref, "$this", lname); - Replaceall(ref, "$self", lname); - } - return ref; -} - -/* ----------------------------------------------------------------------------- - * Swig_cdestructor_call() - * - * Creates a string that calls a C destructor function. - * - * free((char *) arg0); - * ----------------------------------------------------------------------------- */ - -String *Swig_cdestructor_call(Node *n) { - Node *cn = Swig_methodclass(n); - String *unref = Swig_unref_call(cn); - - if (unref) { - return unref; - } else { - String *pname = Swig_cparm_name(0, 0); - String *call = NewStringf("free((char *) %s);", pname); - Delete(pname); - return call; - } -} - - -/* ----------------------------------------------------------------------------- - * Swig_cppdestructor_call() - * - * Creates a string that calls a C destructor function. - * - * delete arg1; - * ----------------------------------------------------------------------------- */ - -String *Swig_cppdestructor_call(Node *n) { - Node *cn = Swig_methodclass(n); - String *unref = Swig_unref_call(cn); - if (unref) { - return unref; - } else { - String *pname = Swig_cparm_name(0, 0); - String *call = NewStringf("delete %s;", pname); - Delete(pname); - return call; - } -} - -/* ----------------------------------------------------------------------------- - * Swig_cmemberset_call() - * - * Generates a string that sets the name of a member in a C++ class or C struct. - * - * arg0->name = arg1 - * - * ----------------------------------------------------------------------------- */ - -String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, String *self, int varcref) { - String *func; - String *pname0 = Swig_cparm_name(0, 0); - String *pname1 = Swig_cparm_name(0, 1); - func = NewStringEmpty(); - if (!self) - self = NewString("(this)->"); - else - self = NewString(self); - Replaceall(self, "this", pname0); - if (SwigType_type(type) != T_ARRAY) { - if (!Strstr(type, "enum $unnamed")) { - String *dref = Swig_wrapped_var_deref(type, pname1, varcref); - int extra_cast = 0; - if (cparse_cplusplusout) { - /* Required for C nested structs compiled as C++ as a duplicate of the nested struct is put into the global namespace. - * We could improve this by adding the extra casts just for nested structs rather than all structs. */ - String *base = SwigType_base(type); - extra_cast = SwigType_isclass(base); - Delete(base); - } - if (extra_cast) { - String *lstr; - SwigType *ptype = Copy(type); - SwigType_add_pointer(ptype); - lstr = SwigType_lstr(ptype, 0); - Printf(func, "if (%s) *(%s)&%s%s = %s", pname0, lstr, self, name, dref); - Delete(lstr); - Delete(ptype); - } else { - Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref); - } - Delete(dref); - } else { - Printf(func, "if (%s && sizeof(int) == sizeof(%s%s)) *(int*)(void*)&(%s%s) = %s", pname0, self, name, self, name, pname1); - } - } - Delete(self); - Delete(pname0); - Delete(pname1); - return (func); -} - - -/* ----------------------------------------------------------------------------- - * Swig_cmemberget_call() - * - * Generates a string that sets the name of a member in a C++ class or C struct. - * - * arg0->name - * - * ----------------------------------------------------------------------------- */ - -String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String *self, int varcref) { - String *func; - String *call; - String *pname0 = Swig_cparm_name(0, 0); - if (!self) - self = NewString("(this)->"); - else - self = NewString(self); - Replaceall(self, "this", pname0); - func = NewStringEmpty(); - call = Swig_wrapped_var_assign(t, "", varcref); - Printf(func, "%s (%s%s)", call, self, name); - Delete(self); - Delete(call); - Delete(pname0); - return func; -} - -/* ----------------------------------------------------------------------------- - * Swig_replace_special_variables() - * - * Replaces special variables with a value from the supplied node - * ----------------------------------------------------------------------------- */ -void Swig_replace_special_variables(Node *n, Node *parentnode, String *code) { - Node *parentclass = parentnode; - String *overloaded = Getattr(n, "sym:overloaded"); - Replaceall(code, "$name", Getattr(n, "name")); - Replaceall(code, "$symname", Getattr(n, "sym:name")); - Replaceall(code, "$wrapname", Getattr(n, "wrap:name")); - Replaceall(code, "$overname", overloaded ? Char(Getattr(n, "sym:overname")) : ""); - - if (Strstr(code, "$decl")) { - String *decl = Swig_name_decl(n); - Replaceall(code, "$decl", decl); - Delete(decl); - } - if (Strstr(code, "$fulldecl")) { - String *fulldecl = Swig_name_fulldecl(n); - Replaceall(code, "$fulldecl", fulldecl); - Delete(fulldecl); - } - - if (parentclass && !Equal(nodeType(parentclass), "class")) - parentclass = 0; - if (Strstr(code, "$parentclasssymname")) { - String *parentclasssymname = 0; - if (parentclass) - parentclasssymname = Getattr(parentclass, "sym:name"); - Replaceall(code, "$parentclasssymname", parentclasssymname ? parentclasssymname : ""); - } - if (Strstr(code, "$parentclassname")) { - String *parentclassname = 0; - if (parentclass) - parentclassname = Getattr(parentclass, "name"); - Replaceall(code, "$parentclassname", parentclassname ? SwigType_str(parentclassname, "") : ""); - } -} - -/* ----------------------------------------------------------------------------- - * extension_code() - * - * Generates an extension function (a function defined in %extend) - * - * return_type function_name(parms) code - * - * ----------------------------------------------------------------------------- */ -static String *extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) { - String *parms_str = cplusplus ? ParmList_str_defaultargs(parms) : ParmList_str(parms); - String *sig = NewStringf("%s(%s)", function_name, (cplusplus || Len(parms_str)) ? parms_str : "void"); - String *rt_sig = SwigType_str(return_type, sig); - String *body = NewStringf("SWIGINTERN %s", rt_sig); - Printv(body, code, "\n", NIL); - if (Strstr(body, "$")) { - Swig_replace_special_variables(n, parentNode(parentNode(n)), body); - if (self) - Replaceall(body, "$self", self); - } - Delete(parms_str); - Delete(sig); - Delete(rt_sig); - return body; -} - -/* ----------------------------------------------------------------------------- - * Swig_add_extension_code() - * - * Generates an extension function (a function defined in %extend) and - * adds it to the "wrap:code" attribute of a node - * - * See also extension_code() - * - * ----------------------------------------------------------------------------- */ -int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) { - String *body = extension_code(n, function_name, parms, return_type, code, cplusplus, self); - Setattr(n, "wrap:code", body); - Delete(body); - return SWIG_OK; -} - - -/* ----------------------------------------------------------------------------- - * Swig_MethodToFunction(Node *n) - * - * Converts a C++ method node to a function accessor function. - * ----------------------------------------------------------------------------- */ - -int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int flags, SwigType *director_type, int is_director) { - String *name; - ParmList *parms; - SwigType *type; - Parm *p; - String *self = 0; - int is_smart_pointer_overload = 0; - String *qualifier = Getattr(n, "qualifier"); - String *directorScope = NewString(nspace); - - Replace(directorScope, NSPACE_SEPARATOR, "_", DOH_REPLACE_ANY); - - /* If smart pointer without const overload or mutable method, change self dereferencing */ - if (flags & CWRAP_SMART_POINTER) { - if (flags & CWRAP_SMART_POINTER_OVERLOAD) { - if (qualifier && strncmp(Char(qualifier), "q(const)", 8) == 0) { - self = NewString("(*(this))->"); - is_smart_pointer_overload = 1; - } - else if (Swig_storage_isstatic(n)) { - String *cname = Getattr(n, "extendsmartclassname") ? Getattr(n, "extendsmartclassname") : classname; - String *ctname = SwigType_namestr(cname); - self = NewStringf("(*(%s const *)this)->", ctname); - is_smart_pointer_overload = 1; - Delete(ctname); - } - else { - self = NewString("(*this)->"); - } - } else { - self = NewString("(*this)->"); - } - } - - /* If node is a member template expansion, we don't allow added code */ - if (Getattr(n, "templatetype")) - flags &= ~(CWRAP_EXTEND); - - name = Getattr(n, "name"); - parms = CopyParmList(nonvoid_parms(Getattr(n, "parms"))); - - type = NewString(classname); - if (qualifier) { - SwigType_push(type, qualifier); - } - SwigType_add_pointer(type); - p = NewParm(type, "self", n); - Setattr(p, "self", "1"); - Setattr(p, "hidden","1"); - /* - Disable the 'this' ownership in 'self' to manage inplace - operations like: - - A& A::operator+=(int i) { ...; return *this;} - - Here the 'self' parameter ownership needs to be disabled since - there could be two objects sharing the same 'this' pointer: the - input and the result one. And worse, the pointer could be deleted - in one of the objects (input), leaving the other (output) with - just a seg. fault to happen. - - To avoid the previous problem, use - - %feature("self:disown") *::operator+=; - %feature("new") *::operator+=; - - These two lines just transfer the ownership of the 'this' pointer - from the input to the output wrapping object. - - This happens in python, but may also happen in other target - languages. - */ - if (GetFlag(n, "feature:self:disown")) { - Setattr(p, "wrap:disown", "1"); - } - set_nextSibling(p, parms); - Delete(type); - - /* Generate action code for the access */ - if (!(flags & CWRAP_EXTEND)) { - String *explicit_qualifier = 0; - String *call = 0; - String *cres = 0; - String *explicitcall_name = 0; - int pure_virtual = !(Cmp(Getattr(n, "storage"), "virtual")) && !(Cmp(Getattr(n, "value"), "0")); - - /* Call the explicit method rather than allow for a polymorphic call */ - if ((flags & CWRAP_DIRECTOR_TWO_CALLS) || (flags & CWRAP_DIRECTOR_ONE_CALL)) { - String *access = Getattr(n, "access"); - if (access && (Cmp(access, "protected") == 0)) { - /* If protected access (can only be if a director method) then call the extra public accessor method (language module must provide this) */ - String *explicit_qualifier_tmp = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname")); - explicitcall_name = NewStringf("%sSwigPublic", name); - if (Len(directorScope) > 0) - explicit_qualifier = NewStringf("SwigDirector_%s_%s", directorScope, explicit_qualifier_tmp); - else - explicit_qualifier = NewStringf("SwigDirector_%s", explicit_qualifier_tmp); - Delete(explicit_qualifier_tmp); - } else { - explicit_qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname")); - } - } - - if (!self && SwigType_isrvalue_reference(Getattr(n, "refqualifier"))) { - String *memory_header = NewString("<memory>"); - Setfile(memory_header, Getfile(n)); - Setline(memory_header, Getline(n)); - Swig_fragment_emit(memory_header); - self = NewString("std::move(*this)."); - Delete(memory_header); - } - - call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type); - cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call); - - if (pure_virtual && is_director && (flags & CWRAP_DIRECTOR_TWO_CALLS)) { - String *qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname")); - Delete(cres); - cres = NewStringf("Swig::DirectorPureVirtualException::raise(\"%s::%s\");", qualifier, name); - Delete(qualifier); - } - - if (flags & CWRAP_DIRECTOR_TWO_CALLS) { - /* Create two method calls, one to call the explicit method, the other a normal polymorphic function call */ - String *cres_both_calls = NewStringf(""); - String *call_extra = Swig_cmethod_call(name, p, self, 0, director_type); - String *cres_extra = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call_extra); - Printv(cres_both_calls, "if (upcall) {\n", cres, "\n", "} else {", cres_extra, "\n}", NIL); - Setattr(n, "wrap:action", cres_both_calls); - Delete(cres_extra); - Delete(call_extra); - Delete(cres_both_calls); - } else { - Setattr(n, "wrap:action", cres); - } - - Delete(explicitcall_name); - Delete(call); - Delete(cres); - Delete(explicit_qualifier); - } else { - /* Methods with default arguments are wrapped with additional methods for each default argument, - * however, only one extra %extend method is generated. */ - - String *defaultargs = Getattr(n, "defaultargs"); - String *code = Getattr(n, "code"); - String *cname = Getattr(n, "extendsmartclassname") ? Getattr(n, "extendsmartclassname") : classname; - String *membername = Swig_name_member(nspace, cname, name); - String *mangled = Swig_name_mangle(membername); - int is_smart_pointer = flags & CWRAP_SMART_POINTER; - - type = Getattr(n, "type"); - - /* Check if the method is overloaded. If so, and it has code attached, we append an extra suffix - to avoid a name-clash in the generated wrappers. This allows overloaded methods to be defined - in C. - - But when not using the suffix used for overloaded functions, we still need to ensure that the - wrapper name doesn't conflict with any wrapper functions for some languages, so optionally make - it sufficiently unique by appending a suffix similar to the one used for overloaded functions to it. - */ - if (code) { - if (Getattr(n, "sym:overloaded")) { - Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname")); - } else if (UseWrapperSuffix) { - Append(mangled, "__SWIG"); - } - } - - /* See if there is any code that we need to emit */ - if (!defaultargs && code && !is_smart_pointer) { - Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, "self"); - } - if (is_smart_pointer) { - int i = 0; - Parm *pp = p; - String *func = NewStringf("%s(", mangled); - String *cres; - - if (!Swig_storage_isstatic(n)) { - String *pname = Swig_cparm_name(pp, i); - String *ctname = SwigType_namestr(cname); - String *fadd = 0; - if (is_smart_pointer_overload) { - String *nclassname = SwigType_namestr(classname); - fadd = NewStringf("(%s const *)((%s const *)%s)->operator ->()", ctname, nclassname, pname); - Delete(nclassname); - } - else { - fadd = NewStringf("(%s*)(%s)->operator ->()", ctname, pname); - } - Append(func, fadd); - Delete(ctname); - Delete(fadd); - Delete(pname); - pp = nextSibling(pp); - if (pp) - Append(func, ","); - } else { - pp = nextSibling(pp); - } - ++i; - while (pp) { - SwigType *pt = Getattr(pp, "type"); - if ((SwigType_type(pt) != T_VOID)) { - String *pname = Swig_cparm_name(pp, i++); - String *rcaststr = SwigType_rcaststr(pt, pname); - Append(func, rcaststr); - Delete(rcaststr); - Delete(pname); - pp = nextSibling(pp); - if (pp) - Append(func, ","); - } - } - Append(func, ")"); - cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), func); - Setattr(n, "wrap:action", cres); - Delete(cres); - } else { - String *call = Swig_cfunction_call(mangled, p); - String *cres = Swig_cresult(Getattr(n, "type"), Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); - Delete(call); - Delete(cres); - } - - Delete(membername); - Delete(mangled); - } - Setattr(n, "parms", p); - Delete(p); - Delete(self); - Delete(parms); - Delete(directorScope); - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Swig_methodclass() - * - * This function returns the class node for a given method or class. - * ----------------------------------------------------------------------------- */ - -Node *Swig_methodclass(Node *n) { - Node *nodetype = nodeType(n); - if (Cmp(nodetype, "class") == 0) - return n; - return GetFlag(n, "feature:extend") ? parentNode(parentNode(n)) : parentNode(n); -} - -int Swig_directorclass(Node *n) { - Node *classNode = Swig_methodclass(n); - assert(classNode != 0); - return (Getattr(classNode, "vtable") != 0); -} - -Node *Swig_directormap(Node *module, String *type) { - int is_void = !Cmp(type, "void"); - if (!is_void && module) { - /* ?? follow the inheritance hierarchy? */ - - String *base = SwigType_base(type); - - Node *directormap = Getattr(module, "wrap:directormap"); - if (directormap) - return Getattr(directormap, base); - } - return 0; -} - - -/* ----------------------------------------------------------------------------- - * Swig_ConstructorToFunction() - * - * This function creates a C wrapper for a C constructor function. - * ----------------------------------------------------------------------------- */ - -int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags, String *directorname) { - Parm *p; - ParmList *directorparms; - SwigType *type; - int use_director = Swig_directorclass(n); - ParmList *parms = CopyParmList(nonvoid_parms(Getattr(n, "parms"))); - /* Prepend the list of prefix_args (if any) */ - Parm *prefix_args = Getattr(n, "director:prefix_args"); - if (prefix_args != NIL) { - Parm *p2, *p3; - - directorparms = CopyParmList(prefix_args); - for (p = directorparms; nextSibling(p); p = nextSibling(p)); - for (p2 = parms; p2; p2 = nextSibling(p2)) { - p3 = CopyParm(p2); - set_nextSibling(p, p3); - Delete(p3); - p = p3; - } - } else - directorparms = parms; - - type = NewString(classname); - SwigType_add_pointer(type); - - if (flags & CWRAP_EXTEND) { - /* Constructors with default arguments are wrapped with additional constructor methods for each default argument, - * however, only one extra %extend method is generated. */ - String *call; - String *cres; - String *defaultargs = Getattr(n, "defaultargs"); - String *code = Getattr(n, "code"); - String *membername = Swig_name_construct(nspace, classname); - String *mangled = Swig_name_mangle(membername); - - /* Check if the constructor is overloaded. If so, and it has code attached, we append an extra suffix - to avoid a name-clash in the generated wrappers. This allows overloaded constructors to be defined - in C. */ - if (Getattr(n, "sym:overloaded") && code) { - Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname")); - } - - /* See if there is any code that we need to emit */ - if (!defaultargs && code) { - Swig_add_extension_code(n, mangled, parms, type, code, cparse_cplusplus, "self"); - } - - call = Swig_cfunction_call(mangled, parms); - cres = Swig_cresult(type, Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); - Delete(cres); - Delete(call); - Delete(membername); - Delete(mangled); - } else { - if (cplus) { - /* if a C++ director class exists, create it rather than the original class */ - if (use_director) { - Node *parent = Swig_methodclass(n); - int abstract = Getattr(parent, "abstracts") != 0; - String *action = NewStringEmpty(); - String *tmp_none_comparison = Copy(none_comparison); - String *director_call; - String *nodirector_call; - - Replaceall(tmp_none_comparison, "$arg", "arg1"); - - director_call = Swig_cppconstructor_director_call(directorname, directorparms); - nodirector_call = Swig_cppconstructor_nodirector_call(classname, parms); - - if (abstract) { - /* whether or not the abstract class has been subclassed in python, - * create a director instance (there's no way to create a normal - * instance). if any of the pure virtual methods haven't been - * implemented in the target language, calls to those methods will - * generate Swig::DirectorPureVirtualException exceptions. - */ - String *cres = Swig_cresult(type, Swig_cresult_name(), director_call); - Append(action, cres); - Delete(cres); - } else { - /* (scottm): The code for creating a new director is now a string - template that gets passed in via the director_ctor argument. - - $comparison : an 'if' comparison from none_comparison - $director_new: Call new for director class - $nondirector_new: Call new for non-director class - */ - String *cres; - Append(action, director_ctor); - Replaceall(action, "$comparison", tmp_none_comparison); - - cres = Swig_cresult(type, Swig_cresult_name(), director_call); - Replaceall(action, "$director_new", cres); - Delete(cres); - - cres = Swig_cresult(type, Swig_cresult_name(), nodirector_call); - Replaceall(action, "$nondirector_new", cres); - Delete(cres); - } - Setattr(n, "wrap:action", action); - Delete(tmp_none_comparison); - Delete(action); - } else { - String *call = Swig_cppconstructor_call(classname, parms); - String *cres = Swig_cresult(type, Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); - Delete(cres); - Delete(call); - } - } else { - String *call = Swig_cconstructor_call(classname); - String *cres = Swig_cresult(type, Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); - Delete(cres); - Delete(call); - } - } - Setattr(n, "type", type); - Setattr(n, "parms", parms); - Delete(type); - if (directorparms != parms) - Delete(directorparms); - Delete(parms); - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Swig_DestructorToFunction() - * - * This function creates a C wrapper for a destructor function. - * ----------------------------------------------------------------------------- */ - -int Swig_DestructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int cplus, int flags) { - SwigType *type; - Parm *p; - - type = NewString(classname); - SwigType_add_pointer(type); - p = NewParm(type, "self", n); - Setattr(p, "self", "1"); - Setattr(p, "hidden", "1"); - Setattr(p, "wrap:disown", "1"); - Delete(type); - type = NewString("void"); - - if (flags & CWRAP_EXTEND) { - String *cres; - String *call; - String *membername, *mangled, *code; - membername = Swig_name_destroy(nspace, classname); - mangled = Swig_name_mangle(membername); - code = Getattr(n, "code"); - if (code) { - Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, "self"); - } - call = Swig_cfunction_call(mangled, p); - cres = NewStringf("%s;", call); - Setattr(n, "wrap:action", cres); - Delete(membername); - Delete(mangled); - Delete(call); - Delete(cres); - } else { - if (cplus) { - String *call = Swig_cppdestructor_call(n); - String *cres = NewStringf("%s", call); - Setattr(n, "wrap:action", cres); - Delete(call); - Delete(cres); - } else { - String *call = Swig_cdestructor_call(n); - String *cres = NewStringf("%s", call); - Setattr(n, "wrap:action", cres); - Delete(call); - Delete(cres); - } - } - Setattr(n, "type", type); - Setattr(n, "parms", p); - Delete(type); - Delete(p); - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Swig_MembersetToFunction() - * - * This function creates a C wrapper for setting a structure member. - * ----------------------------------------------------------------------------- */ - -int Swig_MembersetToFunction(Node *n, String *classname, int flags) { - String *name; - ParmList *parms; - Parm *p; - SwigType *t; - SwigType *ty; - SwigType *type; - SwigType *void_type = NewString("void"); - String *self = 0; - - int varcref = flags & CWRAP_NATURAL_VAR; - - if (flags & CWRAP_SMART_POINTER) { - self = NewString("(*this)->"); - } - if (flags & CWRAP_ALL_PROTECTED_ACCESS) { - self = NewStringf("darg->"); - } - - name = Getattr(n, "name"); - type = Getattr(n, "type"); - - t = NewString(classname); - SwigType_add_pointer(t); - parms = NewParm(t, "self", n); - Setattr(parms, "self", "1"); - Setattr(parms, "hidden","1"); - Delete(t); - - ty = Swig_wrapped_member_var_type(type, varcref); - p = NewParm(ty, name, n); - Setattr(parms, "hidden", "1"); - set_nextSibling(parms, p); - - /* If the type is a pointer or reference. We mark it with a special wrap:disown attribute */ - if (SwigType_check_decl(type, "p.")) { - Setattr(p, "wrap:disown", "1"); - } - Delete(p); - - if (flags & CWRAP_EXTEND) { - String *call; - String *cres; - String *code = Getattr(n, "code"); - - String *sname = Swig_name_set(0, name); - String *membername = Swig_name_member(0, classname, sname); - String *mangled = Swig_name_mangle(membername); - - if (code) { - /* I don't think this ever gets run - WSF */ - Swig_add_extension_code(n, mangled, parms, void_type, code, cparse_cplusplus, "self"); - } - call = Swig_cfunction_call(mangled, parms); - cres = NewStringf("%s;", call); - Setattr(n, "wrap:action", cres); - - Delete(cres); - Delete(call); - Delete(mangled); - Delete(membername); - Delete(sname); - } else { - String *call = Swig_cmemberset_call(name, type, self, varcref); - String *cres = NewStringf("%s;", call); - Setattr(n, "wrap:action", cres); - Delete(call); - Delete(cres); - } - Setattr(n, "type", void_type); - Setattr(n, "parms", parms); - Delete(parms); - Delete(ty); - Delete(void_type); - Delete(self); - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Swig_MembergetToFunction() - * - * This function creates a C wrapper for getting a structure member. - * ----------------------------------------------------------------------------- */ - -int Swig_MembergetToFunction(Node *n, String *classname, int flags) { - String *name; - ParmList *parms; - SwigType *t; - SwigType *ty; - SwigType *type; - String *self = 0; - - int varcref = flags & CWRAP_NATURAL_VAR; - - if (flags & CWRAP_SMART_POINTER) { - if (Swig_storage_isstatic(n)) { - Node *sn = Getattr(n, "cplus:staticbase"); - String *base = Getattr(sn, "name"); - self = NewStringf("%s::", base); - } else if (flags & CWRAP_SMART_POINTER_OVERLOAD) { - String *nclassname = SwigType_namestr(classname); - self = NewStringf("(*(%s const *)this)->", nclassname); - Delete(nclassname); - } else { - self = NewString("(*this)->"); - } - } - if (flags & CWRAP_ALL_PROTECTED_ACCESS) { - self = NewStringf("darg->"); - } - - name = Getattr(n, "name"); - type = Getattr(n, "type"); - - t = NewString(classname); - SwigType_add_pointer(t); - parms = NewParm(t, "self", n); - Setattr(parms, "self", "1"); - Setattr(parms, "hidden","1"); - Delete(t); - - ty = Swig_wrapped_member_var_type(type, varcref); - if (flags & CWRAP_EXTEND) { - String *call; - String *cres; - String *code = Getattr(n, "code"); - - String *gname = Swig_name_get(0, name); - String *membername = Swig_name_member(0, classname, gname); - String *mangled = Swig_name_mangle(membername); - - if (code) { - /* I don't think this ever gets run - WSF */ - Swig_add_extension_code(n, mangled, parms, ty, code, cparse_cplusplus, "self"); - } - call = Swig_cfunction_call(mangled, parms); - cres = Swig_cresult(ty, Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); - - Delete(cres); - Delete(call); - Delete(mangled); - Delete(membername); - Delete(gname); - } else { - String *call = Swig_cmemberget_call(name, type, self, varcref); - String *cres = Swig_cresult(ty, Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); - Delete(call); - Delete(cres); - } - Setattr(n, "type", ty); - Setattr(n, "parms", parms); - Delete(parms); - Delete(ty); - - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Swig_VarsetToFunction() - * - * This function creates a C wrapper for setting a global variable or static member - * variable. - * ----------------------------------------------------------------------------- */ - -int Swig_VarsetToFunction(Node *n, int flags) { - String *name, *nname; - ParmList *parms; - SwigType *type, *ty; - - int varcref = flags & CWRAP_NATURAL_VAR; - - name = Getattr(n, "name"); - type = Getattr(n, "type"); - nname = SwigType_namestr(name); - ty = Swig_wrapped_var_type(type, varcref); - parms = NewParm(ty, name, n); - - if (flags & CWRAP_EXTEND) { - String *sname = Swig_name_set(0, name); - String *mangled = Swig_name_mangle(sname); - String *call = Swig_cfunction_call(mangled, parms); - String *cres = NewStringf("%s;", call); - Setattr(n, "wrap:action", cres); - Delete(cres); - Delete(call); - Delete(mangled); - Delete(sname); - } else { - if (!Strstr(type, "enum $unnamed")) { - String *pname = Swig_cparm_name(0, 0); - String *dref = Swig_wrapped_var_deref(type, pname, varcref); - String *call = NewStringf("%s = %s;", nname, dref); - Setattr(n, "wrap:action", call); - Delete(call); - Delete(dref); - Delete(pname); - } else { - String *pname = Swig_cparm_name(0, 0); - String *call = NewStringf("if (sizeof(int) == sizeof(%s)) *(int*)(void*)&(%s) = %s;", nname, nname, pname); - Setattr(n, "wrap:action", call); - Delete(pname); - Delete(call); - } - } - Setattr(n, "type", "void"); - Setattr(n, "parms", parms); - Delete(parms); - Delete(ty); - Delete(nname); - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Swig_VargetToFunction() - * - * This function creates a C wrapper for getting a global variable or static member - * variable. - * ----------------------------------------------------------------------------- */ - -int Swig_VargetToFunction(Node *n, int flags) { - String *cres, *call; - String *name; - SwigType *type; - SwigType *ty = 0; - - int varcref = flags & CWRAP_NATURAL_VAR; - - name = Getattr(n, "name"); - type = Getattr(n, "type"); - ty = Swig_wrapped_var_type(type, varcref); - - if (flags & CWRAP_EXTEND) { - String *sname = Swig_name_get(0, name); - String *mangled = Swig_name_mangle(sname); - call = Swig_cfunction_call(mangled, 0); - cres = Swig_cresult(ty, Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); - Delete(mangled); - Delete(sname); - } else { - String *nname = 0; - if (Equal(nodeType(n), "constant")) { - String *rawval = Getattr(n, "rawval"); - String *value = rawval ? rawval : Getattr(n, "value"); - nname = NewStringf("(%s)", value); - } else { - nname = SwigType_namestr(name); - } - call = Swig_wrapped_var_assign(type, nname, varcref); - cres = Swig_cresult(ty, Swig_cresult_name(), call); - Setattr(n, "wrap:action", cres); - Delete(nname); - } - - Setattr(n, "type", ty); - Delattr(n, "parms"); - Delete(cres); - Delete(call); - Delete(ty); - return SWIG_OK; -} diff --git a/contrib/tools/swig/Source/Swig/deprecate.c b/contrib/tools/swig/Source/Swig/deprecate.c deleted file mode 100644 index 5783455e599..00000000000 --- a/contrib/tools/swig/Source/Swig/deprecate.c +++ /dev/null @@ -1,107 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * deprecate.c - * - * The functions in this file are SWIG core functions that are deprecated - * or which do not fit in nicely with everything else. Generally this means - * that the function and/or API needs to be changed in some future release. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" - -/* --------------------------------------------------------------------- - * ParmList_is_compactdefargs() - * - * Returns 1 if the parameter list passed in is marked for compact argument - * handling (by the "compactdefargs" attribute). Otherwise returns 0. - * ---------------------------------------------------------------------- */ - -/* Discussion: - - "compactdefargs" is a property set by the Parser to indicate special - handling of default arguments. This property seems to be something that - is associated with functions and methods rather than low-level ParmList - objects. Therefore, I don't like the fact that this special purpose - feature is bolted onto the side of ParmList objects. - - Proposed solution: - - 1. "compactdefargs" should be a feature set on function/method nodes - instead of ParmList objects. For example, if you have a function, - you would check the function node to see if the parameters are - to be handled in this way. - - - Difficulties: - - 1. This is used by functions in cwrap.c and emit.cxx, none of which - are passed information about the function/method node. We might - have to change the API of those functions to make this work correctly. - For example: - - int emit_num_required(ParmList *parms) - - might become - - int emit_num_required(ParmList *parms, int compactargs) - -*/ - -int ParmList_is_compactdefargs(ParmList *p) { - int compactdefargs = 0; - - if (p) { - compactdefargs = Getattr(p, "compactdefargs") ? 1 : 0; - - /* The "compactdefargs" attribute should only be set on the first parameter in the list. - * However, sometimes an extra parameter is inserted at the beginning of the parameter list, - * so we check the 2nd parameter too. */ - if (!compactdefargs) { - Parm *nextparm = nextSibling(p); - compactdefargs = (nextparm && Getattr(nextparm, "compactdefargs")) ? 1 : 0; - } - } - - return compactdefargs; -} - -/* --------------------------------------------------------------------- - * ParmList_errorstr() - * - * Generate a prototype string suitable for use in error/warning messages. - * Similar to ParmList_protostr() but is also aware of hidden parameters. - * ---------------------------------------------------------------------- */ - -/* Discussion. This function is used to generate error messages, but take - into account that there might be a hidden parameter. Although this involves - parameter lists, it really isn't a core feature of swigparm.h or parms.c. - This is because the "hidden" attribute of parameters is added elsewhere (cwrap.c). - - For now, this function is placed here because it doesn't really seem to fit in - with the parms.c interface. - -*/ - -String *ParmList_errorstr(ParmList *p) { - String *out = NewStringEmpty(); - while (p) { - if (Getattr(p,"hidden")) { - p = nextSibling(p); - } else { - String *pstr = SwigType_str(Getattr(p, "type"), 0); - Append(out, pstr); - p = nextSibling(p); - if (p) { - Append(out, ","); - } - Delete(pstr); - } - } - return out; -} diff --git a/contrib/tools/swig/Source/Swig/error.c b/contrib/tools/swig/Source/Swig/error.c deleted file mode 100644 index efd644f9a8e..00000000000 --- a/contrib/tools/swig/Source/Swig/error.c +++ /dev/null @@ -1,351 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * error.c - * - * Error handling functions. These are used to issue warnings and - * error messages. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include <stdarg.h> -#include <ctype.h> - -/* ----------------------------------------------------------------------------- - * Commentary on the warning filter. - * - * The warning filter is a string of numbers prefaced by (-) or (+) to - * indicate whether or not a warning message is displayed. For example: - * - * "-304-201-140+210+201" - * - * The filter string is scanned left to right and the first occurrence - * of a warning number is used to determine printing behavior. - * - * The same number may appear more than once in the string. For example, in the - * above string, "201" appears twice. This simply means that warning 201 - * was disabled after it was previously enabled. This may only be temporary - * setting--the first number may be removed later in which case the warning - * is reenabled. - * ----------------------------------------------------------------------------- */ - -#if defined(_WIN32) -# define DEFAULT_ERROR_MSG_FORMAT EMF_MICROSOFT -#else -# define DEFAULT_ERROR_MSG_FORMAT EMF_STANDARD -#endif -static ErrorMessageFormat msg_format = DEFAULT_ERROR_MSG_FORMAT; -static int silence = 0; /* Silent operation */ -static String *filter = 0; /* Warning filter */ -static int warnall = 0; -static int nwarning = 0; -static int nerrors = 0; - -static int init_fmt = 0; -static char wrn_wnum_fmt[64]; -static char wrn_nnum_fmt[64]; -static char err_line_fmt[64]; -static char err_eof_fmt[64]; -static char diag_line_fmt[64]; -static char diag_eof_fmt[64]; - -static String *format_filename(const_String_or_char_ptr filename); - -/* ----------------------------------------------------------------------------- - * Swig_warning() - * - * Issue a warning message on stderr. - * ----------------------------------------------------------------------------- */ - -void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const char *fmt, ...) { - String *out; - char *msg; - int wrn = 1; - va_list ap; - if (silence) - return; - if (!init_fmt) - Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); - - va_start(ap, fmt); - - out = NewStringEmpty(); - vPrintf(out, fmt, ap); - - msg = Char(out); - if (isdigit((unsigned char) *msg)) { - unsigned long result = strtoul(msg, &msg, 10); - if (msg != Char(out)) { - msg++; - wnum = result; - } - } - - /* Check in the warning filter */ - if (filter) { - char temp[32]; - char *c; - char *f = Char(filter); - sprintf(temp, "%d", wnum); - while (*f != '\0' && (c = strstr(f, temp))) { - if (*(c - 1) == '-') { - wrn = 0; /* Warning disabled */ - break; - } - if (*(c - 1) == '+') { - wrn = 1; /* Warning enabled */ - break; - } - f += strlen(temp); - } - } - if (warnall || wrn) { - String *formatted_filename = format_filename(filename); - String *full_message = NewString(""); - if (wnum) { - Printf(full_message, wrn_wnum_fmt, formatted_filename, line, wnum); - } else { - Printf(full_message, wrn_nnum_fmt, formatted_filename, line); - } - Printf(full_message, "%s", msg); - Printv(stderr, full_message, NIL); - nwarning++; - Delete(full_message); - Delete(formatted_filename); - } - Delete(out); - va_end(ap); -} - -/* ----------------------------------------------------------------------------- - * Swig_error() - * - * Issue an error message on stderr. - * ----------------------------------------------------------------------------- */ - -void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...) { - va_list ap; - String *formatted_filename = NULL; - String *full_message = NULL; - - if (silence) - return; - if (!init_fmt) - Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); - - va_start(ap, fmt); - formatted_filename = format_filename(filename); - full_message = NewString(""); - if (line > 0) { - Printf(full_message, err_line_fmt, formatted_filename, line); - } else { - Printf(full_message, err_eof_fmt, formatted_filename); - } - vPrintf(full_message, fmt, ap); - Printv(stderr, full_message, NIL); - va_end(ap); - nerrors++; - Delete(full_message); - Delete(formatted_filename); -} - -/* ----------------------------------------------------------------------------- - * Swig_error_count() - * - * Returns number of errors received. - * ----------------------------------------------------------------------------- */ - -int Swig_error_count(void) { - return nerrors; -} - -/* ----------------------------------------------------------------------------- - * Swig_error_silent() - * - * Set silent flag - * ----------------------------------------------------------------------------- */ - -void Swig_error_silent(int s) { - silence = s; -} - - -/* ----------------------------------------------------------------------------- - * Swig_warnfilter() - * - * Takes a comma separate list of warning numbers and puts in the filter. - * ----------------------------------------------------------------------------- */ - -void Swig_warnfilter(const_String_or_char_ptr wlist, int add) { - char *c; - char *cw; - String *s; - if (!filter) - filter = NewStringEmpty(); - - s = NewString(""); - Clear(s); - cw = Char(wlist); - while (*cw != '\0') { - if (*cw != ' ') { - Putc(*cw, s); - } - ++cw; - } - c = Char(s); - c = strtok(c, ", "); - while (c) { - if (isdigit((int) *c) || (*c == '+') || (*c == '-')) { - /* Even if c is a digit, the rest of the string might not be, eg in the case of typemap - * warnings (a bit odd really), eg: %warnfilter(SWIGWARN_TYPEMAP_CHARLEAK_MSG) */ - if (add) { - Insert(filter, 0, c); - if (isdigit((int) *c)) { - Insert(filter, 0, "-"); - } - } else { - char *temp = (char *)Malloc(sizeof(char)*strlen(c) + 2); - if (isdigit((int) *c)) { - sprintf(temp, "-%s", c); - } else { - strcpy(temp, c); - } - Replace(filter, temp, "", DOH_REPLACE_FIRST); - Free(temp); - } - } - c = strtok(NULL, ", "); - } - Delete(s); -} - -void Swig_warnall(void) { - warnall = 1; -} - - -/* ----------------------------------------------------------------------------- - * Swig_warn_count() - * - * Return the number of warnings - * ----------------------------------------------------------------------------- */ - -int Swig_warn_count(void) { - return nwarning; -} - -/* ----------------------------------------------------------------------------- - * Swig_error_msg_format() - * - * Set the type of error/warning message display - * ----------------------------------------------------------------------------- */ - -void Swig_error_msg_format(ErrorMessageFormat format) { - const char *error = "Error"; - const char *warning = "Warning"; - - const char *fmt_eof = 0; - const char *fmt_line = 0; - - /* here 'format' could be directly a string instead of an enum, but - by now a switch is used to translated into one. */ - switch (format) { - case EMF_MICROSOFT: - fmt_line = "%s(%d) "; - fmt_eof = "%s(999999) "; /* Is there a special character for EOF? Just use a large number. */ - break; - case EMF_STANDARD: - default: - fmt_line = "%s:%d"; - fmt_eof = "%s:EOF"; - } - - sprintf(wrn_wnum_fmt, "%s: %s %%d: ", fmt_line, warning); - sprintf(wrn_nnum_fmt, "%s: %s: ", fmt_line, warning); - sprintf(err_line_fmt, "%s: %s: ", fmt_line, error); - sprintf(err_eof_fmt, "%s: %s: ", fmt_eof, error); - sprintf(diag_line_fmt, "%s: ", fmt_line); - sprintf(diag_eof_fmt, "%s: ", fmt_eof); - - msg_format = format; - init_fmt = 1; -} - -/* ----------------------------------------------------------------------------- - * format_filename() - * - * Remove double backslashes in Windows filename paths for display - * ----------------------------------------------------------------------------- */ -static String *format_filename(const_String_or_char_ptr filename) { - String *formatted_filename = NewString(filename); -#if defined(_WIN32) - Replaceall(formatted_filename, "\\\\", "\\"); -#endif - return formatted_filename; -} - -/* ----------------------------------------------------------------------------- - * Swig_stringify_with_location() - * - * Return a string representation of any DOH object with line and file location - * information in the appropriate error message format. The string representation - * is enclosed within [] brackets after the line and file information. - * ----------------------------------------------------------------------------- */ - -String *Swig_stringify_with_location(DOH *object) { - String *str = NewStringEmpty(); - - if (!init_fmt) - Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); - - if (object) { - int line = Getline(object); - String *formatted_filename = format_filename(Getfile(object)); - if (line > 0) { - Printf(str, diag_line_fmt, formatted_filename, line); - } else { - Printf(str, diag_eof_fmt, formatted_filename); - } - if (Len(object) == 0) { - Printf(str, "[EMPTY]"); - } else { - Printf(str, "[%s]", object); - } - Delete(formatted_filename); - } else { - Printf(str, "[NULL]"); - } - - return str; -} - -/* ----------------------------------------------------------------------------- - * Swig_diagnostic() - * - * Issue a diagnostic message on stdout. - * ----------------------------------------------------------------------------- */ - -void Swig_diagnostic(const_String_or_char_ptr filename, int line, const char *fmt, ...) { - va_list ap; - String *formatted_filename = NULL; - - if (!init_fmt) - Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); - - va_start(ap, fmt); - formatted_filename = format_filename(filename); - if (line > 0) { - Printf(stdout, diag_line_fmt, formatted_filename, line); - } else { - Printf(stdout, diag_eof_fmt, formatted_filename); - } - vPrintf(stdout, fmt, ap); - va_end(ap); - Delete(formatted_filename); -} - diff --git a/contrib/tools/swig/Source/Swig/extend.c b/contrib/tools/swig/Source/Swig/extend.c deleted file mode 100644 index 23660c0ad8a..00000000000 --- a/contrib/tools/swig/Source/Swig/extend.c +++ /dev/null @@ -1,141 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * extend.c - * - * Extensions support (%extend) - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "cparse.h" - -static Hash *extendhash = 0; /* Hash table of added methods */ - -/* ----------------------------------------------------------------------------- - * Swig_extend_hash() - * - * Access the extend hash - * ----------------------------------------------------------------------------- */ -Hash *Swig_extend_hash(void) { - if (!extendhash) - extendhash = NewHash(); - return extendhash; -} - -/* ----------------------------------------------------------------------------- - * Swig_extend_merge() - * - * Extension merge. This function is used to handle the %extend directive - * when it appears before a class definition. To handle this, the %extend - * actually needs to take precedence. Therefore, we will selectively nuke symbols - * from the current symbol table, replacing them with the added methods. - * ----------------------------------------------------------------------------- */ - -void Swig_extend_merge(Node *cls, Node *am) { - Node *n; - Node *csym; - - n = firstChild(am); - while (n) { - String *symname; - if (Strcmp(nodeType(n),"constructor") == 0) { - symname = Getattr(n,"sym:name"); - if (symname) { - if (Strcmp(symname,Getattr(n,"name")) == 0) { - /* If the name and the sym:name of a constructor are the same, - then it hasn't been renamed. However---the name of the class - itself might have been renamed so we need to do a consistency - check here */ - if (Getattr(cls,"sym:name")) { - Setattr(n,"sym:name", Getattr(cls,"sym:name")); - } - } - } - } - - symname = Getattr(n,"sym:name"); - DohIncref(symname); - if ((symname) && (!Getattr(n,"error"))) { - /* Remove node from its symbol table */ - Swig_symbol_remove(n); - csym = Swig_symbol_add(symname,n); - if (csym != n) { - /* Conflict with previous definition. Nuke previous definition */ - String *e = NewStringEmpty(); - String *en = NewStringEmpty(); - String *ec = NewStringEmpty(); - Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname); - Printf(en,"%%extend definition of '%s'.",symname); - SWIG_WARN_NODE_BEGIN(n); - Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec); - Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en); - SWIG_WARN_NODE_END(n); - Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec, - Getfile(n),Getline(n),en); - Setattr(csym,"error",e); - Delete(e); - Delete(en); - Delete(ec); - Swig_symbol_remove(csym); /* Remove class definition */ - Swig_symbol_add(symname,n); /* Insert extend definition */ - } - } - n = nextSibling(n); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_extend_append_previous() - * ----------------------------------------------------------------------------- */ - -void Swig_extend_append_previous(Node *cls, Node *am) { - Node *n, *ne; - Node *pe = 0; - Node *ae = 0; - - if (!am) return; - - n = firstChild(am); - while (n) { - ne = nextSibling(n); - set_nextSibling(n,0); - /* typemaps and fragments need to be prepended */ - if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) { - if (!pe) pe = Swig_cparse_new_node("extend"); - appendChild(pe, n); - } else { - if (!ae) ae = Swig_cparse_new_node("extend"); - appendChild(ae, n); - } - n = ne; - } - if (pe) prependChild(cls,pe); - if (ae) appendChild(cls,ae); -} - - -/* ----------------------------------------------------------------------------- - * Swig_extend_unused_check() - * - * Check for unused %extend. Special case, don't report unused - * extensions for templates - * ----------------------------------------------------------------------------- */ - -void Swig_extend_unused_check(void) { - Iterator ki; - - if (!extendhash) return; - for (ki = First(extendhash); ki.key; ki = Next(ki)) { - if (!Strchr(ki.key,'<')) { - SWIG_WARN_NODE_BEGIN(ki.item); - Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", SwigType_namestr(ki.key)); - SWIG_WARN_NODE_END(ki.item); - } - } -} - diff --git a/contrib/tools/swig/Source/Swig/fragment.c b/contrib/tools/swig/Source/Swig/fragment.c deleted file mode 100644 index 03b231fa13a..00000000000 --- a/contrib/tools/swig/Source/Swig/fragment.c +++ /dev/null @@ -1,188 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * fragment.c - * - * This file manages named code fragments. Code fragments are typically - * used to hold helper-code that may or may not be included in the wrapper - * file (depending on what features are actually used in the interface). - * - * By using fragments, it's possible to greatly reduce the amount of - * wrapper code and to generate cleaner wrapper files. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "swigwarn.h" -#include "cparse.h" - -static Hash *fragments = 0; -static Hash *looking_fragments = 0; -static int debug = 0; - - -/* ----------------------------------------------------------------------------- - * Swig_fragment_register() - * - * Add a fragment. Use the original Node*, so, if something needs to be - * changed, lang.cxx doesn't need to be touched again. - * ----------------------------------------------------------------------------- */ - -void Swig_fragment_register(Node *fragment) { - if (Getattr(fragment, "emitonly")) { - Swig_fragment_emit(fragment); - return; - } else { - String *name = Copy(Getattr(fragment, "value")); - String *type = Getattr(fragment, "type"); - if (type) { - SwigType *rtype = SwigType_typedef_resolve_all(type); - String *mangle = Swig_string_mangle(type); - Append(name, mangle); - Delete(mangle); - Delete(rtype); - if (debug) - Printf(stdout, "register fragment %s %s\n", name, type); - } - if (!fragments) { - fragments = NewHash(); - } - if (!Getattr(fragments, name)) { - String *section = Copy(Getattr(fragment, "section")); - String *ccode = Copy(Getattr(fragment, "code")); - Hash *kwargs = Getattr(fragment, "kwargs"); - Setmeta(ccode, "section", section); - if (kwargs) { - Setmeta(ccode, "kwargs", kwargs); - } - Setfile(ccode, Getfile(fragment)); - Setline(ccode, Getline(fragment)); - /* Replace $descriptor() macros */ - Swig_cparse_replace_descriptor(ccode); - Setattr(fragments, name, ccode); - if (debug) - Printf(stdout, "registering fragment %s %s\n", name, section); - Delete(section); - Delete(ccode); - } - Delete(name); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_fragment_emit() - * - * Emit a fragment - * ----------------------------------------------------------------------------- */ - -static -char *char_index(char *str, char c) { - while (*str && (c != *str)) - ++str; - return (c == *str) ? str : 0; -} - -void Swig_fragment_emit(Node *n) { - String *code; - char *pc, *tok; - String *t; - String *mangle = 0; - String *name = 0; - String *type = 0; - - name = Getattr(n, "value"); - if (!name) { - name = n; - } - - if (!fragments) { - Swig_warning(WARN_FRAGMENT_NOT_FOUND, Getfile(n), Getline(n), "Fragment '%s' not found.\n", name); - return; - } - - type = Getattr(n, "type"); - if (type) { - mangle = Swig_string_mangle(type); - } - - if (debug) - Printf(stdout, "looking fragment %s %s\n", name, type); - t = Copy(name); - tok = Char(t); - pc = char_index(tok, ','); - if (pc) - *pc = 0; - while (tok) { - String *name = NewString(tok); - if (mangle) - Append(name, mangle); - if (looking_fragments && Getattr(looking_fragments, name)) { - return; - } - code = Getattr(fragments, name); - if (debug) - Printf(stdout, "looking subfragment %s\n", name); - if (code && (Strcmp(code, "ignore") != 0)) { - String *section = Getmeta(code, "section"); - Hash *nn = Getmeta(code, "kwargs"); - if (!looking_fragments) - looking_fragments = NewHash(); - Setattr(looking_fragments, name, "1"); - while (nn) { - if (Equal(Getattr(nn, "name"), "fragment")) { - if (debug) - Printf(stdout, "emitting fragment %s %s\n", nn, type); - Setfile(nn, Getfile(n)); - Setline(nn, Getline(n)); - Swig_fragment_emit(nn); - } - nn = nextSibling(nn); - } - if (section) { - File *f = Swig_filebyname(section); - if (!f) { - Swig_error(Getfile(code), Getline(code), "Bad section '%s' in %%fragment declaration for code fragment '%s'\n", section, name); - } else { - if (debug) - Printf(stdout, "emitting subfragment %s %s\n", name, section); - if (debug) - Printf(f, "/* begin fragment %s */\n", name); - Printf(f, "%s\n", code); - if (debug) - Printf(f, "/* end fragment %s */\n\n", name); - Setattr(fragments, name, "ignore"); - Delattr(looking_fragments, name); - } - } - } else if (!code && type) { - SwigType *rtype = SwigType_typedef_resolve_all(type); - if (!Equal(type, rtype)) { - String *name = Copy(Getattr(n, "value")); - String *mangle = Swig_string_mangle(type); - Append(name, mangle); - Setfile(name, Getfile(n)); - Setline(name, Getline(n)); - Swig_fragment_emit(name); - Delete(mangle); - Delete(name); - } - Delete(rtype); - } - - if (!code) { - Swig_warning(WARN_FRAGMENT_NOT_FOUND, Getfile(n), Getline(n), "Fragment '%s' not found.\n", name); - } - tok = pc ? pc + 1 : 0; - if (tok) { - pc = char_index(tok, ','); - if (pc) - *pc = 0; - } - Delete(name); - } - Delete(t); -} diff --git a/contrib/tools/swig/Source/Swig/getopt.c b/contrib/tools/swig/Source/Swig/getopt.c deleted file mode 100644 index 7791d13f72d..00000000000 --- a/contrib/tools/swig/Source/Swig/getopt.c +++ /dev/null @@ -1,104 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * getopt.c - * - * Handles the parsing of command line options. This is particularly nasty - * compared to other utilities given that command line options can potentially - * be read by many different modules within SWIG. Thus, in order to make sure - * there are no unrecognized options, each module is required to "mark" - * the options that it uses. Afterwards, we can make a quick scan to make - * sure there are no unmarked options. - * - * TODO: - * Should have cleaner error handling in general. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" - -static char **args; -static int numargs; -static int *marked; - -/* ----------------------------------------------------------------------------- - * Swig_init_args() - * - * Initialize the argument list handler. - * ----------------------------------------------------------------------------- */ - -void Swig_init_args(int argc, char **argv) { - assert(argc > 0); - assert(argv); - - numargs = argc; - args = argv; - marked = (int *) Calloc(numargs, sizeof(int)); - marked[0] = 1; -} - -/* ----------------------------------------------------------------------------- - * Swig_mark_arg() - * - * Marks an argument as being parsed. - * ----------------------------------------------------------------------------- */ - -void Swig_mark_arg(int n) { - assert(marked); - assert((n >= 0) && (n < numargs)); - marked[n] = 1; -} - -/* ----------------------------------------------------------------------------- - * Swig_check_marked() - * - * Checks to see if argument has been picked up. - * ----------------------------------------------------------------------------- */ - -int Swig_check_marked(int n) { - assert((n >= 0) && (n < numargs)); - return marked[n]; -} - -/* ----------------------------------------------------------------------------- - * Swig_check_options() - * - * Checkers for unprocessed command line options and errors. - * ----------------------------------------------------------------------------- */ - -void Swig_check_options(int check_input) { - int error = 0; - int i; - int max = check_input ? numargs - 1 : numargs; - assert(marked); - for (i = 1; i < max; i++) { - if (!marked[i]) { - Printf(stderr, "swig error : Unrecognized option %s\n", args[i]); - error = 1; - } - } - if (error) { - Printf(stderr, "Use 'swig -help' for available options.\n"); - Exit(EXIT_FAILURE); - } - if (check_input && marked[numargs - 1]) { - Printf(stderr, "Must specify an input file. Use -help for available options.\n"); - Exit(EXIT_FAILURE); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_arg_error() - * - * Generates a generic error message and exits. - * ----------------------------------------------------------------------------- */ - -void Swig_arg_error(void) { - Printf(stderr, "SWIG : Unable to parse command line options.\n"); - Printf(stderr, "Use 'swig -help' for available options.\n"); - Exit(EXIT_FAILURE); -} diff --git a/contrib/tools/swig/Source/Swig/include.c b/contrib/tools/swig/Source/Swig/include.c deleted file mode 100644 index c153ac9b7a4..00000000000 --- a/contrib/tools/swig/Source/Swig/include.c +++ /dev/null @@ -1,377 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * include.c - * - * The functions in this file are used to manage files in the SWIG library. - * General purpose functions for opening, including, and retrieving pathnames - * are provided. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" - -static List *directories = 0; /* List of include directories */ -static String *lastpath = 0; /* Last file that was included */ -static List *pdirectories = 0; /* List of pushed directories */ -static int dopush = 1; /* Whether to push directories */ -static int file_debug = 0; - -/* This functions determine whether to push/pop dirs in the preprocessor */ -void Swig_set_push_dir(int push) { - dopush = push; -} - -int Swig_get_push_dir(void) { - return dopush; -} - -/* ----------------------------------------------------------------------------- - * Swig_add_directory() - * - * Adds a directory to the SWIG search path. - * ----------------------------------------------------------------------------- */ - -List *Swig_add_directory(const_String_or_char_ptr dirname) { - String *adirname; - if (!directories) - directories = NewList(); - assert(directories); - if (dirname) { - adirname = NewString(dirname); - Append(directories,adirname); - Delete(adirname); - } - return directories; -} - -/* ----------------------------------------------------------------------------- - * Swig_push_directory() - * - * Inserts a directory at the front of the SWIG search path. This is used by - * the preprocessor to grab files in the same directory as other included files. - * ----------------------------------------------------------------------------- */ - -void Swig_push_directory(const_String_or_char_ptr dirname) { - String *pdirname; - if (!Swig_get_push_dir()) - return; - if (!pdirectories) - pdirectories = NewList(); - assert(pdirectories); - pdirname = NewString(dirname); - assert(pdirname); - Insert(pdirectories,0,pdirname); - Delete(pdirname); -} - -/* ----------------------------------------------------------------------------- - * Swig_pop_directory() - * - * Pops a directory off the front of the SWIG search path. This is used by - * the preprocessor. - * ----------------------------------------------------------------------------- */ - -void Swig_pop_directory(void) { - if (!Swig_get_push_dir()) - return; - if (!pdirectories) - return; - Delitem(pdirectories, 0); -} - -/* ----------------------------------------------------------------------------- - * Swig_last_file() - * - * Returns the full pathname of the last file opened. - * ----------------------------------------------------------------------------- */ - -String *Swig_last_file(void) { - assert(lastpath); - return lastpath; -} - -/* ----------------------------------------------------------------------------- - * Swig_search_path_any() - * - * Returns a list of the current search paths. - * ----------------------------------------------------------------------------- */ - -static List *Swig_search_path_any(int syspath) { - String *filename; - List *slist; - int i, ilen; - - slist = NewList(); - assert(slist); - filename = NewStringEmpty(); - assert(filename); - Printf(filename, ".%s", SWIG_FILE_DELIMITER); - Append(slist, filename); - Delete(filename); - - /* If there are any pushed directories. Add them first */ - if (pdirectories) { - ilen = Len(pdirectories); - for (i = 0; i < ilen; i++) { - filename = NewString(Getitem(pdirectories,i)); - Append(filename,SWIG_FILE_DELIMITER); - Append(slist,filename); - Delete(filename); - } - } - /* Add system directories next */ - ilen = Len(directories); - for (i = 0; i < ilen; i++) { - filename = NewString(Getitem(directories,i)); - Append(filename,SWIG_FILE_DELIMITER); - if (syspath) { - /* If doing a system include, put the system directories first */ - Insert(slist,i,filename); - } else { - /* Otherwise, just put the system directories after the pushed directories (if any) */ - Append(slist,filename); - } - Delete(filename); - } - return slist; -} - -List *Swig_search_path(void) { - return Swig_search_path_any(0); -} - - - -/* ----------------------------------------------------------------------------- - * Swig_open() - * - * open a file, optionally looking for it in the include path. Returns an open - * FILE * on success. - * ----------------------------------------------------------------------------- */ - -static FILE *Swig_open_file(const_String_or_char_ptr name, int sysfile, int use_include_path) { - FILE *f; - String *filename; - List *spath = 0; - char *cname; - int i, ilen, nbytes; - char bom[3]; - - if (!directories) - directories = NewList(); - assert(directories); - - cname = Char(name); - filename = NewString(cname); - assert(filename); - if (file_debug) { - Printf(stdout, " Open: %s\n", filename); - } - f = fopen(Char(filename), "r"); - if (!f && use_include_path) { - spath = Swig_search_path_any(sysfile); - ilen = Len(spath); - for (i = 0; i < ilen; i++) { - Clear(filename); - Printf(filename, "%s%s", Getitem(spath, i), cname); - f = fopen(Char(filename), "r"); - if (f) - break; - } - Delete(spath); - } - if (f) { - Delete(lastpath); - lastpath = filename; - - /* Skip the UTF-8 BOM if it's present */ - nbytes = (int)fread(bom, 1, 3, f); - if (nbytes == 3 && bom[0] == (char)0xEF && bom[1] == (char)0xBB && bom[2] == (char)0xBF) { - /* skip */ - } else { - fseek(f, 0, SEEK_SET); - } - } - return f; -} - -/* Open a file - searching the include paths to find it */ -FILE *Swig_include_open(const_String_or_char_ptr name) { - return Swig_open_file(name, 0, 1); -} - -/* Open a file - does not use include paths to find it */ -FILE *Swig_open(const_String_or_char_ptr name) { - return Swig_open_file(name, 0, 0); -} - - - -/* ----------------------------------------------------------------------------- - * Swig_read_file() - * - * Reads data from an open FILE * and returns it as a string. - * ----------------------------------------------------------------------------- */ - -String *Swig_read_file(FILE *f) { - int len; - char buffer[4096]; - String *str = NewStringEmpty(); - - assert(str); - while (fgets(buffer, 4095, f)) { - Append(str, buffer); - } - len = Len(str); - /* Add a newline if not present on last line -- the preprocessor seems to - * rely on \n and not EOF terminating lines */ - if (len) { - char *cstr = Char(str); - if (cstr[len - 1] != '\n') { - Append(str, "\n"); - } - } - return str; -} - -/* ----------------------------------------------------------------------------- - * Swig_include() - * - * Opens a file and returns it as a string. - * ----------------------------------------------------------------------------- */ - -static String *Swig_include_any(const_String_or_char_ptr name, int sysfile) { - FILE *f; - String *str; - String *file; - - f = Swig_open_file(name, sysfile, 1); - if (!f) - return 0; - str = Swig_read_file(f); - fclose(f); - Seek(str, 0, SEEK_SET); - file = Copy(Swig_last_file()); - Setfile(str, file); - Delete(file); - Setline(str, 1); - return str; -} - -String *Swig_include(const_String_or_char_ptr name) { - return Swig_include_any(name, 0); -} - -String *Swig_include_sys(const_String_or_char_ptr name) { - return Swig_include_any(name, 1); -} - -/* ----------------------------------------------------------------------------- - * Swig_insert_file() - * - * Copies the contents of a file into another file - * ----------------------------------------------------------------------------- */ - -int Swig_insert_file(const_String_or_char_ptr filename, File *outfile) { - char buffer[4096]; - int nbytes; - FILE *f = Swig_include_open(filename); - - if (!f) - return -1; - while ((nbytes = Read(f, buffer, 4096)) > 0) { - Write(outfile, buffer, nbytes); - } - fclose(f); - return 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_register_filebyname() - * - * Register a "named" file with the core. Named files can become targets - * for %insert directives and other SWIG operations. This function takes - * the place of the f_header, f_wrapper, f_init, and other global variables - * in SWIG1.1 - * ----------------------------------------------------------------------------- */ - -static Hash *named_files = 0; - -void Swig_register_filebyname(const_String_or_char_ptr filename, File *outfile) { - if (!named_files) - named_files = NewHash(); - Setattr(named_files, filename, outfile); -} - -/* ----------------------------------------------------------------------------- - * Swig_filebyname() - * - * Get a named file - * ----------------------------------------------------------------------------- */ - -File *Swig_filebyname(const_String_or_char_ptr filename) { - if (!named_files) - return 0; - return Getattr(named_files, filename); -} - -/* ----------------------------------------------------------------------------- - * Swig_file_extension() - * - * Returns the extension of a file - * ----------------------------------------------------------------------------- */ - -String *Swig_file_extension(const_String_or_char_ptr filename) { - String *name = Swig_file_filename(filename); - const char *c = strrchr(Char(name), '.'); - String *extension = c ? NewString(c) : NewString(""); - Delete(name); - return extension; -} - -/* ----------------------------------------------------------------------------- - * Swig_file_basename() - * - * Returns the filename with the extension removed. - * ----------------------------------------------------------------------------- */ - -String *Swig_file_basename(const_String_or_char_ptr filename) { - String *extension = Swig_file_extension(filename); - String *basename = NewStringWithSize(filename, Len(filename) - Len(extension)); - Delete(extension); - return basename; -} - -/* ----------------------------------------------------------------------------- - * Swig_file_filename() - * - * Return the file name with any leading path stripped off - * ----------------------------------------------------------------------------- */ -String *Swig_file_filename(const_String_or_char_ptr filename) { - const char *delim = SWIG_FILE_DELIMITER; - const char *c = strrchr(Char(filename), *delim); - return c ? NewString(c + 1) : NewString(filename); -} - -/* ----------------------------------------------------------------------------- - * Swig_file_dirname() - * - * Return the name of the directory associated with a file - * ----------------------------------------------------------------------------- */ -String *Swig_file_dirname(const_String_or_char_ptr filename) { - const char *delim = SWIG_FILE_DELIMITER; - const char *c = strrchr(Char(filename), *delim); - return c ? NewStringWithSize(filename, (int)(c - Char(filename) + 1)) : NewString(""); -} - -/* - * Swig_file_debug() - */ -void Swig_file_debug_set(void) { - file_debug = 1; -} diff --git a/contrib/tools/swig/Source/Swig/misc.c b/contrib/tools/swig/Source/Swig/misc.c deleted file mode 100644 index 7d1119c5e27..00000000000 --- a/contrib/tools/swig/Source/Swig/misc.c +++ /dev/null @@ -1,1569 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * misc.c - * - * Miscellaneous functions that don't really fit anywhere else. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include <errno.h> -#include <ctype.h> -#include <limits.h> -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef _WIN32 -#include <direct.h> -#ifndef S_ISDIR -#define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR) -#endif -#endif - -static char *fake_version = 0; - -/* ----------------------------------------------------------------------------- - * Swig_copy_string() - * - * Duplicate a NULL-terminate string given as a char *. - * ----------------------------------------------------------------------------- */ - -char *Swig_copy_string(const char *s) { - char *c = 0; - if (s) { - c = (char *) Malloc(strlen(s) + 1); - strcpy(c, s); - } - return c; -} - -/* ----------------------------------------------------------------------------- - * Swig_set_fakeversion() - * - * Version string override - * ----------------------------------------------------------------------------- */ - -void Swig_set_fakeversion(const char *version) { - fake_version = Swig_copy_string(version); -} - -/* ----------------------------------------------------------------------------- - * Swig_package_version() - * - * Return the package string containing the version number - * ----------------------------------------------------------------------------- */ - -const char *Swig_package_version(void) { - return fake_version ? fake_version : PACKAGE_VERSION; -} - -/* ----------------------------------------------------------------------------- - * Swig_package_version_hex() - * - * Return the package version in hex format "0xAABBCC" such as "0x040200" for 4.2.0 - * ----------------------------------------------------------------------------- */ - -String *Swig_package_version_hex(void) { - String *package_version = NewString(Swig_package_version()); - char *token = strtok(Char(package_version), "."); - String *vers = NewString("SWIG_VERSION 0x"); - int count = 0; - while (token) { - int len = (int)strlen(token); - assert(len == 1 || len == 2); - Printf(vers, "%s%s", (len == 1) ? "0" : "", token); - token = strtok(NULL, "."); - count++; - } - Delete(package_version); - assert(count == 3); /* Check version format is correct */ - return vers; -} - -/* ----------------------------------------------------------------------------- - * Swig_obligatory_macros() - * - * Generates the SWIG_VERSION and SWIGXXX macros where XXX is the target language - * name (must be provided uppercase). - * ----------------------------------------------------------------------------- */ - -void Swig_obligatory_macros(String *f_runtime, const char *language) { - String *version_hex = Swig_package_version_hex(); - Printf(f_runtime, "\n\n"); - Printf(f_runtime, "#define %s\n", version_hex); - Printf(f_runtime, "#define SWIG%s\n", language); - Delete(version_hex); -} - -/* ----------------------------------------------------------------------------- - * Swig_banner() - * - * Emits the SWIG identifying banner for the C/C++ wrapper file. - * ----------------------------------------------------------------------------- */ - -void Swig_banner(File *f) { - Printf(f, "/* ----------------------------------------------------------------------------\n"); - Swig_banner_target_lang(f, " *"); - Printf(f, " * ----------------------------------------------------------------------------- */\n"); - -} - -/* ----------------------------------------------------------------------------- - * Swig_banner_target_lang() - * - * Emits a SWIG identifying banner in the target language - * ----------------------------------------------------------------------------- */ - -void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar) { - Printf(f, "%s This file was automatically generated by SWIG (https://www.swig.org).\n", commentchar); - Printf(f, "%s Version %s\n", commentchar, Swig_package_version()); - Printf(f, "%s\n", commentchar); - Printf(f, "%s Do not make changes to this file unless you know what you are doing - modify\n", commentchar); - Printf(f, "%s the SWIG interface file instead.\n", commentchar); -} - -/* ----------------------------------------------------------------------------- - * Swig_strip_c_comments() - * - * Return a new string with C comments stripped from the input string. NULL is - * returned if there aren't any comments. - * ----------------------------------------------------------------------------- */ - -String *Swig_strip_c_comments(const String *s) { - const char *c = Char(s); - const char *comment_begin = 0; - const char *comment_end = 0; - String *stripped = 0; - - while (*c) { - if (!comment_begin && *c == '/') { - ++c; - if (!*c) - break; - if (*c == '*') - comment_begin = c-1; - } else if (comment_begin && !comment_end && *c == '*') { - ++c; - if (*c == '/') { - comment_end = c; - break; - } - } - ++c; - } - - if (comment_begin && comment_end) { - int size = (int)(comment_begin - Char(s)); - String *stripmore = 0; - stripped = NewStringWithSize(s, size); - Printv(stripped, comment_end + 1, NIL); - do { - stripmore = Swig_strip_c_comments(stripped); - if (stripmore) { - Delete(stripped); - stripped = stripmore; - } - } while (stripmore); - } - return stripped; -} - -/* ----------------------------------------------------------------------------- - * is_directory() - * ----------------------------------------------------------------------------- */ -static int is_directory(String *directory) { - int last = Len(directory) - 1; - int statres; - struct stat st; - char *dir = Char(directory); - if (dir[last] == SWIG_FILE_DELIMITER[0]) { - /* remove trailing slash - can cause S_ISDIR to fail on Windows, at least */ - dir[last] = 0; - statres = stat(dir, &st); - dir[last] = SWIG_FILE_DELIMITER[0]; - } else { - statres = stat(dir, &st); - } - return (statres == 0 && S_ISDIR(st.st_mode)); -} - -/* ----------------------------------------------------------------------------- - * Swig_new_subdirectory() - * - * Create the subdirectory only if the basedirectory already exists as a directory. - * basedirectory can be empty to indicate current directory but not NULL. - * ----------------------------------------------------------------------------- */ - -String *Swig_new_subdirectory(String *basedirectory, String *subdirectory) { - String *error = 0; - int current_directory = Len(basedirectory) == 0; - - if (current_directory || is_directory(basedirectory)) { - Iterator it; - String *dir = NewString(basedirectory); - List *subdirs = Split(subdirectory, SWIG_FILE_DELIMITER[0], INT_MAX); - - for (it = First(subdirs); it.item; it = Next(it)) { - int result; - String *subdirectory = it.item; - Printf(dir, "%s", subdirectory); -#ifdef _WIN32 - result = _mkdir(Char(dir)); -#else - result = mkdir(Char(dir), 0777); -#endif - if (result != 0 && errno != EEXIST) { - error = NewStringf("Cannot create directory %s: %s", dir, strerror(errno)); - break; - } - if (!is_directory(dir)) { - error = NewStringf("Cannot create directory %s: it may already exist but not be a directory", dir); - break; - } - Printf(dir, SWIG_FILE_DELIMITER); - } - } else { - error = NewStringf("Cannot create subdirectory %s under the base directory %s. Either the base does not exist as a directory or it is not readable.", subdirectory, basedirectory); - } - return error; -} - -/* ----------------------------------------------------------------------------- - * Swig_filename_correct() - * - * Corrects filename paths by removing duplicate delimiters and on non-unix - * systems use the correct delimiter across the whole name. - * ----------------------------------------------------------------------------- */ - -void Swig_filename_correct(String *filename) { - int network_path = 0; - if (Len(filename) >= 2) { - const char *fname = Char(filename); - if (fname[0] == '\\' && fname[1] == '\\') - network_path = 1; - if (fname[0] == '/' && fname[1] == '/') - network_path = 1; - } -#if defined(_WIN32) - /* accept Unix path separator on non-Unix systems */ - Replaceall(filename, "/", SWIG_FILE_DELIMITER); -#endif -#if defined(__CYGWIN__) - /* accept Windows path separator in addition to Unix path separator */ - Replaceall(filename, "\\", SWIG_FILE_DELIMITER); -#endif - /* remove all duplicate file name delimiters */ - while (Replaceall(filename, SWIG_FILE_DELIMITER SWIG_FILE_DELIMITER, SWIG_FILE_DELIMITER)) { - } - /* Network paths can start with a double slash on Windows - unremove the duplicate slash we just removed */ - if (network_path) - Insert(filename, 0, SWIG_FILE_DELIMITER); -} - -/* ----------------------------------------------------------------------------- - * Swig_filename_escape() - * - * Escapes backslashes in filename - for Windows - * ----------------------------------------------------------------------------- */ - -String *Swig_filename_escape(String *filename) { - String *adjusted_filename = Copy(filename); - Swig_filename_correct(adjusted_filename); -#if defined(_WIN32) /* Note not on Cygwin else filename is displayed with double '/' */ - Replaceall(adjusted_filename, "\\", "\\\\"); -#endif - return adjusted_filename; -} - -/* ----------------------------------------------------------------------------- - * Swig_filename_escape() - * - * Escapes spaces in filename - for Makefiles - * ----------------------------------------------------------------------------- */ - -String *Swig_filename_escape_space(String *filename) { - String *adjusted_filename = Copy(filename); - Swig_filename_correct(adjusted_filename); - Replaceall(adjusted_filename, " ", "\\ "); - return adjusted_filename; -} - -/* ----------------------------------------------------------------------------- - * Swig_filename_unescape() - * - * Remove double backslash escaping in filename - for Windows - * ----------------------------------------------------------------------------- */ - -void Swig_filename_unescape(String *filename) { - (void)filename; -#if defined(_WIN32) - Replaceall(filename, "\\\\", "\\"); -#endif -} - -/* ----------------------------------------------------------------------------- - * Swig_storage_isextern() - * - * Determine if the storage class specifier is extern (but not externc) - * ----------------------------------------------------------------------------- */ - -int Swig_storage_isextern(Node *n) { - const String *storage = Getattr(n, "storage"); - return storage ? Strcmp(storage, "extern") == 0 || Strncmp(storage, "extern ", 7) == 0 : 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_storage_isexternc() - * - * Determine if the storage class specifier is externc (but not plain extern) - * ----------------------------------------------------------------------------- */ - -int Swig_storage_isexternc(Node *n) { - const String *storage = Getattr(n, "storage"); - return storage ? Strcmp(storage, "externc") == 0 || Strncmp(storage, "externc ", 8) == 0 : 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_storage_isstatic_custom() - * - * Determine if the storage class specifier is static - * ----------------------------------------------------------------------------- */ - -int Swig_storage_isstatic_custom(Node *n, const_String_or_char_ptr storage_name) { - const String *storage = Getattr(n, storage_name); - return storage ? Strncmp(storage, "static", 6) == 0 : 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_storage_isstatic() - * - * Determine if the storage class specifier is static - * ----------------------------------------------------------------------------- */ - -int Swig_storage_isstatic(Node *n) { - return Swig_storage_isstatic_custom(n, "storage"); -} - -/* ----------------------------------------------------------------------------- - * Swig_string_escape() - * - * Takes a string object and produces a string with escape codes added to it. - * Octal escaping is used. - * ----------------------------------------------------------------------------- */ - -String *Swig_string_escape(String *s) { - String *ns; - int c; - ns = NewStringEmpty(); - - while ((c = Getc(s)) != EOF) { - if (c == '\n') { - Printf(ns, "\\n"); - } else if (c == '\r') { - Printf(ns, "\\r"); - } else if (c == '\t') { - Printf(ns, "\\t"); - } else if (c == '\\') { - Printf(ns, "\\\\"); - } else if (c == '\'') { - Printf(ns, "\\'"); - } else if (c == '\"') { - Printf(ns, "\\\""); - } else if (c == ' ') { - Putc(c, ns); - } else if (!isgraph(c)) { - if (c < 0) - c += UCHAR_MAX + 1; - Printf(ns, "\\%o", c); - } else { - Putc(c, ns); - } - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_hexescape() - * - * Takes a string object and produces a string with escape codes added to it. - * Hex escaping is used. - * ----------------------------------------------------------------------------- */ - -String *Swig_string_hexescape(String *s) { - String *ns; - int c; - ns = NewStringEmpty(); - - while ((c = Getc(s)) != EOF) { - if (c == '\n') { - Printf(ns, "\\n"); - } else if (c == '\r') { - Printf(ns, "\\r"); - } else if (c == '\t') { - Printf(ns, "\\t"); - } else if (c == '\\') { - Printf(ns, "\\\\"); - } else if (c == '\'') { - Printf(ns, "\\'"); - } else if (c == '\"') { - Printf(ns, "\\\""); - } else if (c == ' ') { - Putc(c, ns); - } else if (!isgraph(c)) { - if (c < 0) - c += UCHAR_MAX + 1; - Printf(ns, "\\x%X", c); - } else { - Putc(c, ns); - } - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_upper() - * - * Takes a string object and returns a copy that is uppercase - * ----------------------------------------------------------------------------- */ - -String *Swig_string_upper(String *s) { - String *ns; - int c; - ns = NewStringEmpty(); - - Seek(s, 0, SEEK_SET); - while ((c = Getc(s)) != EOF) { - Putc(toupper(c), ns); - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_lower() - * - * Takes a string object and returns a copy that is lowercase - * ----------------------------------------------------------------------------- */ - -String *Swig_string_lower(String *s) { - String *ns; - int c; - ns = NewStringEmpty(); - - Seek(s, 0, SEEK_SET); - while ((c = Getc(s)) != EOF) { - Putc(tolower(c), ns); - } - return ns; -} - - -/* ----------------------------------------------------------------------------- - * Swig_string_title() - * - * Takes a string object and returns a copy that is lowercase with first letter - * capitalized - * ----------------------------------------------------------------------------- */ - -String *Swig_string_title(String *s) { - String *ns; - int first = 1; - int c; - ns = NewStringEmpty(); - - Seek(s, 0, SEEK_SET); - while ((c = Getc(s)) != EOF) { - Putc(first ? toupper(c) : tolower(c), ns); - first = 0; - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_ccase() - * - * Takes a string object and returns a copy that is lowercase with the first - * letter capitalized and the one following '_', which are removed. - * - * camel_case -> CamelCase - * camelCase -> CamelCase - * ----------------------------------------------------------------------------- */ - -String *Swig_string_ccase(String *s) { - String *ns; - int first = 1; - int c; - ns = NewStringEmpty(); - - Seek(s, 0, SEEK_SET); - while ((c = Getc(s)) != EOF) { - if (c == '_') { - first = 1; - continue; - } - Putc(first ? toupper(c) : c, ns); - first = 0; - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_lccase() - * - * Takes a string object and returns a copy with the character after - * each '_' capitalised, and the '_' removed. The first character is - * also forced to lowercase. - * - * camel_case -> camelCase - * CamelCase -> camelCase - * ----------------------------------------------------------------------------- */ - -String *Swig_string_lccase(String *s) { - String *ns; - int first = 1; - int after_underscore = 0; - int c; - ns = NewStringEmpty(); - - Seek(s, 0, SEEK_SET); - while ((c = Getc(s)) != EOF) { - if (c == '_') { - after_underscore = 1; - continue; - } - if (first) { - Putc(tolower(c), ns); - first = 0; - } else { - Putc(after_underscore ? toupper(c) : c, ns); - } - after_underscore = 0; - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_ucase() - * - * This is the reverse case of ccase, ie - * - * CamelCase -> camel_case - * get2D -> get_2d - * asFloat2 -> as_float2 - * ----------------------------------------------------------------------------- */ - -String *Swig_string_ucase(String *s) { - String *ns; - int c; - int lastC = 0; - int nextC = 0; - int underscore = 0; - ns = NewStringEmpty(); - - /* We insert a underscore when: - 1. Lower case char followed by upper case char - getFoo > get_foo; getFOo > get_foo; GETFOO > getfoo - 2. Number preceded by char and not end of string - get2D > get_2d; get22D > get_22d; GET2D > get_2d - but: - asFloat2 > as_float2 - */ - - Seek(s, 0, SEEK_SET); - - while ((c = Getc(s)) != EOF) { - nextC = Getc(s); Ungetc(nextC, s); - if (isdigit(c) && isalpha(lastC) && nextC != EOF) - underscore = 1; - else if (isupper(c) && isalpha(lastC) && !isupper(lastC)) - underscore = 1; - - lastC = c; - - if (underscore) { - Putc('_', ns); - underscore = 0; - } - - Putc(tolower(c), ns); - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_first_upper() - * - * Make the first character in the string uppercase, leave all the - * rest the same. This is used by the Ruby module to provide backwards - * compatibility with the old way of naming classes and constants. For - * more info see the Ruby documentation. - * - * firstUpper -> FirstUpper - * ----------------------------------------------------------------------------- */ - -String *Swig_string_first_upper(String *s) { - String *ns = NewStringEmpty(); - char *cs = Char(s); - if (cs && cs[0] != 0) { - Putc(toupper((int)cs[0]), ns); - Append(ns, cs + 1); - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_first_lower() - * - * Make the first character in the string lowercase, leave all the - * rest the same. This is used by the Ruby module to provide backwards - * compatibility with the old way of naming classes and constants. For - * more info see the Ruby documentation. - * - * firstLower -> FirstLower - * ----------------------------------------------------------------------------- */ - -String *Swig_string_first_lower(String *s) { - String *ns = NewStringEmpty(); - char *cs = Char(s); - if (cs && cs[0] != 0) { - Putc(tolower((int)cs[0]), ns); - Append(ns, cs + 1); - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_schemify() - * - * Replace underscores with dashes, to make identifiers look nice to Schemers. - * - * under_scores -> under-scores - * ----------------------------------------------------------------------------- */ - -String *Swig_string_schemify(String *s) { - String *ns = NewString(s); - Replaceall(ns, "_", "-"); - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_typecode() - * - * Takes a string with possible type-escapes in it and replaces them with - * real C datatypes. - * ----------------------------------------------------------------------------- */ - -String *Swig_string_typecode(String *s) { - String *ns; - int c; - String *tc; - ns = NewStringEmpty(); - while ((c = Getc(s)) != EOF) { - if (c == '`') { - String *str = 0; - tc = NewStringEmpty(); - while ((c = Getc(s)) != EOF) { - if (c == '`') - break; - Putc(c, tc); - } - str = SwigType_str(tc, 0); - Append(ns, str); - Delete(str); - } else { - Putc(c, ns); - if (c == '\'') { - while ((c = Getc(s)) != EOF) { - Putc(c, ns); - if (c == '\'') - break; - if (c == '\\') { - c = Getc(s); - Putc(c, ns); - } - } - } else if (c == '\"') { - while ((c = Getc(s)) != EOF) { - Putc(c, ns); - if (c == '\"') - break; - if (c == '\\') { - c = Getc(s); - Putc(c, ns); - } - } - } - } - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_mangle() - * - * Take a string and mangle it by stripping all non-valid C identifier - * characters. - * - * This routine skips unnecessary blank spaces, therefore mangling - * 'char *' and 'char*', 'std::pair<int, int >' and - * 'std::pair<int,int>', produce the same result. - * - * However, note that 'long long' and 'long_long' produce different - * mangled strings. - * - * The mangling method still is not 'perfect', for example std::pair and - * std_pair return the same mangling. This is just a little better - * than before, but it seems to be enough for most of the purposes. - * - * Having a perfect mangling will break some examples and code which - * assume, for example, that A::get_value will be mangled as - * A_get_value. - * ----------------------------------------------------------------------------- */ - -String *Swig_string_mangle(const String *s) { -#if 0 - /* old mangling, not suitable for using in macros */ - String *t = Copy(s); - char *c = Char(t); - while (*c) { - if (!isalnum(*c)) - *c = '_'; - c++; - } - return t; -#else - String *result = NewStringEmpty(); - int space = 0; - int state = 0; - char *pc, *cb; - String *b = Copy(s); - if (SwigType_istemplate(b)) { - String *st = Swig_symbol_template_deftype(b, 0); - String *sq = Swig_symbol_type_qualify(st, 0); - String *t = SwigType_namestr(sq); - Delete(st); - Delete(sq); - Delete(b); - b = t; - } - pc = cb = Char(b); - while (*pc) { - char c = *pc; - if (isalnum((int) c) || (c == '_')) { - state = 1; - if (space && (space == state)) { - Append(result, "_SS_"); - } - space = 0; - Printf(result, "%c", (int) c); - - } else { - if (isspace((int) c)) { - space = state; - ++pc; - continue; - } else { - state = 3; - space = 0; - } - switch (c) { - case '.': - if ((cb != pc) && (*(pc - 1) == 'p')) { - Append(result, "_"); - ++pc; - continue; - } else { - c = 'f'; - } - break; - case ':': - if (*(pc + 1) == ':') { - Append(result, "_"); - ++pc; - ++pc; - continue; - } - break; - case '*': - c = 'm'; - break; - case '&': - c = 'A'; - break; - case '<': - c = 'l'; - break; - case '>': - c = 'g'; - break; - case '=': - c = 'e'; - break; - case ',': - c = 'c'; - break; - case '(': - c = 'p'; - break; - case ')': - c = 'P'; - break; - case '[': - c = 'b'; - break; - case ']': - c = 'B'; - break; - case '^': - c = 'x'; - break; - case '|': - c = 'o'; - break; - case '~': - c = 'n'; - break; - case '!': - c = 'N'; - break; - case '%': - c = 'M'; - break; - case '?': - c = 'q'; - break; - case '+': - c = 'a'; - break; - case '-': - c = 's'; - break; - case '/': - c = 'd'; - break; - default: - break; - } - if (isalpha((int) c)) { - Printf(result, "_S%c_", (int) c); - } else { - Printf(result, "_S%02X_", (int) c); - } - } - ++pc; - } - Delete(b); - return result; -#endif -} - -String *Swig_string_emangle(String *s) { - return Swig_string_mangle(s); -} - - -/* ----------------------------------------------------------------------------- - * Swig_scopename_split() - * - * Take a qualified name like "A::B::C" and splits off the last name. - * In this case, returns "C" as last and "A::B" as prefix. - * Always returns non NULL for last, but prefix may be NULL if there is no prefix. - * ----------------------------------------------------------------------------- */ - -void Swig_scopename_split(const String *s, String **rprefix, String **rlast) { - char *tmp = Char(s); - char *c = tmp; - char *cc = c; - char *co = 0; - if (!strstr(c, "::")) { - *rprefix = 0; - *rlast = Copy(s); - } - - co = strstr(cc, "operator "); - if (co) { - if (co == cc) { - *rprefix = 0; - *rlast = Copy(s); - return; - } else { - *rprefix = NewStringWithSize(cc, (int)(co - cc - 2)); - *rlast = NewString(co); - return; - } - } - while (*c) { - if ((*c == ':') && (*(c + 1) == ':')) { - cc = c; - c += 2; - } else { - if (*c == '<') { - int level = 1; - c++; - while (*c && level) { - if (*c == '<') - level++; - if (*c == '>') - level--; - c++; - } - } else { - c++; - } - } - } - - if (cc != tmp) { - *rprefix = NewStringWithSize(tmp, (int)(cc - tmp)); - *rlast = NewString(cc + 2); - return; - } else { - *rprefix = 0; - *rlast = Copy(s); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_scopename_prefix() - * - * Take a qualified name like "A::B::C" and return the scope name. - * In this case, "A::B". Returns NULL if there is no base. - * ----------------------------------------------------------------------------- */ - -String *Swig_scopename_prefix(const String *s) { - char *tmp = Char(s); - char *c = tmp; - char *cc = c; - char *co = 0; - if (!strstr(c, "::")) - return 0; - co = strstr(cc, "operator "); - - if (co) { - if (co == cc) { - return 0; - } else { - String *prefix = NewStringWithSize(cc, (int)(co - cc - 2)); - return prefix; - } - } - while (*c) { - if ((*c == ':') && (*(c + 1) == ':')) { - cc = c; - c += 2; - } else { - if (*c == '<') { - int level = 1; - c++; - while (*c && level) { - if (*c == '<') - level++; - if (*c == '>') - level--; - c++; - } - } else { - c++; - } - } - } - - if (cc != tmp) { - return NewStringWithSize(tmp, (int)(cc - tmp)); - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * Swig_scopename_last() - * - * Take a qualified name like "A::B::C" and returns the last. In this - * case, "C". - * ----------------------------------------------------------------------------- */ - -String *Swig_scopename_last(const String *s) { - char *tmp = Char(s); - char *c = tmp; - char *cc = c; - char *co = 0; - if (!strstr(c, "::")) - return NewString(s); - - co = strstr(cc, "operator "); - if (co) { - return NewString(co); - } - - - while (*c) { - if ((*c == ':') && (*(c + 1) == ':')) { - c += 2; - cc = c; - } else { - if (*c == '<') { - int level = 1; - c++; - while (*c && level) { - if (*c == '<') - level++; - if (*c == '>') - level--; - c++; - } - } else { - c++; - } - } - } - return NewString(cc); -} - -/* ----------------------------------------------------------------------------- - * Swig_scopename_first() - * - * Take a qualified name like "A::B::C" and returns the first scope name. - * In this case, "A". Returns NULL if there is no base. - * ----------------------------------------------------------------------------- */ - -String *Swig_scopename_first(const String *s) { - char *tmp = Char(s); - char *c = tmp; - char *co = 0; - if (!strstr(c, "::")) - return 0; - - co = strstr(c, "operator "); - if (co) { - if (co == c) { - return 0; - } - } else { - co = c + Len(s); - } - - while (*c && (c != co)) { - if ((*c == ':') && (*(c + 1) == ':')) { - break; - } else { - if (*c == '<') { - int level = 1; - c++; - while (*c && level) { - if (*c == '<') - level++; - if (*c == '>') - level--; - c++; - } - } else { - c++; - } - } - } - if (*c && (c != tmp)) { - return NewStringWithSize(tmp, (int)(c - tmp)); - } else { - return 0; - } -} - - -/* ----------------------------------------------------------------------------- - * Swig_scopename_suffix() - * - * Take a qualified name like "A::B::C" and returns the suffix. - * In this case, "B::C". Returns NULL if there is no suffix. - * ----------------------------------------------------------------------------- */ - -String *Swig_scopename_suffix(const String *s) { - char *tmp = Char(s); - char *c = tmp; - char *co = 0; - if (!strstr(c, "::")) - return 0; - - co = strstr(c, "operator "); - if (co) { - if (co == c) - return 0; - } - while (*c) { - if ((*c == ':') && (*(c + 1) == ':')) { - break; - } else { - if (*c == '<') { - int level = 1; - c++; - while (*c && level) { - if (*c == '<') - level++; - if (*c == '>') - level--; - c++; - } - } else { - c++; - } - } - } - if (*c && (c != tmp)) { - return NewString(c + 2); - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * Swig_scopename_tolist() - * - * Take a qualified scope name like "A::B::C" and convert it to a list. - * In this case, return a list of 3 elements "A", "B", "C". - * Returns an empty list if the input is empty. - * ----------------------------------------------------------------------------- */ - -List *Swig_scopename_tolist(const String *s) { - List *scopes = NewList(); - String *name = Len(s) == 0 ? 0 : NewString(s); - - while (name) { - String *last = 0; - String *prefix = 0; - Swig_scopename_split(name, &prefix, &last); - Insert(scopes, 0, last); - Delete(last); - Delete(name); - name = prefix; - } - Delete(name); - return scopes; -} - -/* ----------------------------------------------------------------------------- - * Swig_scopename_check() - * - * Checks to see if a name is qualified with a scope name, examples: - * foo -> 0 - * ::foo -> 1 - * foo::bar -> 1 - * foo< ::bar > -> 0 - * ----------------------------------------------------------------------------- */ - -int Swig_scopename_check(const String *s) { - char *c = Char(s); - char *co = strstr(c, "operator "); - - if (co) { - if (co == c) - return 0; - } - if (!strstr(c, "::")) - return 0; - while (*c) { - if ((*c == ':') && (*(c + 1) == ':')) { - return 1; - } else { - if (*c == '<') { - int level = 1; - c++; - while (*c && level) { - if (*c == '<') - level++; - if (*c == '>') - level--; - c++; - } - } else { - c++; - } - } - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_command() - * - * Feature removed in SWIG 4.1.0. - * ----------------------------------------------------------------------------- */ - -String *Swig_string_command(String *s) { - Swig_error("SWIG", Getline(s), "Command encoder no longer supported - use regex encoder instead.\n"); - Exit(EXIT_FAILURE); - return 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_strip() - * - * Strip given prefix from identifiers - * - * Printf(stderr,"%(strip:[wx])s","wxHello") -> Hello - * ----------------------------------------------------------------------------- */ - -String *Swig_string_strip(String *s) { - String *ns; - if (!Len(s)) { - ns = NewString(s); - } else { - const char *cs = Char(s); - const char *ce = Strchr(cs, ']'); - if (*cs != '[' || !ce) { - ns = NewString(s); - } else { - String *fmt = NewStringf("%%.%ds", ce-cs-1); - String *prefix = NewStringf(fmt, cs+1); - if (0 == Strncmp(ce+1, prefix, Len(prefix))) { - ns = NewString(ce+1+Len(prefix)); - } else { - ns = NewString(ce+1); - } - } - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_rstrip() - * - * Strip given suffix from identifiers - * - * Printf(stderr,"%(rstrip:[Cls])s","HelloCls") -> Hello - * ----------------------------------------------------------------------------- */ - -String *Swig_string_rstrip(String *s) { - String *ns; - int len = Len(s); - if (!len) { - ns = NewString(s); - } else { - const char *cs = Char(s); - const char *ce = Strchr(cs, ']'); - if (*cs != '[' || !ce) { - ns = NewString(s); - } else { - String *fmt = NewStringf("%%.%ds", ce-cs-1); - String *suffix = NewStringf(fmt, cs+1); - int suffix_len = Len(suffix); - if (0 == Strncmp(cs+len-suffix_len, suffix, suffix_len)) { - int copy_len = len-suffix_len-(int)(ce+1-cs); - ns = NewStringWithSize(ce+1, copy_len); - } else { - ns = NewString(ce+1); - } - } - } - return ns; -} - -/* ----------------------------------------------------------------------------- - * Swig_offset_string() - * - * Insert number tabs before each new line in s - * ----------------------------------------------------------------------------- */ - -void Swig_offset_string(String *s, int number) { - char *res, *p, *end, *start; - /* count a number of lines in s */ - int lines = 1; - int len = Len(s); - if (len == 0) - return; - start = strchr(Char(s), '\n'); - while (start) { - ++lines; - start = strchr(start + 1, '\n'); - } - /* do not count pending new line */ - if ((Char(s))[len-1] == '\n') - --lines; - /* allocate a temporary storage for a padded string */ - res = (char*)Malloc(len + lines * number * 2 + 1); - res[len + lines * number * 2] = 0; - - /* copy lines to res, prepending tabs to each line */ - p = res; /* output pointer */ - start = Char(s); /* start of a current line */ - end = strchr(start, '\n'); /* end of a current line */ - while (end) { - memset(p, ' ', number*2); - p += number*2; - memcpy(p, start, end - start + 1); - p += end - start + 1; - start = end + 1; - end = strchr(start, '\n'); - } - /* process the last line */ - if (*start) { - memset(p, ' ', number*2); - p += number*2; - strcpy(p, start); - } - /* replace 's' contents with 'res' */ - Clear(s); - Append(s, res); - Free(res); -} - - -#ifdef HAVE_PCRE -#define PCRE2_CODE_UNIT_WIDTH 8 -#include <pcre2.h> - -static int split_regex_pattern_subst(String *s, String **pattern, String **subst, const char **input) -{ - const char *pats, *pate; - const char *subs, *sube; - - /* Locate the search pattern */ - const char *p = Char(s); - if (*p++ != '/') goto err_out; - pats = p; - p = strchr(p, '/'); - if (!p) goto err_out; - pate = p; - - /* Locate the substitution string */ - subs = ++p; - p = strchr(p, '/'); - if (!p) goto err_out; - sube = p; - - *pattern = NewStringWithSize(pats, (int)(pate - pats)); - *subst = NewStringWithSize(subs, (int)(sube - subs)); - *input = p + 1; - return 1; - -err_out: - Swig_error("SWIG", Getline(s), "Invalid regex substitution: '%s'.\n", s); - Exit(EXIT_FAILURE); - return 0; -} - -/* This function copies len characters from src to dst, possibly applying case conversions to them: if convertCase is 1, to upper case and if it is -1, to lower - * case. If convertNextOnly is 1, only a single character is converted (and convertCase is reset), otherwise all of them are. */ -static void copy_with_maybe_case_conversion(String *dst, const char *src, int len, int *convertCase, int convertNextOnly) -{ - /* Deal with the trivial cases first. */ - if (!len) - return; - - if (!*convertCase) { - Write(dst, src, len); - return; - } - - /* If we must convert only the first character, do it and write the rest at once. */ - if (convertNextOnly) { - int src_char = *src; - Putc(*convertCase == 1 ? toupper(src_char) : tolower(src_char), dst); - *convertCase = 0; - if (len > 1) { - Write(dst, src + 1, len - 1); - } - } else { - /* We need to convert all characters. */ - int i; - for (i = 0; i < len; i++, src++) { - int src_char = *src; - Putc(*convertCase == 1 ? toupper(src_char) : tolower(src_char), dst); - } - } -} - -String *replace_captures(int num_captures, const char *input, String *subst, size_t captures[], String *pattern, String *s) -{ - int convertCase = 0, convertNextOnly = 0; - String *result = NewStringEmpty(); - const char *p = Char(subst); - - while (*p) { - /* Copy part without substitutions */ - const char *q = strchr(p, '\\'); - if (!q) { - copy_with_maybe_case_conversion(result, p, (int)strlen(p), &convertCase, convertNextOnly); - break; - } - copy_with_maybe_case_conversion(result, p, (int)(q - p), &convertCase, convertNextOnly); - p = q + 1; - - /* Handle substitution */ - if (*p == '\0') { - Putc('\\', result); - } else if (isdigit((unsigned char)*p)) { - int group = *p++ - '0'; - if (group < num_captures) { - int l = (int)captures[group*2], r = (int)captures[group*2 + 1]; - if (l != -1) { - copy_with_maybe_case_conversion(result, input + l, r - l, &convertCase, convertNextOnly); - } - } else { - Swig_error("SWIG", Getline(s), "PCRE capture replacement failed while matching \"%s\" using \"%s\" - request for group %d is greater than the number of captures %d.\n", - Char(pattern), input, group, num_captures-1); - } - } else { - /* Handle Perl-like case conversion escapes. */ - switch (*p) { - case 'u': - convertCase = 1; - convertNextOnly = 1; - break; - case 'U': - convertCase = 1; - convertNextOnly = 0; - break; - case 'l': - convertCase = -1; - convertNextOnly = 1; - break; - case 'L': - convertCase = -1; - convertNextOnly = 0; - break; - case 'E': - convertCase = 0; - break; - default: - Swig_error("SWIG", Getline(s), "Unrecognized escape character '%c' in the replacement string \"%s\".\n", - *p, Char(subst)); - } - p++; - } - } - - return result; -} - -/* ----------------------------------------------------------------------------- - * Swig_string_regex() - * - * Executes a regular expression substitution. For example: - * - * Printf(stderr,"gsl%(regex:/GSL_(.*)_/\\1/)s", "GSL_Hello_") -> gslHello - * ----------------------------------------------------------------------------- */ -String *Swig_string_regex(String *s) { - const int pcre_options = 0; - - String *res = 0; - pcre2_code *compiled_pat = 0; - const char *input; - PCRE2_UCHAR pcre_error[256]; - int pcre_errornum; - size_t pcre_errorpos; - String *pattern = 0, *subst = 0; - size_t *captures = 0; - pcre2_match_data *match_data = 0; - if (split_regex_pattern_subst(s, &pattern, &subst, &input)) { - int rc; - - compiled_pat = pcre2_compile( - (PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, pcre_options, &pcre_errornum, &pcre_errorpos, NULL); - if (!compiled_pat) { - pcre2_get_error_message (pcre_errornum, pcre_error, sizeof pcre_error); - Swig_error("SWIG", Getline(s), "PCRE compilation failed: '%s' in '%s':%i.\n", - pcre_error, Char(pattern), pcre_errorpos); - Exit(EXIT_FAILURE); - } - match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL); - rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)input, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL); - captures = pcre2_get_ovector_pointer (match_data); - if (rc >= 0) { - res = replace_captures(rc, input, subst, captures, pattern, s); - } else if (rc != PCRE2_ERROR_NOMATCH) { - Swig_error("SWIG", Getline(s), "PCRE execution failed: error %d while matching \"%s\" using \"%s\".\n", - rc, Char(pattern), input); - Exit(EXIT_FAILURE); - } - } - - DohDelete(pattern); - DohDelete(subst); - pcre2_code_free(compiled_pat); - pcre2_match_data_free(match_data); - return res ? res : NewStringEmpty(); -} - -String *Swig_pcre_version(void) { - int len = pcre2_config(PCRE2_CONFIG_VERSION, NULL); - char *buf = Malloc(len); - String *result; - pcre2_config(PCRE2_CONFIG_VERSION, buf); - result = NewStringf("PCRE2 Version: %s", buf); - Free(buf); - return result; -} - -#else - -String *Swig_string_regex(String *s) { - Swig_error("SWIG", Getline(s), "PCRE regex support not enabled in this SWIG build.\n"); - Exit(EXIT_FAILURE); - return 0; -} - -String *Swig_pcre_version(void) { - return NewStringf("PCRE not used"); -} - -#endif - -/* ------------------------------------------------------------ - * Swig_is_generated_overload() - * Check if the function is an automatically generated - * overload created because a method has default parameters. - * ------------------------------------------------------------ */ -int Swig_is_generated_overload(Node *n) { - Node *base_method = Getattr(n, "sym:overloaded"); - Node *default_args = Getattr(n, "defaultargs"); - return ((base_method != NULL) && (default_args != NULL) && (base_method == default_args)); -} - -/* ----------------------------------------------------------------------------- - * Swig_init() - * - * Initialize the SWIG core - * ----------------------------------------------------------------------------- */ - -void Swig_init(void) { - /* Set some useful string encoding methods */ - DohEncoding("escape", Swig_string_escape); - DohEncoding("hexescape", Swig_string_hexescape); - DohEncoding("upper", Swig_string_upper); - DohEncoding("lower", Swig_string_lower); - DohEncoding("title", Swig_string_title); - DohEncoding("ctitle", Swig_string_ccase); - DohEncoding("lctitle", Swig_string_lccase); - DohEncoding("utitle", Swig_string_ucase); - DohEncoding("typecode", Swig_string_typecode); - DohEncoding("mangle", Swig_string_emangle); - DohEncoding("command", Swig_string_command); - DohEncoding("schemify", Swig_string_schemify); - DohEncoding("strip", Swig_string_strip); - DohEncoding("rstrip", Swig_string_rstrip); - DohEncoding("regex", Swig_string_regex); - - /* aliases for the case encoders */ - DohEncoding("uppercase", Swig_string_upper); - DohEncoding("lowercase", Swig_string_lower); - DohEncoding("camelcase", Swig_string_ccase); - DohEncoding("lowercamelcase", Swig_string_lccase); - DohEncoding("undercase", Swig_string_ucase); - DohEncoding("firstuppercase", Swig_string_first_upper); - DohEncoding("firstlowercase", Swig_string_first_lower); - - /* Initialize typemaps */ - Swig_typemap_init(); - - /* Initialize symbol table */ - Swig_symbol_init(); - - /* Initialize type system */ - SwigType_typesystem_init(); - - /* Initialize template system */ - SwigType_template_init(); -} diff --git a/contrib/tools/swig/Source/Swig/naming.c b/contrib/tools/swig/Source/Swig/naming.c deleted file mode 100644 index c4613f6c620..00000000000 --- a/contrib/tools/swig/Source/Swig/naming.c +++ /dev/null @@ -1,1771 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * naming.c - * - * Functions for generating various kinds of names during code generation. - * - * Swig_name_register is used to register a format string for generating names. - * The format string makes use of the following format specifiers: - * - * %c - class name is substituted - * %f - function name is substituted - * %m - member name is substituted - * %n - namespace is substituted - * %v - variable name is substituted - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "cparse.h" -#include <ctype.h> - -/* Hash table containing naming data */ - -static Hash *naming_hash = 0; - -#if 0 -#define SWIG_DEBUG -#endif - -/* ----------------------------------------------------------------------------- - * Swig_name_register() - * - * Register a new naming format. - * ----------------------------------------------------------------------------- */ - -void Swig_name_register(const_String_or_char_ptr method, const_String_or_char_ptr format) { - if (!naming_hash) - naming_hash = NewHash(); - Setattr(naming_hash, method, format); -} - -void Swig_name_unregister(const_String_or_char_ptr method) { - if (naming_hash) { - Delattr(naming_hash, method); - } -} - -/* Return naming format for the specified method or the default format if none was explicitly registered */ -static String* get_naming_format_for(const char *method, const char *def_format) { - String* f = naming_hash ? Getattr(naming_hash, method) : NULL; - - return f ? Copy(f) : NewString(def_format); -} - -static int name_mangle(String *r) { - char *c; - int special; - special = 0; - Replaceall(r, "::", "_"); - c = Char(r); - while (*c) { - if (!isalnum((int) *c) && (*c != '_')) { - special = 1; - switch (*c) { - case '+': - *c = 'a'; - break; - case '-': - *c = 's'; - break; - case '*': - *c = 'm'; - break; - case '/': - *c = 'd'; - break; - case '<': - *c = 'l'; - break; - case '>': - *c = 'g'; - break; - case '=': - *c = 'e'; - break; - case ',': - *c = 'c'; - break; - case '(': - *c = 'p'; - break; - case ')': - *c = 'P'; - break; - case '[': - *c = 'b'; - break; - case ']': - *c = 'B'; - break; - case '^': - *c = 'x'; - break; - case '&': - *c = 'A'; - break; - case '|': - *c = 'o'; - break; - case '~': - *c = 'n'; - break; - case '!': - *c = 'N'; - break; - case '%': - *c = 'M'; - break; - case '.': - *c = 'f'; - break; - case '?': - *c = 'q'; - break; - default: - *c = '_'; - break; - } - } - c++; - } - if (special) - Append(r, "___"); - return special; -} - -/* ----------------------------------------------------------------------------- - * replace_nspace() - * - * Mangles in the namespace from nspace by replacing %n in name if nspace feature required. - * ----------------------------------------------------------------------------- */ - -static void replace_nspace(String *name, const_String_or_char_ptr nspace) { - if (nspace) { - String *namspace = NewStringf("%s_", nspace); - Replaceall(namspace, NSPACE_SEPARATOR, "_"); - Replace(name, "%n", namspace, DOH_REPLACE_ANY); - Delete(namspace); - } else { - Replace(name, "%n", "", DOH_REPLACE_ANY); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_name_mangle() - * - * Converts all of the non-identifier characters of a string to underscores. - * ----------------------------------------------------------------------------- */ - -String *Swig_name_mangle(const_String_or_char_ptr s) { -#if 0 - String *r = NewString(s); - name_mangle(r); - return r; -#else - return Swig_string_mangle(s); -#endif -} - -/* ----------------------------------------------------------------------------- - * Swig_name_wrapper() - * - * Returns the name of a wrapper function. - * ----------------------------------------------------------------------------- */ - -String *Swig_name_wrapper(const_String_or_char_ptr fname) { - String *r = get_naming_format_for("wrapper", "_wrap_%f"); - - Replace(r, "%f", fname, DOH_REPLACE_ANY); - name_mangle(r); - return r; -} - - -/* ----------------------------------------------------------------------------- - * Swig_name_member() - * - * Returns the name of a class method. - * ----------------------------------------------------------------------------- */ - -String *Swig_name_member(const_String_or_char_ptr nspace, const_String_or_char_ptr classname, const_String_or_char_ptr membername) { - String *r; - String *rclassname; - char *cname; - - rclassname = SwigType_namestr(classname); - r = get_naming_format_for("member", "%n%c_%m"); - cname = Char(rclassname); - if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { - cname = strchr(cname, ' ') + 1; - } - replace_nspace(r, nspace); - Replace(r, "%c", cname, DOH_REPLACE_ANY); - Replace(r, "%m", membername, DOH_REPLACE_ANY); - /* name_mangle(r); */ - Delete(rclassname); - return r; -} - -/* ----------------------------------------------------------------------------- - * Swig_name_get() - * - * Returns the name of the accessor function used to get a variable. - * ----------------------------------------------------------------------------- */ - -String *Swig_name_get(const_String_or_char_ptr nspace, const_String_or_char_ptr vname) { - String *r = get_naming_format_for("get", "%n%v_get"); - -#ifdef SWIG_DEBUG - Printf(stdout, "Swig_name_get: '%s'\n", vname); -#endif - - replace_nspace(r, nspace); - Replace(r, "%v", vname, DOH_REPLACE_ANY); - /* name_mangle(r); */ - return r; -} - -/* ----------------------------------------------------------------------------- - * Swig_name_set() - * - * Returns the name of the accessor function used to set a variable. - * ----------------------------------------------------------------------------- */ - -String *Swig_name_set(const_String_or_char_ptr nspace, const_String_or_char_ptr vname) { - String *r = get_naming_format_for("set", "%n%v_set"); - - replace_nspace(r, nspace); - Replace(r, "%v", vname, DOH_REPLACE_ANY); - /* name_mangle(r); */ - return r; -} - -/* Common implementation of all Swig_name_<special-method>() functions below. */ -static String *make_full_name_for(const char *method, const char *def_format, const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { - String *r; - String *rclassname; - char *cname; - - rclassname = SwigType_namestr(classname); - r = get_naming_format_for(method, def_format); - - cname = Char(rclassname); - if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { - cname = strchr(cname, ' ') + 1; - } - - replace_nspace(r, nspace); - Replace(r, "%c", cname, DOH_REPLACE_ANY); - Delete(rclassname); - return r; -} - -/* ----------------------------------------------------------------------------- - * Swig_name_construct() - * - * Returns the name of the accessor function used to create an object. - * ----------------------------------------------------------------------------- */ - -String *Swig_name_construct(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { - return make_full_name_for("construct", "new_%n%c", nspace, classname); -} - - -/* ----------------------------------------------------------------------------- - * Swig_name_copyconstructor() - * - * Returns the name of the accessor function used to copy an object. - * ----------------------------------------------------------------------------- */ - -String *Swig_name_copyconstructor(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { - return make_full_name_for("copy", "copy_%n%c", nspace, classname); -} - -/* ----------------------------------------------------------------------------- - * Swig_name_destroy() - * - * Returns the name of the accessor function used to destroy an object. - * ----------------------------------------------------------------------------- */ - -String *Swig_name_destroy(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { - return make_full_name_for("destroy", "delete_%n%c", nspace, classname); -} - - -/* ----------------------------------------------------------------------------- - * Swig_name_disown() - * - * Returns the name of the accessor function used to disown an object. - * ----------------------------------------------------------------------------- */ - -String *Swig_name_disown(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { - return make_full_name_for("disown", "disown_%n%c", nspace, classname); -} - - -/* ----------------------------------------------------------------------------- - * Swig_name_object_set() - * - * Sets an object associated with a name and optional declarators. - * ----------------------------------------------------------------------------- */ - -void Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object) { - DOH *n; - -#ifdef SWIG_DEBUG - Printf(stdout, "Swig_name_object_set: '%s', '%s'\n", name, decl); -#endif - n = Getattr(namehash, name); - if (!n) { - n = NewHash(); - Setattr(namehash, name, n); - Delete(n); - } - /* Add an object based on the declarator value */ - if (!decl) { - Setattr(n, "start", object); - } else { - SwigType *cd = Copy(decl); - Setattr(n, cd, object); - Delete(cd); - } -} - - -/* ----------------------------------------------------------------------------- - * Swig_name_object_get() - * - * Return an object associated with an optional class prefix, name, and - * declarator. This function operates according to name matching rules - * described for the %rename directive in the SWIG manual. - * ----------------------------------------------------------------------------- */ - -static DOH *get_object(Hash *n, String *decl) { - DOH *rn = 0; - if (!n) - return 0; - if (decl) { - rn = Getattr(n, decl); - } else { - rn = Getattr(n, "start"); - } - return rn; -} - -static DOH *name_object_get(Hash *namehash, String *tname, SwigType *decl, SwigType *ncdecl) { - DOH *rn = 0; - Hash *n = Getattr(namehash, tname); - if (n) { - rn = get_object(n, decl); - if ((!rn) && ncdecl) - rn = get_object(n, ncdecl); - if (!rn) - rn = get_object(n, 0); - } - return rn; -} - -DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl) { - String *tname = NewStringEmpty(); - DOH *rn = 0; - char *ncdecl = 0; - - if (!namehash) - return 0; - - /* DB: This removed to more tightly control feature/name matching */ - /* if ((decl) && (SwigType_isqualifier(decl))) { - ncdecl = strchr(Char(decl),'.'); - ncdecl++; - } - */ -#ifdef SWIG_DEBUG - Printf(stdout, "Swig_name_object_get: '%s' '%s', '%s'\n", prefix, name, decl); -#endif - - - /* Perform a class-based lookup (if class prefix supplied) */ - if (prefix) { - if (Len(prefix)) { - Printf(tname, "%s::%s", prefix, name); - rn = name_object_get(namehash, tname, decl, ncdecl); - if (!rn) { - String *cls = Swig_scopename_last(prefix); - if (!Equal(cls, prefix)) { - Clear(tname); - Printf(tname, "*::%s::%s", cls, name); - rn = name_object_get(namehash, tname, decl, ncdecl); - } - Delete(cls); - } - /* Lookup a name within a templated-based class */ - if (!rn) { - String *t_name = SwigType_istemplate_templateprefix(prefix); - if (t_name) { - Clear(tname); - Printf(tname, "%s::%s", t_name, name); - rn = name_object_get(namehash, tname, decl, ncdecl); - Delete(t_name); - } - } - /* Lookup a template-based name within a class */ - if (!rn) { - String *t_name = SwigType_istemplate_templateprefix(name); - if (t_name) - rn = Swig_name_object_get(namehash, prefix, t_name, decl); - Delete(t_name); - } - } - /* A wildcard-based class lookup */ - if (!rn) { - Clear(tname); - Printf(tname, "*::%s", name); - rn = name_object_get(namehash, tname, decl, ncdecl); - } - } else { - /* Lookup in the global namespace only */ - Clear(tname); - Printf(tname, "::%s", name); - rn = name_object_get(namehash, tname, decl, ncdecl); - } - /* Catch-all */ - if (!rn) { - rn = name_object_get(namehash, name, decl, ncdecl); - } - if (!rn && Swig_scopename_check(name)) { - String *nprefix = 0; - String *nlast = 0; - Swig_scopename_split(name, &nprefix, &nlast); - rn = name_object_get(namehash, nlast, decl, ncdecl); - Delete(nlast); - Delete(nprefix); - } - - Delete(tname); - -#ifdef SWIG_DEBUG - Printf(stdout, "Swig_name_object_get: found %d\n", rn ? 1 : 0); -#endif - - return rn; -} - -/* ----------------------------------------------------------------------------- - * Swig_name_object_inherit() - * - * Implements name-based inheritance scheme. - * ----------------------------------------------------------------------------- */ - -void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) { - Iterator ki; - Hash *derh; - String *bprefix; - String *dprefix; - char *cbprefix; - int plen; - - if (!namehash) - return; - - /* Temporary hash holding all the entries we add while we iterate over - namehash itself as we can't modify the latter while iterating over it. */ - derh = NULL; - bprefix = NewStringf("%s::", base); - dprefix = NewStringf("%s::", derived); - cbprefix = Char(bprefix); - plen = (int)strlen(cbprefix); - for (ki = First(namehash); ki.key; ki = Next(ki)) { - char *k = Char(ki.key); - if (strncmp(k, cbprefix, plen) == 0) { - /* Copy, adjusting name, this element to the derived hash. */ - Iterator oi; - String *nkey = NewStringf("%s%s", dprefix, k + plen); - Hash *n = ki.item; - Hash *newh; - - /* Don't overwrite an existing value for the derived class, if any. */ - newh = Getattr(namehash, nkey); - if (!newh) { - if (!derh) - derh = NewHash(); - - newh = NewHash(); - Setattr(derh, nkey, newh); - Delete(newh); - } - for (oi = First(n); oi.key; oi = Next(oi)) { - if (!Getattr(newh, oi.key)) { - String *ci = Copy(oi.item); - Setattr(newh, oi.key, ci); - Delete(ci); - } - } - Delete(nkey); - } - } - - /* Merge the contents of derived hash into the main hash. */ - if (derh) { - for (ki = First(derh); ki.key; ki = Next(ki)) { - Setattr(namehash, ki.key, ki.item); - } - } - - Delete(bprefix); - Delete(dprefix); - Delete(derh); -} - -/* ----------------------------------------------------------------------------- - * merge_features() - * - * Given a hash, this function merges the features in the hash into the node. - * ----------------------------------------------------------------------------- */ - -static void merge_features(Hash *features, Node *n) { - Iterator ki; - - if (!features) - return; - for (ki = First(features); ki.key; ki = Next(ki)) { - String *ci = Copy(ki.item); - Setattr(n, ki.key, ci); - Delete(ci); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_features_get() - * - * Attaches any features in the features hash to the node that matches - * the declaration, decl. - * ----------------------------------------------------------------------------- */ - -static void features_get(Hash *features, const String *tname, SwigType *decl, SwigType *ncdecl, Node *node) { - Node *n = Getattr(features, tname); -#ifdef SWIG_DEBUG - Printf(stdout, " features_get: %s\n", tname); -#endif - if (n) { - merge_features(get_object(n, 0), node); - if (ncdecl) - merge_features(get_object(n, ncdecl), node); - merge_features(get_object(n, decl), node); - } -} - -void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) { - char *ncdecl = 0; - String *rdecl = 0; - String *rname = 0; - if (!features) - return; - - /* MM: This removed to more tightly control feature/name matching */ - /* - if ((decl) && (SwigType_isqualifier(decl))) { - ncdecl = strchr(Char(decl),'.'); - ncdecl++; - } - */ - - /* very specific hack for template constructors/destructors */ - if (name && SwigType_istemplate(name)) { - String *nodetype = nodeType(node); - if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) { - String *nprefix = 0; - String *nlast = 0; - String *tprefix; - Swig_scopename_split(name, &nprefix, &nlast); - tprefix = SwigType_templateprefix(nlast); - Delete(nlast); - if (Len(nprefix)) { - Append(nprefix, "::"); - Append(nprefix, tprefix); - Delete(tprefix); - rname = nprefix; - } else { - rname = tprefix; - Delete(nprefix); - } - rdecl = Copy(decl); - Replaceall(rdecl, name, rname); - decl = rdecl; - name = rname; - } - } - -#ifdef SWIG_DEBUG - Printf(stdout, "Swig_features_get: '%s' '%s' '%s'\n", prefix, name, decl); -#endif - - /* Global features */ - features_get(features, "", 0, 0, node); - if (name) { - String *tname = NewStringEmpty(); - /* add features for 'root' template */ - String *dname = SwigType_istemplate_templateprefix(name); - if (dname) { - features_get(features, dname, decl, ncdecl, node); - } - /* Catch-all */ - features_get(features, name, decl, ncdecl, node); - /* Perform a class-based lookup (if class prefix supplied) */ - if (prefix) { - /* A class-generic feature */ - if (Len(prefix)) { - Printf(tname, "%s::", prefix); - features_get(features, tname, decl, ncdecl, node); - } - /* A wildcard-based class lookup */ - Clear(tname); - Printf(tname, "*::%s", name); - features_get(features, tname, decl, ncdecl, node); - /* A specific class lookup */ - if (Len(prefix)) { - /* A template-based class lookup */ - String *tprefix = SwigType_istemplate_templateprefix(prefix); - if (tprefix) { - Clear(tname); - Printf(tname, "%s::%s", tprefix, name); - features_get(features, tname, decl, ncdecl, node); - } - Clear(tname); - Printf(tname, "%s::%s", prefix, name); - features_get(features, tname, decl, ncdecl, node); - Delete(tprefix); - } - } else { - /* Lookup in the global namespace only */ - Clear(tname); - Printf(tname, "::%s", name); - features_get(features, tname, decl, ncdecl, node); - } - Delete(tname); - Delete(dname); - } - if (name && SwigType_istemplate(name)) { - /* add features for complete template type */ - String *dname = Swig_symbol_template_deftype(name, 0); - if (!Equal(dname, name)) { - Swig_features_get(features, prefix, dname, decl, node); - } - Delete(dname); - } - - if (rname) - Delete(rname); - if (rdecl) - Delete(rdecl); -} - - -/* ----------------------------------------------------------------------------- - * Swig_feature_set() - * - * Sets a feature name and value. Also sets optional feature attributes as - * passed in by featureattribs. Optional feature attributes are given a full name - * concatenating the feature name plus ':' plus the attribute name. - * ----------------------------------------------------------------------------- */ - -void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, const_String_or_char_ptr value, Hash *featureattribs) { - Hash *n; - Hash *fhash; - -#ifdef SWIG_DEBUG - Printf(stdout, "Swig_feature_set: '%s' '%s' '%s' '%s'\n", name, decl, featurename, value); -#endif - - n = Getattr(features, name); - if (!n) { - n = NewHash(); - Setattr(features, name, n); - Delete(n); - } - if (!decl) { - fhash = Getattr(n, "start"); - if (!fhash) { - fhash = NewHash(); - Setattr(n, "start", fhash); - Delete(fhash); - } - } else { - fhash = Getattr(n, decl); - if (!fhash) { - String *cdecl_ = Copy(decl); - fhash = NewHash(); - Setattr(n, cdecl_, fhash); - Delete(cdecl_); - Delete(fhash); - } - } - if (value) { - Setattr(fhash, featurename, value); - } else { - Delattr(fhash, featurename); - } - - { - /* Add in the optional feature attributes */ - Hash *attribs = featureattribs; - while (attribs) { - String *attribname = Getattr(attribs, "name"); - String *featureattribname = NewStringf("%s:%s", featurename, attribname); - if (value) { - String *attribvalue = Getattr(attribs, "value"); - Setattr(fhash, featureattribname, attribvalue); - } else { - Delattr(fhash, featureattribname); - } - attribs = nextSibling(attribs); - Delete(featureattribname); - } - } - - if (name && SwigType_istemplate(name)) { - String *dname = Swig_symbol_template_deftype(name, 0); - if (Strcmp(dname, name)) { - Swig_feature_set(features, dname, decl, featurename, value, featureattribs); - } - Delete(dname); - } -} - -/* ----------------------------------------------------------------------------- - * The rename/namewarn engine - * - * Code below was in parser.y for a while - * ----------------------------------------------------------------------------- */ - -static Hash *namewarn_hash = 0; -static Hash *name_namewarn_hash(void) { - if (!namewarn_hash) - namewarn_hash = NewHash(); - return namewarn_hash; -} - -static Hash *rename_hash = 0; -static Hash *name_rename_hash(void) { - if (!rename_hash) - rename_hash = NewHash(); - return rename_hash; -} - -static List *namewarn_list = 0; -static List *name_namewarn_list(void) { - if (!namewarn_list) - namewarn_list = NewList(); - return namewarn_list; -} - -static List *rename_list = 0; -static List *name_rename_list(void) { - if (!rename_list) - rename_list = NewList(); - return rename_list; -} - -/* ----------------------------------------------------------------------------- - * int need_name_warning(Node *n) - * - * Detects if a node needs name warnings - * - * ----------------------------------------------------------------------------- */ - -static int need_name_warning(Node *n) { - int need = 1; - /* - We don't use name warnings for: - - class forwards, no symbol is generated at the target language. - - template declarations, only for real instances using %template(name). - - typedefs, have no effect at the target language. - - using declarations and using directives, have no effect at the target language. - */ - if (checkAttribute(n, "nodeType", "classforward")) { - need = 0; - } else if (checkAttribute(n, "nodeType", "using")) { - need = 0; - } else if (checkAttribute(n, "storage", "typedef")) { - need = 0; - } else if (Getattr(n, "hidden")) { - need = 0; - } else if (Getattr(n, "ignore")) { - need = 0; - } else if (Getattr(n, "templatetype")) { - need = 0; - } else if (GetFlag(n, "parsing_template_declaration")) { - need = 0; - } - return need; -} - -/* ----------------------------------------------------------------------------- - * int Swig_need_redefined_warn() - * - * Detects when a redefined object needs a warning - * - * ----------------------------------------------------------------------------- */ - -static int nodes_are_equivalent(Node *a, Node *b, int a_inclass) { - /* they must have the same type */ - String *ta = nodeType(a); - String *tb = nodeType(b); - if (!Equal(ta, tb)) { - if (!(Equal(ta, "using") && Equal(tb, "cdecl"))) { - return 0; - } - } - - if (Cmp(ta, "cdecl") == 0) { - /* both cdecl case */ - /* typedef */ - String *a_storage = Getattr(a, "storage"); - String *b_storage = Getattr(b, "storage"); - - if ((Cmp(a_storage, "typedef") == 0) - || (Cmp(b_storage, "typedef") == 0)) { - if (Cmp(a_storage, b_storage) == 0) { - String *a_type = (Getattr(a, "type")); - String *b_type = (Getattr(b, "type")); - if (Cmp(a_type, b_type) == 0) - return 1; - } - return 0; - } - - /* static functions */ - if (Swig_storage_isstatic(a) || Swig_storage_isstatic(b)) { - if (Cmp(a_storage, b_storage) != 0) - return 0; - } - - /* friend methods */ - - if (!a_inclass || (Cmp(a_storage, "friend") == 0)) { - /* check declaration */ - - String *a_decl = (Getattr(a, "decl")); - String *b_decl = (Getattr(b, "decl")); - if (Cmp(a_decl, b_decl) == 0) { - /* check return type */ - String *a_type = (Getattr(a, "type")); - String *b_type = (Getattr(b, "type")); - if (Cmp(a_type, b_type) == 0) { - /* check parameters */ - Parm *ap = (Getattr(a, "parms")); - Parm *bp = (Getattr(b, "parms")); - while (ap && bp) { - SwigType *at = Getattr(ap, "type"); - SwigType *bt = Getattr(bp, "type"); - if (Cmp(at, bt) != 0) - return 0; - ap = nextSibling(ap); - bp = nextSibling(bp); - } - if (ap || bp) { - return 0; - } else { - Node *a_template = Getattr(a, "template"); - Node *b_template = Getattr(b, "template"); - /* Not equivalent if one is a template instantiation (via %template) and the other is a non-templated function */ - if ((a_template && !b_template) || (!a_template && b_template)) - return 0; - } - return 1; - } - } - } - } else if (Equal(ta, "using")) { - /* using and cdecl case */ - String *b_storage = Getattr(b, "storage"); - if (Equal(b_storage, "typedef")) { - String *a_name = Getattr(a, "name"); - String *b_name = Getattr(b, "name"); - if (Equal(a_name, b_name)) - return 1; - } - } else { - /* both %constant case */ - String *a_storage = Getattr(a, "storage"); - String *b_storage = Getattr(b, "storage"); - if ((Cmp(a_storage, "%constant") == 0) - || (Cmp(b_storage, "%constant") == 0)) { - if (Cmp(a_storage, b_storage) == 0) { - String *a_type = (Getattr(a, "type")); - String *b_type = (Getattr(b, "type")); - if ((Cmp(a_type, b_type) == 0) - && (Cmp(Getattr(a, "value"), Getattr(b, "value")) == 0)) - return 1; - } - return 0; - } - if (Equal(ta, "template") && Equal(tb, "template")) { - if (Cmp(a_storage, "friend") == 0 || Cmp(b_storage, "friend") == 0) - return 1; - } - } - return 0; -} - -int Swig_need_redefined_warn(Node *a, Node *b, int InClass) { - String *a_name = Getattr(a, "name"); - String *b_name = Getattr(b, "name"); - String *a_symname = Getattr(a, "sym:name"); - String *b_symname = Getattr(b, "sym:name"); - /* always send a warning if a 'rename' is involved */ - if ((a_symname && !Equal(a_symname, a_name)) - || (b_symname && !Equal(b_symname, b_name))) { - if (!Equal(a_name, b_name)) { - return 1; - } - } - - - return !nodes_are_equivalent(a, b, InClass); -} - - -/* ----------------------------------------------------------------------------- - * int Swig_need_protected(Node* n) - * - * Detects when we need to fully register the protected member. - * This is basically any protected members when the allprotected mode is set. - * Otherwise we take just the protected virtual methods and non-static methods - * (potentially virtual methods) as well as constructors/destructors. - * Also any "using" statements in a class may potentially be virtual. - * ----------------------------------------------------------------------------- */ - -int Swig_need_protected(Node *n) { - String *nodetype = nodeType(n); - if (checkAttribute(n, "access", "protected")) { - if ((Equal(nodetype, "cdecl"))) { - if (Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode()) { - return 1; - } - if (SwigType_isfunction(Getattr(n, "decl"))) { - String *storage = Getattr(n, "storage"); - /* The function is declared virtual, or it has no storage. This eliminates typedef, static etc. */ - return !storage || Equal(storage, "virtual"); - } - } else if (Equal(nodetype, "constructor") || Equal(nodetype, "destructor")) { - return 1; - } else if (Equal(nodetype, "using") && !Getattr(n, "namespace")) { - return 1; - } - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * void name_nameobj_add() - * - * Add nameobj (rename/namewarn) - * - * ----------------------------------------------------------------------------- */ - -static List *make_attrlist(const char *ckey) { - List *list = NewList(); - const char *cattr = strchr(ckey, '$'); - if (cattr) { - String *nattr; - const char *rattr = strchr(++cattr, '$'); - while (rattr) { - nattr = NewStringWithSize(cattr, (int)(rattr - cattr)); - Append(list, nattr); - Delete(nattr); - cattr = rattr + 1; - rattr = strchr(cattr, '$'); - } - nattr = NewString(cattr); - Append(list, nattr); - Delete(nattr); - } else { - Append(list, "nodeType"); - } - return list; -} - -static void name_object_attach_keys(const char *keys[], Hash *nameobj) { - Node *kw = nextSibling(nameobj); - List *matchlist = 0; - while (kw) { - Node *next = nextSibling(kw); - String *kname = Getattr(kw, "name"); - char *ckey = kname ? Char(kname) : 0; - if (ckey) { - const char **rkey; - int isnotmatch = 0; - int isregexmatch = 0; - if ((strncmp(ckey, "match", 5) == 0) - || (isnotmatch = (strncmp(ckey, "notmatch", 8) == 0)) - || (isregexmatch = (strncmp(ckey, "regexmatch", 10) == 0)) - || (isnotmatch = isregexmatch = (strncmp(ckey, "notregexmatch", 13) == 0))) { - Hash *mi = NewHash(); - List *attrlist = make_attrlist(ckey); - if (!matchlist) - matchlist = NewList(); - Setattr(mi, "value", Getattr(kw, "value")); - Setattr(mi, "attrlist", attrlist); - if (isnotmatch) - SetFlag(mi, "notmatch"); - if (isregexmatch) - SetFlag(mi, "regexmatch"); - Delete(attrlist); - Append(matchlist, mi); - Delete(mi); - removeNode(kw); - } else { - for (rkey = keys; *rkey != 0; ++rkey) { - if (strcmp(ckey, *rkey) == 0) { - Setattr(nameobj, *rkey, Getattr(kw, "value")); - removeNode(kw); - } - } - } - } - kw = next; - } - if (matchlist) { - Setattr(nameobj, "matchlist", matchlist); - Delete(matchlist); - } -} - -static void name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, String *name, SwigType *decl, Hash *nameobj) { - String *nname = 0; - if (name && Len(name)) { - String *target_fmt = Getattr(nameobj, "targetfmt"); - nname = prefix ? NewStringf("%s::%s", prefix, name) : NewString(name); - if (target_fmt) { - String *tmp = NewStringf(target_fmt, nname); - Delete(nname); - nname = tmp; - } - } - - if (!nname || !Len(nname) || Getattr(nameobj, "fullname") || /* any of these options trigger a 'list' nameobj */ - Getattr(nameobj, "sourcefmt") || Getattr(nameobj, "matchlist") || Getattr(nameobj, "regextarget")) { - if (decl) - Setattr(nameobj, "decl", decl); - if (nname && Len(nname)) - Setattr(nameobj, "targetname", nname); - /* put the new nameobj at the beginning of the list, such that the - last inserted rule take precedence */ - Insert(name_list, 0, nameobj); - } else { - /* here we add an old 'hash' nameobj, simple and fast */ - Swig_name_object_set(name_hash, nname, decl, nameobj); - } - Delete(nname); -} - -/* ----------------------------------------------------------------------------- - * int name_match_nameobj() - * - * Apply and check the nameobj's math list to the node - * - * ----------------------------------------------------------------------------- */ - -static DOH *get_lattr(Node *n, List *lattr) { - DOH *res = 0; - int ilen = Len(lattr); - int i; - for (i = 0; n && (i < ilen); ++i) { - String *nattr = Getitem(lattr, i); - res = Getattr(n, nattr); -#ifdef SWIG_DEBUG - if (!res) { - Printf(stdout, "missing %s %s %s\n", nattr, Getattr(n, "name"), Getattr(n, "member")); - } else { - Printf(stdout, "lattr %d %s %s\n", i, nattr, DohIsString(res) ? res : Getattr(res, "name")); - } -#endif - n = res; - } - return res; -} - -#ifdef HAVE_PCRE -#define PCRE2_CODE_UNIT_WIDTH 8 -#include <pcre2.h> - -static int name_regexmatch_value(Node *n, String *pattern, String *s) { - pcre2_code *compiled_pat; - PCRE2_UCHAR err[256]; - int errornum; - size_t errpos; - int rc; - pcre2_match_data *match_data = 0; - - compiled_pat = pcre2_compile((PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, 0, &errornum, &errpos, NULL); - if (!compiled_pat) { - pcre2_get_error_message (errornum, err, sizeof err); - Swig_error("SWIG", Getline(n), - "Invalid regex \"%s\": compilation failed at %d: %s\n", - Char(pattern), errpos, err); - Exit(EXIT_FAILURE); - } - - match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL); - rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)Char(s), PCRE2_ZERO_TERMINATED, 0, 0, match_data, 0); - pcre2_code_free(compiled_pat); - pcre2_match_data_free(match_data); - - if (rc == PCRE2_ERROR_NOMATCH) - return 0; - - if (rc < 0 ) { - Swig_error("SWIG", Getline(n), - "Matching \"%s\" against regex \"%s\" failed: %d\n", - Char(s), Char(pattern), rc); - Exit(EXIT_FAILURE); - } - - return 1; -} - -#else /* !HAVE_PCRE */ - -static int name_regexmatch_value(Node *n, String *pattern, String *s) { - (void)pattern; - (void)s; - Swig_error("SWIG", Getline(n), - "PCRE regex matching is not available in this SWIG build.\n"); - Exit(EXIT_FAILURE); - return 0; -} - -#endif /* HAVE_PCRE/!HAVE_PCRE */ - -static int name_match_value(String *mvalue, String *value) { -#if defined(SWIG_USE_SIMPLE_MATCHOR) - int match = 0; - char *cvalue = Char(value); - char *cmvalue = Char(mvalue); - char *sep = strchr(cmvalue, '|'); - while (sep && !match) { - match = strncmp(cvalue, cmvalue, sep - cmvalue) == 0; -#ifdef SWIG_DEBUG - Printf(stdout, "match_value: %s %s %d\n", cvalue, cmvalue, match); -#endif - cmvalue = sep + 1; - sep = strchr(cmvalue, '|'); - } - if (!match) { - match = strcmp(cvalue, cmvalue) == 0; -#ifdef SWIG_DEBUG - Printf(stdout, "match_value: %s %s %d\n", cvalue, cmvalue, match); -#endif - } - return match; -#else - return Equal(mvalue, value); -#endif -} - -static int name_match_nameobj(Hash *rn, Node *n) { - int match = 1; - List *matchlist = Getattr(rn, "matchlist"); -#ifdef SWIG_DEBUG - Printf(stdout, "name_match_nameobj: %s\n", Getattr(n, "name")); -#endif - if (matchlist) { - int ilen = Len(matchlist); - int i; - for (i = 0; match && (i < ilen); ++i) { - Node *mi = Getitem(matchlist, i); - List *lattr = Getattr(mi, "attrlist"); - String *nval = get_lattr(n, lattr); - int notmatch = GetFlag(mi, "notmatch"); - int regexmatch = GetFlag(mi, "regexmatch"); - match = 0; - if (nval) { - String *kwval = Getattr(mi, "value"); - match = regexmatch ? name_regexmatch_value(n, kwval, nval) - : name_match_value(kwval, nval); -#ifdef SWIG_DEBUG - Printf(stdout, "val %s %s %d %d \n", nval, kwval, match, ilen); -#endif - } - if (notmatch) - match = !match; - } - } -#ifdef SWIG_DEBUG - Printf(stdout, "name_match_nameobj: %d\n", match); -#endif - return match; -} - -/* ----------------------------------------------------------------------------- - * Hash *name_nameobj_lget() - * - * Get a nameobj (rename/namewarn) from the list of filters - * - * ----------------------------------------------------------------------------- */ - -static Hash *name_nameobj_lget(List *namelist, Node *n, String *prefix, String *name, String *decl) { - Hash *res = 0; - if (namelist) { - int len = Len(namelist); - int i; - int match = 0; - for (i = 0; !match && (i < len); i++) { - Hash *rn = Getitem(namelist, i); - String *rdecl = Getattr(rn, "decl"); - if (rdecl && (!decl || !Equal(rdecl, decl))) { - continue; - } else if (name_match_nameobj(rn, n)) { - String *tname = Getattr(rn, "targetname"); - if (tname) { - String *sfmt = Getattr(rn, "sourcefmt"); - String *sname = 0; - int fullname = GetFlag(rn, "fullname"); - int regextarget = GetFlag(rn, "regextarget"); - if (sfmt) { - if (fullname && prefix) { - String *pname = NewStringf("%s::%s", prefix, name); - sname = NewStringf(sfmt, pname); - Delete(pname); - } else { - sname = NewStringf(sfmt, name); - } - } else { - if (fullname && prefix) { - sname = NewStringf("%s::%s", prefix, name); - } else { - sname = name; - DohIncref(name); - } - } - match = regextarget ? name_regexmatch_value(n, tname, sname) - : name_match_value(tname, sname); - Delete(sname); - } else { - /* Applying the renaming rule may fail if it contains a %(regex)s expression that doesn't match the given name. */ - String *sname = NewStringf(Getattr(rn, "name"), name); - if (sname) { - if (Len(sname)) - match = 1; - Delete(sname); - } - } - } - if (match) { - res = rn; - break; - } - } - } - return res; -} - -/* ----------------------------------------------------------------------------- - * Swig_name_namewarn_add - * - * Add a namewarn objects - * - * ----------------------------------------------------------------------------- */ - -void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn) { - const char *namewrn_keys[] = { "rename", "error", "fullname", "sourcefmt", "targetfmt", 0 }; - name_object_attach_keys(namewrn_keys, namewrn); - name_nameobj_add(name_namewarn_hash(), name_namewarn_list(), prefix, name, decl, namewrn); -} - -/* ----------------------------------------------------------------------------- - * Hash *name_namewarn_get() - * - * Return the namewarn object, if there is one. - * - * ----------------------------------------------------------------------------- */ - -static Hash *name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl) { - if (!namewarn_hash && !namewarn_list) - return 0; - if (n) { - /* Return in the obvious cases */ - if (!name || !need_name_warning(n)) { - return 0; - } else { - String *access = Getattr(n, "access"); - int is_public = !access || Equal(access, "public"); - if (!is_public && !Swig_need_protected(n)) { - return 0; - } - } - } - if (name) { - /* Check to see if the name is in the hash */ - Hash *wrn = Swig_name_object_get(name_namewarn_hash(), prefix, name, decl); - if (wrn && !name_match_nameobj(wrn, n)) - wrn = 0; - if (!wrn) { - wrn = name_nameobj_lget(name_namewarn_list(), n, prefix, name, decl); - } - if (wrn && Getattr(wrn, "error")) { - if (n) { - Swig_error(Getfile(n), Getline(n), "%s\n", Getattr(wrn, "name")); - } else { - Swig_error(cparse_file, cparse_line, "%s\n", Getattr(wrn, "name")); - } - } - return wrn; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * String *Swig_name_warning() - * - * Return the name warning, if there is one. - * - * ----------------------------------------------------------------------------- */ - -String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl) { - Hash *wrn = name_namewarn_get(n, prefix, name, decl); - return (name && wrn) ? Getattr(wrn, "name") : 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_name_rename_add() - * - * Manage the rename objects - * - * ----------------------------------------------------------------------------- */ - -static void single_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname) { - name_nameobj_add(name_rename_hash(), name_rename_list(), prefix, name, decl, newname); -} - -/* Add a new rename. Works much like new_feature including default argument handling. */ -void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname, ParmList *declaratorparms) { - - ParmList *declparms = declaratorparms; - - const char *rename_keys[] = { "fullname", "sourcefmt", "targetfmt", "continue", "regextarget", 0 }; - name_object_attach_keys(rename_keys, newname); - - /* Add the name */ - single_rename_add(prefix, name, decl, newname); - - /* Add extra names if there are default parameters in the parameter list */ - if (decl) { - int constqualifier = SwigType_isconst(decl); - while (declparms) { - if (ParmList_has_defaultargs(declparms)) { - - /* Create a parameter list for the new rename by copying all - but the last (defaulted) parameter */ - ParmList *newparms = CopyParmListMax(declparms,ParmList_len(declparms)-1); - - /* Create new declaration - with the last parameter removed */ - SwigType *newdecl = Copy(decl); - Delete(SwigType_pop_function(newdecl)); /* remove the old parameter list from newdecl */ - SwigType_add_function(newdecl, newparms); - if (constqualifier) - SwigType_add_qualifier(newdecl, "const"); - - single_rename_add(prefix, name, newdecl, newname); - declparms = newparms; - Delete(newdecl); - } else { - declparms = 0; - } - } - } -} - - -/* Create a name for the given node applying rename/namewarn if needed */ -static String *apply_rename(Node* n, String *newname, int fullname, String *prefix, String *name) { - String *result = 0; - if (newname && Len(newname)) { - if (Strcmp(newname, "$ignore") == 0) { - /* $ignore doesn't apply to parameters and while it's rare to explicitly write %ignore directives for them they could be caught by a wildcard ignore using - regex match, just ignore the attempt to ignore them in this case */ - if (!Equal(nodeType(n), "parm")) - result = Copy(newname); - } else { - char *cnewname = Char(newname); - if (cnewname) { - int destructor = name && (*(Char(name)) == '~'); - String *fmt = newname; - /* use name as a fmt, but avoid C++ "%" and "%=" operators */ - if (Len(newname) > 1 && strchr(cnewname, '%') && !(strcmp(cnewname, "%=") == 0)) { - if (fullname && prefix) { - result = NewStringf(fmt, prefix, name); - } else { - result = NewStringf(fmt, name); - } - } else { - result = Copy(newname); - } - if (destructor && result && (*(Char(result)) != '~')) { - Insert(result, 0, "~"); - } - } - } - } - - return result; -} - -/* ----------------------------------------------------------------------------- - * String *Swig_name_make() - * - * Make a name after applying all the rename/namewarn objects - * - * ----------------------------------------------------------------------------- */ - -String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, SwigType *decl, String *oldname) { - String *nname = 0; - String *result = 0; - String *name = NewString(cname); - Hash *wrn = 0; - String *rdecl = 0; - String *rname = 0; - - /* very specific hack for template constructors/destructors */ -#ifdef SWIG_DEBUG - Printf(stdout, "Swig_name_make: looking for %s %s %s %s\n", prefix, name, decl, oldname); -#endif - - if (name && n && SwigType_istemplate(name)) { - String *nodetype = nodeType(n); - if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) { - String *nprefix = 0; - String *nlast = 0; - String *tprefix; - Swig_scopename_split(name, &nprefix, &nlast); - tprefix = SwigType_templateprefix(nlast); - Delete(nlast); - if (Len(nprefix)) { - Append(nprefix, "::"); - Append(nprefix, tprefix); - Delete(tprefix); - rname = nprefix; - } else { - rname = tprefix; - Delete(nprefix); - } - rdecl = Copy(decl); - Replaceall(rdecl, name, rname); -#ifdef SWIG_DEBUG - Printf(stdout, "SWIG_name_make: use new name %s %s : %s %s\n", name, decl, rname, rdecl); -#endif - decl = rdecl; - Delete(name); - name = rname; - } - } - - if (rename_hash || rename_list || namewarn_hash || namewarn_list) { - Hash *rn = Swig_name_object_get(name_rename_hash(), prefix, name, decl); - if (!rn || !name_match_nameobj(rn, n)) { - rn = name_nameobj_lget(name_rename_list(), n, prefix, name, decl); - if (rn) { - String *sfmt = Getattr(rn, "sourcefmt"); - int fullname = GetFlag(rn, "fullname"); - if (fullname && prefix) { - String *sname = NewStringf("%s::%s", prefix, name); - Delete(name); - name = sname; - prefix = 0; - } - if (sfmt) { - String *sname = NewStringf(sfmt, name); - Delete(name); - name = sname; - } - } - } - if (rn) { - String *newname = Getattr(rn, "name"); - int fullname = GetFlag(rn, "fullname"); - result = apply_rename(n, newname, fullname, prefix, name); - } - if (result && !Equal(result, name)) { - /* operators in C++ allow aliases, we look for them */ - char *cresult = Char(result); - if (cresult && (strncmp(cresult, "operator ", 9) == 0)) { - String *nresult = Swig_name_make(n, prefix, result, decl, oldname); - if (!Equal(nresult, result)) { - Delete(result); - result = nresult; - } else { - Delete(nresult); - } - } - } - nname = result ? result : name; - wrn = name_namewarn_get(n, prefix, nname, decl); - if (wrn) { - String *rename = Getattr(wrn, "rename"); - if (rename) { - String *msg = Getattr(wrn, "name"); - int fullname = GetFlag(wrn, "fullname"); - if (result) - Delete(result); - result = apply_rename(n, rename, fullname, prefix, name); - if ((msg) && (Len(msg))) { - if (!Getmeta(nname, "already_warned")) { - String* suffix = 0; - if (Strcmp(result, "$ignore") == 0) { - suffix = NewStringf(": ignoring '%s'\n", name); - } else if (Strcmp(result, name) != 0) { - suffix = NewStringf(", renaming to '%s'\n", result); - } else { - /* No rename was performed */ - suffix = NewString("\n"); - } - if (n) { - /* Parameter renaming is not fully implemented. Mainly because there is no C/C++ syntax to - * for %rename to fully qualify a function's parameter name from outside the function. Hence it - * is not possible to implemented targeted warning suppression on one parameter in one function. */ - int suppress_parameter_rename_warning = Equal(nodeType(n), "parm"); - if (!suppress_parameter_rename_warning) { - SWIG_WARN_NODE_BEGIN(n); - Swig_warning(0, Getfile(n), Getline(n), "%s%s", msg, suffix); - SWIG_WARN_NODE_END(n); - } - } else { - Swig_warning(0, Getfile(name), Getline(name), "%s%s", msg, suffix); - } - Setmeta(nname, "already_warned", "1"); - Delete(suffix); - } - } - } - } - } - if (!result || !Len(result)) { - if (result) - Delete(result); - if (oldname) { - result = NewString(oldname); - } else { - result = NewString(cname); - } - } - Delete(name); - -#ifdef SWIG_DEBUG - Printf(stdout, "Swig_name_make: result '%s' '%s'\n", cname, result); -#endif - - return result; -} - -/* ----------------------------------------------------------------------------- - * void Swig_name_inherit() - * - * Inherit namewarn, rename, and feature objects - * - * ----------------------------------------------------------------------------- */ - -void Swig_name_inherit(String *base, String *derived) { - /* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */ - Swig_name_object_inherit(name_rename_hash(), base, derived); - Swig_name_object_inherit(name_namewarn_hash(), base, derived); - Swig_name_object_inherit(Swig_cparse_features(), base, derived); -} - -/* ----------------------------------------------------------------------------- - * Swig_inherit_base_symbols() - * ----------------------------------------------------------------------------- */ - -void Swig_inherit_base_symbols(List *bases) { - if (bases) { - Iterator s; - for (s = First(bases); s.item; s = Next(s)) { - Symtab *st = Getattr(s.item, "symtab"); - if (st) { - Setfile(st, Getfile(s.item)); - Setline(st, Getline(s.item)); - Swig_symbol_inherit(st); - } - } - Delete(bases); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_make_inherit_list() - * ----------------------------------------------------------------------------- */ - -List *Swig_make_inherit_list(String *clsname, List *names, String *Namespaceprefix) { - int i, ilen; - String *derived; - List *bases = NewList(); - - if (Namespaceprefix) - derived = NewStringf("%s::%s", Namespaceprefix, clsname); - else - derived = NewString(clsname); - - ilen = Len(names); - for (i = 0; i < ilen; i++) { - String *base; - String *n = Getitem(names, i); - /* Try to figure out where this symbol is */ - Node *s = Swig_symbol_clookup(n, 0); - if (s) { - while (s && (Strcmp(nodeType(s), "class") != 0)) { - /* Not a class. Could be a typedef though. */ - String *storage = Getattr(s, "storage"); - if (storage && (Strcmp(storage, "typedef") == 0)) { - String *nn = Getattr(s, "type"); - s = Swig_symbol_clookup(nn, Getattr(s, "sym:symtab")); - } else { - break; - } - } - if (s && ((Strcmp(nodeType(s), "class") == 0) || (Strcmp(nodeType(s), "template") == 0))) { - String *q = Swig_symbol_qualified(s); - Append(bases, s); - if (q) { - base = NewStringf("%s::%s", q, Getattr(s, "name")); - Delete(q); - } else { - base = NewString(Getattr(s, "name")); - } - } else { - base = NewString(n); - } - } else { - base = NewString(n); - } - if (base) { - Swig_name_inherit(base, derived); - Delete(base); - } - } - return bases; -} - - -/* ----------------------------------------------------------------------------- - * void Swig_name_str() - * - * Return a stringified version of a C/C++ symbol from a node. - * The node passed in is expected to be a function, constructor, destructor or - * variable. Some example return values: - * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate" - * "MyNameSpace::ABC::ABC" - * "MyNameSpace::ABC::constmethod" - * "MyNameSpace::ABC::variablename" - * - * ----------------------------------------------------------------------------- */ - -String *Swig_name_str(Node *n) { - String *qname; - String *qualifier = Swig_symbol_qualified(n); - String *name = Swig_scopename_last(Getattr(n, "name")); - if (qualifier) - qualifier = SwigType_namestr(qualifier); - - /* Very specific hack for template constructors/destructors */ - if (SwigType_istemplate(name)) { - String *nodetype = nodeType(n); - if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) { - String *nprefix = 0; - String *nlast = 0; - String *tprefix; - Swig_scopename_split(name, &nprefix, &nlast); - tprefix = SwigType_templateprefix(nlast); - Delete(nlast); - Delete(nprefix); - Delete(name); - name = tprefix; - } - } - - qname = NewString(""); - if (qualifier && Len(qualifier) > 0) - Printf(qname, "%s::", qualifier); - Printf(qname, "%s", SwigType_str(name, 0)); - - Delete(name); - Delete(qualifier); - - return qname; -} - -/* ----------------------------------------------------------------------------- - * void Swig_name_decl() - * - * Return a stringified version of a C/C++ declaration without the return type. - * The node passed in is expected to be a function, constructor, destructor or - * variable. Some example return values: - * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()" - * "MyNameSpace::ABC::ABC(int,double)" - * "MyNameSpace::ABC::constmethod(int) const" - * "MyNameSpace::ABC::refqualifiermethod(int) const &" - * "MyNameSpace::ABC::variablename" - * - * ----------------------------------------------------------------------------- */ - -String *Swig_name_decl(Node *n) { - String *qname; - String *decl; - - qname = Swig_name_str(n); - decl = NewStringf("%s", qname); - - if (!checkAttribute(n, "kind", "variable")) { - String *d = Getattr(n, "decl"); - Printv(decl, "(", ParmList_errorstr(Getattr(n, "parms")), ")", NIL); - if (SwigType_isfunction(d)) { - SwigType *decl_temp = Copy(d); - SwigType *qualifiers = SwigType_pop_function_qualifiers(decl_temp); - if (qualifiers) { - String *qualifiers_string = SwigType_str(qualifiers, 0); - Printv(decl, " ", qualifiers_string, NIL); - Delete(qualifiers_string); - } - Delete(decl_temp); - } - } - - Delete(qname); - - return decl; -} - -/* ----------------------------------------------------------------------------- - * void Swig_name_fulldecl() - * - * Return a stringified version of a C/C++ declaration including the return type. - * The node passed in is expected to be a function, constructor or destructor. - * Some example return values: - * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()" - * "MyNameSpace::ABC::ABC(int,double)" - * "int * MyNameSpace::ABC::constmethod(int) const" - * - * ----------------------------------------------------------------------------- */ - -String *Swig_name_fulldecl(Node *n) { - String *decl = Swig_name_decl(n); - String *type = Getattr(n, "type"); - String *nodetype = nodeType(n); - String *fulldecl; - /* add on the return type */ - if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) { - fulldecl = decl; - } else { - String *t = SwigType_str(type, 0); - fulldecl = NewStringf("%s %s", t, decl); - Delete(decl); - Delete(t); - } - return fulldecl; -} - diff --git a/contrib/tools/swig/Source/Swig/parms.c b/contrib/tools/swig/Source/Swig/parms.c deleted file mode 100644 index 11071ce0cdd..00000000000 --- a/contrib/tools/swig/Source/Swig/parms.c +++ /dev/null @@ -1,272 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * parms.c - * - * Parameter list class. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" - -/* ------------------------------------------------------------------------ - * NewParm() - * - * Create a new parameter from datatype 'type' and name 'name' copying - * the file and line number from the Node from_node. - * ------------------------------------------------------------------------ */ - -Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *from_node) { - Parm *p = NewParmWithoutFileLineInfo(type, name); - Setfile(p, Getfile(from_node)); - Setline(p, Getline(from_node)); - return p; -} - -/* ------------------------------------------------------------------------ - * NewParmWithoutFileLineInfo() - * - * Create a new parameter from datatype 'type' and name 'name' without any - * file / line numbering information. - * ------------------------------------------------------------------------ */ - -Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name) { - Parm *p = NewHash(); - set_nodeType(p, "parm"); - if (type) { - SwigType *ntype = Copy(type); - Setattr(p, "type", ntype); - Delete(ntype); - } - Setattr(p, "name", name); - return p; -} - -/* ------------------------------------------------------------------------ - * NewParmNode() - * - * Create a new parameter from datatype 'type' and name and symbol table as - * well as file and line number from the 'from_node'. - * The resulting Parm will be similar to a Node used for typemap lookups. - * ------------------------------------------------------------------------ */ - -Parm *NewParmNode(SwigType *type, Node *from_node) { - Parm *p = NewParm(type, Getattr(from_node, "name"), from_node); - Setattr(p, "sym:symtab", Getattr(from_node, "sym:symtab")); - return p; -} - -/* ------------------------------------------------------------------------ - * CopyParm() - * ------------------------------------------------------------------------ */ - -Parm *CopyParm(Parm *p) { - Parm *np = NewHash(); - Iterator ki; - for (ki = First(p); ki.key; ki = Next(ki)) { - if (DohIsString(ki.item)) { - DOH *c = Copy(ki.item); - Setattr(np,ki.key,c); - Delete(c); - } - } - Setfile(np, Getfile(p)); - Setline(np, Getline(p)); - return np; -} - -/* ------------------------------------------------------------------ - * CopyParmListMax() - * CopyParmList() - * ------------------------------------------------------------------ */ - -ParmList *CopyParmListMax(ParmList *p, int count) { - Parm *np; - Parm *pp = 0; - Parm *fp = 0; - - if (!p) - return 0; - - while (p) { - if (count == 0) break; - np = CopyParm(p); - if (pp) { - set_nextSibling(pp, np); - Delete(np); - } else { - fp = np; - } - pp = np; - p = nextSibling(p); - count--; - } - return fp; -} - -ParmList *CopyParmList(ParmList *p) { - return CopyParmListMax(p,-1); -} - -/* ----------------------------------------------------------------------------- - * int ParmList_numrequired(). Return number of required arguments - * ----------------------------------------------------------------------------- */ - -int ParmList_numrequired(ParmList *p) { - int i = 0; - while (p) { - SwigType *t = Getattr(p, "type"); - String *value = Getattr(p, "value"); - if (value) - return i; - if (!(SwigType_type(t) == T_VOID)) - i++; - else - break; - p = nextSibling(p); - } - return i; -} - -/* ----------------------------------------------------------------------------- - * int ParmList_len() - * ----------------------------------------------------------------------------- */ - -int ParmList_len(ParmList *p) { - int i = 0; - while (p) { - i++; - p = nextSibling(p); - } - return i; -} - -/* --------------------------------------------------------------------- - * get_empty_type() - * ---------------------------------------------------------------------- */ - -static SwigType *get_empty_type(void) { - return NewStringEmpty(); -} - -/* --------------------------------------------------------------------- - * ParmList_str() - * - * Generates a string of parameters - * ---------------------------------------------------------------------- */ - -String *ParmList_str(ParmList *p) { - String *out = NewStringEmpty(); - while (p) { - String *type = Getattr(p, "type"); - String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name")); - Append(out, pstr); - p = nextSibling(p); - if (p) { - Append(out, ","); - } - Delete(pstr); - } - return out; -} - -/* --------------------------------------------------------------------- - * ParmList_str_defaultargs() - * - * Generates a string of parameters including default arguments - * ---------------------------------------------------------------------- */ - -String *ParmList_str_defaultargs(ParmList *p) { - String *out = NewStringEmpty(); - while (p) { - String *value = Getattr(p, "value"); - String *type = Getattr(p, "type"); - String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name")); - Append(out, pstr); - if (value) { - Printf(out, "=%s", value); - } - p = nextSibling(p); - if (p) { - Append(out, ","); - } - Delete(pstr); - } - return out; -} - -/* ----------------------------------------------------------------------------- - * ParmList_str_multibrackets() - * - * Generates a string of parameters including default arguments adding brackets - * if more than one parameter - * ----------------------------------------------------------------------------- */ - -String *ParmList_str_multibrackets(ParmList *p) { - String *out; - String *parm_str = ParmList_str_defaultargs(p); - if (ParmList_len(p) > 1) - out = NewStringf("(%s)", parm_str); - else - out = NewStringf("%s", parm_str); - Delete(parm_str); - return out; -} - -/* --------------------------------------------------------------------- - * ParmList_protostr() - * - * Generate a prototype string. - * ---------------------------------------------------------------------- */ - -String *ParmList_protostr(ParmList *p) { - String *out = NewStringEmpty(); - while (p) { - String *type = Getattr(p, "type"); - String *pstr = SwigType_str(type ? type : get_empty_type(), 0); - Append(out, pstr); - p = nextSibling(p); - if (p) { - Append(out, ","); - } - Delete(pstr); - } - return out; -} - -/* --------------------------------------------------------------------- - * ParmList_has_defaultargs() - * - * Returns 1 if the parameter list passed in is has one or more default - * arguments. Otherwise returns 0. - * ---------------------------------------------------------------------- */ - -int ParmList_has_defaultargs(ParmList *p) { - while (p) { - if (Getattr(p, "value")) { - return 1; - } - p = nextSibling(p); - } - return 0; -} - -/* --------------------------------------------------------------------- - * ParmList_has_varargs() - * - * Returns 1 if the parameter list passed in has varargs. - * Otherwise returns 0. - * ---------------------------------------------------------------------- */ - -int ParmList_has_varargs(ParmList *p) { - Parm *lp = 0; - while (p) { - lp = p; - p = nextSibling(p); - } - return lp ? SwigType_isvarargs(Getattr(lp, "type")) : 0; -} diff --git a/contrib/tools/swig/Source/Swig/scanner.c b/contrib/tools/swig/Source/Swig/scanner.c deleted file mode 100644 index 9dbb3536480..00000000000 --- a/contrib/tools/swig/Source/Swig/scanner.c +++ /dev/null @@ -1,1898 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * scanner.c - * - * This file implements a general purpose C/C++ compatible lexical scanner. - * This scanner isn't intended to be plugged directly into a parser built - * with yacc. Rather, it contains a lot of generic code that could be used - * to easily construct yacc-compatible scanners. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include <ctype.h> - -extern String *cparse_file; -extern int cparse_line; -extern int cparse_cplusplus; -extern int cparse_start_line; - -struct Scanner { - String *text; /* Current token value */ - List *scanobjs; /* Objects being scanned */ - String *str; /* Current object being scanned */ - char *idstart; /* Optional identifier start characters */ - int nexttoken; /* Next token to be returned */ - int start_line; /* Starting line of certain declarations */ - int line; - int yylen; /* Length of text pushed into text */ - String *file; - String *error; /* Last error message (if any) */ - int error_line; /* Error line number */ - int freeze_line; /* Suspend line number updates */ - List *brackets; /* Current level of < > brackets on each level */ -}; - -typedef struct Locator { - String *filename; - int line_number; - struct Locator *next; -} Locator; -static int follow_locators = 0; - -static void brackets_push(Scanner *); -static void brackets_clear(Scanner *); - -/* ----------------------------------------------------------------------------- - * NewScanner() - * - * Create a new scanner object - * ----------------------------------------------------------------------------- */ - -Scanner *NewScanner(void) { - Scanner *s; - s = (Scanner *) Malloc(sizeof(Scanner)); - s->line = 1; - s->file = 0; - s->nexttoken = -1; - s->start_line = 1; - s->yylen = 0; - s->idstart = NULL; - s->scanobjs = NewList(); - s->text = NewStringEmpty(); - s->str = 0; - s->error = 0; - s->error_line = 0; - s->freeze_line = 0; - s->brackets = NewList(); - brackets_push(s); - return s; -} - -/* ----------------------------------------------------------------------------- - * DelScanner() - * - * Delete a scanner object. - * ----------------------------------------------------------------------------- */ - -void DelScanner(Scanner *s) { - assert(s); - Delete(s->scanobjs); - Delete(s->brackets); - Delete(s->text); - Delete(s->file); - Delete(s->error); - Delete(s->str); - Free(s->idstart); - Free(s); -} - -/* ----------------------------------------------------------------------------- - * Scanner_clear() - * - * Clear the contents of a scanner object. - * ----------------------------------------------------------------------------- */ - -void Scanner_clear(Scanner *s) { - assert(s); - Delete(s->str); - Clear(s->text); - Clear(s->scanobjs); - brackets_clear(s); - Delete(s->error); - s->str = 0; - s->error = 0; - s->line = 1; - s->nexttoken = -1; - s->start_line = 0; - s->yylen = 0; - /* Should these be cleared too? - s->idstart; - s->file; - s->error_line; - s->freeze_line; - */ -} - -/* ----------------------------------------------------------------------------- - * Scanner_push() - * - * Push some new text into the scanner. The scanner will start parsing this text - * immediately before returning to the old text. - * ----------------------------------------------------------------------------- */ - -void Scanner_push(Scanner *s, String *txt) { - assert(s && txt); - Push(s->scanobjs, txt); - if (s->str) { - Setline(s->str,s->line); - Delete(s->str); - } - s->str = txt; - DohIncref(s->str); - s->line = Getline(txt); -} - -/* ----------------------------------------------------------------------------- - * Scanner_pushtoken() - * - * Push a token into the scanner. This token will be returned on the next - * call to Scanner_token(). - * ----------------------------------------------------------------------------- */ - -void Scanner_pushtoken(Scanner *s, int nt, const_String_or_char_ptr val) { - assert(s); - assert((nt >= 0) && (nt < SWIG_MAXTOKENS)); - s->nexttoken = nt; - if ( Char(val) != Char(s->text) ) { - Clear(s->text); - Append(s->text,val); - } -} - -/* ----------------------------------------------------------------------------- - * Scanner_set_location() - * - * Set the file and line number location of the scanner. - * ----------------------------------------------------------------------------- */ - -void Scanner_set_location(Scanner *s, String *file, int line) { - Setline(s->str, line); - Setfile(s->str, file); - s->line = line; -} - -/* ----------------------------------------------------------------------------- - * Scanner_file() - * - * Get the current file. - * ----------------------------------------------------------------------------- */ - -String *Scanner_file(Scanner *s) { - return Getfile(s->str); -} - -/* ----------------------------------------------------------------------------- - * Scanner_line() - * - * Get the current line number - * ----------------------------------------------------------------------------- */ -int Scanner_line(Scanner *s) { - return s->line; -} - -/* ----------------------------------------------------------------------------- - * Scanner_start_line() - * - * Get the line number on which the current token starts - * ----------------------------------------------------------------------------- */ -int Scanner_start_line(Scanner *s) { - return s->start_line; -} - -/* ----------------------------------------------------------------------------- - * Scanner_idstart() - * - * Change the set of additional characters that can be used to start an identifier. - * ----------------------------------------------------------------------------- */ - -void Scanner_idstart(Scanner *s, const char *id) { - Free(s->idstart); - s->idstart = Swig_copy_string(id); -} - -/* ----------------------------------------------------------------------------- - * nextchar() - * - * Returns the next character from the scanner or 0 if end of the string. - * ----------------------------------------------------------------------------- */ -static char nextchar(Scanner *s) { - int nc; - if (!s->str) - return 0; - while ((nc = Getc(s->str)) == EOF) { - Delete(s->str); - s->str = 0; - Delitem(s->scanobjs, 0); - if (Len(s->scanobjs) == 0) - return 0; - s->str = Getitem(s->scanobjs, 0); - s->line = Getline(s->str); - DohIncref(s->str); - } - if ((nc == '\n') && (!s->freeze_line)) - s->line++; - Putc(nc,s->text); - return (char)nc; -} - -/* ----------------------------------------------------------------------------- - * set_error() - * - * Sets error information on the scanner. - * ----------------------------------------------------------------------------- */ - -static void set_error(Scanner *s, int line, const_String_or_char_ptr msg) { - s->error_line = line; - s->error = NewString(msg); -} - -/* ----------------------------------------------------------------------------- - * Scanner_errmsg() - * Scanner_errline() - * - * Returns error information (if any) - * ----------------------------------------------------------------------------- */ - -String *Scanner_errmsg(Scanner *s) { - return s->error; -} - -int Scanner_errline(Scanner *s) { - return s->error_line; -} - -/* ----------------------------------------------------------------------------- - * freeze_line() - * - * Freezes the current line number. - * ----------------------------------------------------------------------------- */ - -static void freeze_line(Scanner *s, int val) { - s->freeze_line = val; -} - -/* ----------------------------------------------------------------------------- - * brackets_count() - * - * Returns the number of brackets at the current depth. - * A syntax error with unbalanced ) brackets will result in a NULL pointer return. - * ----------------------------------------------------------------------------- */ -static int *brackets_count(Scanner *s) { - int *count; - if (Len(s->brackets) > 0) - count = (int *)Data(Getitem(s->brackets, 0)); - else - count = 0; - return count; -} - -/* ----------------------------------------------------------------------------- - * brackets_clear() - * - * Resets the current depth and clears all brackets. - * Usually called at the end of statements; - * ----------------------------------------------------------------------------- */ -static void brackets_clear(Scanner *s) { - Clear(s->brackets); - brackets_push(s); /* base bracket count should always be created */ -} - -/* ----------------------------------------------------------------------------- - * brackets_increment() - * - * Increases the number of brackets at the current depth. - * Usually called when a single '<' is found. - * ----------------------------------------------------------------------------- */ -static void brackets_increment(Scanner *s) { - int *count = brackets_count(s); - if (count) - (*count)++; -} - -/* ----------------------------------------------------------------------------- - * brackets_decrement() - * - * Decreases the number of brackets at the current depth. - * Usually called when a single '>' is found. - * ----------------------------------------------------------------------------- */ -static void brackets_decrement(Scanner *s) { - int *count = brackets_count(s); - if (count) - (*count)--; -} - -/* ----------------------------------------------------------------------------- - * brackets_reset() - * - * Sets the number of '<' brackets back to zero. Called at the point where - * it is no longer possible to have a matching closing >> pair for a template. - * ----------------------------------------------------------------------------- */ -static void brackets_reset(Scanner *s) { - int *count = brackets_count(s); - if (count) - *count = 0; -} - -/* ----------------------------------------------------------------------------- - * brackets_push() - * - * Increases the depth of brackets. - * Usually called when '(' is found. - * ----------------------------------------------------------------------------- */ -static void brackets_push(Scanner *s) { - int *newInt = (int *)Malloc(sizeof(int)); - *newInt = 0; - Push(s->brackets, NewVoid(newInt, Free)); -} - -/* ----------------------------------------------------------------------------- - * brackets_pop() - * - * Decreases the depth of brackets. - * Usually called when ')' is found. - * ----------------------------------------------------------------------------- */ -static void brackets_pop(Scanner *s) { - if (Len(s->brackets) > 0) /* protect against unbalanced ')' brackets */ - Delitem(s->brackets, 0); -} - -/* ----------------------------------------------------------------------------- - * brackets_allow_shift() - * - * Return 1 to allow shift (>>), or 0 if (>>) should be split into (> >). - * This is for C++11 template syntax for closing templates. - * ----------------------------------------------------------------------------- */ -static int brackets_allow_shift(Scanner *s) { - int *count = brackets_count(s); - return !count || (*count <= 0); -} - -/* ----------------------------------------------------------------------------- - * retract() - * - * Retract n characters - * ----------------------------------------------------------------------------- */ -static void retract(Scanner *s, int n) { - int i, l; - char *str; - - str = Char(s->text); - l = Len(s->text); - assert(n <= l); - for (i = 0; i < n; i++) { - if (str[l - 1] == '\n') { - if (!s->freeze_line) s->line--; - } - (void)Seek(s->str, -1, SEEK_CUR); - Delitem(s->text, DOH_END); - } -} - -/* ----------------------------------------------------------------------------- - * get_escape() - * - * Get escape sequence. Called when a backslash is found in a string - * ----------------------------------------------------------------------------- */ - -static void get_escape(Scanner *s) { - int result = 0; - int state = 0; - int c; - - while (1) { - c = nextchar(s); - if (c == 0) - break; - switch (state) { - case 0: - if (c == 'n') { - Delitem(s->text, DOH_END); - Append(s->text,"\n"); - return; - } - if (c == 'r') { - Delitem(s->text, DOH_END); - Append(s->text,"\r"); - return; - } - if (c == 't') { - Delitem(s->text, DOH_END); - Append(s->text,"\t"); - return; - } - if (c == 'a') { - Delitem(s->text, DOH_END); - Append(s->text,"\a"); - return; - } - if (c == 'b') { - Delitem(s->text, DOH_END); - Append(s->text,"\b"); - return; - } - if (c == 'f') { - Delitem(s->text, DOH_END); - Append(s->text,"\f"); - return; - } - if (c == '\\') { - Delitem(s->text, DOH_END); - Append(s->text,"\\"); - return; - } - if (c == 'v') { - Delitem(s->text, DOH_END); - Append(s->text,"\v"); - return; - } - if (c == 'e') { - Delitem(s->text, DOH_END); - Append(s->text,"\033"); - return; - } - if (c == '\'') { - Delitem(s->text, DOH_END); - Append(s->text,"\'"); - return; - } - if (c == '\"') { - Delitem(s->text, DOH_END); - Append(s->text,"\""); - return; - } - if (c == '\n') { - Delitem(s->text, DOH_END); - return; - } - if (isdigit(c)) { - state = 10; - result = (c - '0'); - Delitem(s->text, DOH_END); - } else if (c == 'x') { - state = 20; - Delitem(s->text, DOH_END); - } else { - char tmp[3]; - tmp[0] = '\\'; - tmp[1] = (char)c; - tmp[2] = 0; - Delitem(s->text, DOH_END); - Append(s->text, tmp); - return; - } - break; - case 10: - if (!isdigit(c)) { - retract(s,1); - Putc((char)result,s->text); - return; - } - result = (result << 3) + (c - '0'); - Delitem(s->text, DOH_END); - break; - case 20: - if (!isxdigit(c)) { - retract(s,1); - Putc((char)result, s->text); - return; - } - if (isdigit(c)) - result = (result << 4) + (c - '0'); - else - result = (result << 4) + (10 + tolower(c) - 'a'); - Delitem(s->text, DOH_END); - break; - } - } - return; -} - -/* ----------------------------------------------------------------------------- - * look() - * - * Return the raw value of the next token. - * ----------------------------------------------------------------------------- */ - -static int look(Scanner *s) { - int state = 0; - int c = 0; - String *str_delimiter = 0; - - Clear(s->text); - s->start_line = s->line; - Setfile(s->text, Getfile(s->str)); - - - while (1) { - switch (state) { - case 0: - if ((c = nextchar(s)) == 0) - return (0); - - /* Process delimiters */ - - if (c == '\n') { - return SWIG_TOKEN_ENDLINE; - } else if (!isspace(c)) { - retract(s, 1); - state = 1000; - Clear(s->text); - Setline(s->text, s->line); - Setfile(s->text, Getfile(s->str)); - } - break; - - case 1000: - if ((c = nextchar(s)) == 0) - return (0); - if (c == '%') - state = 4; /* Possibly a SWIG directive */ - - /* Look for possible identifiers or unicode/delimiter strings */ - else if ((isalpha(c)) || (c == '_') || - (s->idstart && strchr(s->idstart, c))) { - state = 7; - } - - /* Look for single character symbols */ - - else if (c == '(') { - brackets_push(s); - return SWIG_TOKEN_LPAREN; - } - else if (c == ')') { - brackets_pop(s); - return SWIG_TOKEN_RPAREN; - } - else if (c == ';') { - brackets_clear(s); - return SWIG_TOKEN_SEMI; - } - else if (c == ',') - return SWIG_TOKEN_COMMA; - else if (c == '*') - state = 220; - else if (c == '}') - return SWIG_TOKEN_RBRACE; - else if (c == '{') { - brackets_reset(s); - return SWIG_TOKEN_LBRACE; - } - else if (c == '=') - state = 33; - else if (c == '+') - state = 200; - else if (c == '-') - state = 210; - else if (c == '&') - state = 31; - else if (c == '|') - state = 32; - else if (c == '^') - state = 230; - else if (c == '<') - state = 60; - else if (c == '>') - state = 61; - else if (c == '~') - return SWIG_TOKEN_NOT; - else if (c == '!') - state = 3; - else if (c == '\\') - return SWIG_TOKEN_BACKSLASH; - else if (c == '@') - return SWIG_TOKEN_AT; - else if (c == '$') - state = 75; - else if (c == '#') - return SWIG_TOKEN_POUND; - else if (c == '?') - return SWIG_TOKEN_QUESTION; - - /* Look for multi-character sequences */ - - else if (c == '/') { - state = 1; /* Comment (maybe) */ - s->start_line = s->line; - } - - else if (c == ':') - state = 5; /* maybe double colon */ - else if (c == '0') - state = 83; /* An octal or hex value */ - else if (c == '\"') { - state = 2; /* A string constant */ - s->start_line = s->line; - Clear(s->text); - } - else if (c == '\'') { - s->start_line = s->line; - Clear(s->text); - state = 9; /* A character constant */ - } else if (c == '`') { - s->start_line = s->line; - Clear(s->text); - state = 900; - } - - else if (c == '.') - state = 100; /* Maybe a number, maybe ellipsis, just a period */ - else if (c == '[') - state = 102; /* Maybe a bracket or a double bracket */ - else if (c == ']') - state = 103; /* Maybe a bracket or a double bracket */ - else if (isdigit(c)) - state = 8; /* A numerical value */ - else - state = 99; /* An error */ - break; - - case 1: /* Comment block */ - if ((c = nextchar(s)) == 0) - return (0); - if (c == '/') { - state = 10; /* C++ style comment */ - Clear(s->text); - Setline(s->text, Getline(s->str)); - Setfile(s->text, Getfile(s->str)); - Append(s->text, "//"); - } else if (c == '*') { - state = 11; /* C style comment */ - Clear(s->text); - Setline(s->text, Getline(s->str)); - Setfile(s->text, Getfile(s->str)); - Append(s->text, "/*"); - } else if (c == '=') { - return SWIG_TOKEN_DIVEQUAL; - } else { - retract(s, 1); - return SWIG_TOKEN_SLASH; - } - break; - case 10: /* C++ style comment */ - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n"); - return SWIG_TOKEN_ERROR; - } - if (c == '\n') { - retract(s,1); - return SWIG_TOKEN_COMMENT; - } else { - state = 10; - } - break; - case 11: /* C style comment block */ - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n"); - return SWIG_TOKEN_ERROR; - } - if (c == '*') { - state = 12; - } else { - state = 11; - } - break; - case 12: /* Still in C style comment */ - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated comment\n"); - return SWIG_TOKEN_ERROR; - } - if (c == '*') { - state = 12; - } else if (c == '/') { - return SWIG_TOKEN_COMMENT; - } else { - state = 11; - } - break; - - case 2: /* Processing a string */ - if (!str_delimiter) { - state=20; - break; - } - - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated string\n"); - return SWIG_TOKEN_ERROR; - } - else if (c == '(') { - state = 20; - } - else { - char temp[2] = { 0, 0 }; - temp[0] = c; - Append( str_delimiter, temp ); - } - - break; - - case 20: /* Inside the string */ - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated string\n"); - return SWIG_TOKEN_ERROR; - } - - if (!str_delimiter) { /* Ordinary string: "value" */ - if (c == '\"') { - Delitem(s->text, DOH_END); - return SWIG_TOKEN_STRING; - } else if (c == '\\') { - Delitem(s->text, DOH_END); - get_escape(s); - } - } else { /* Custom delimiter string: R"XXXX(value)XXXX" */ - if (c==')') { - int i=0; - String *end_delimiter = NewStringEmpty(); - while ((c = nextchar(s)) != 0 && c!='\"') { - char temp[2] = { 0, 0 }; - temp[0] = c; - Append( end_delimiter, temp ); - i++; - } - - if (Strcmp( str_delimiter, end_delimiter )==0) { - int len = Len(s->text); - Delslice(s->text, len - 2 - Len(str_delimiter), len); /* Delete ending )XXXX" */ - Delslice(s->text, 0, Len(str_delimiter) + 1); /* Delete starting XXXX( */ - Delete( end_delimiter ); /* Correct end delimiter )XXXX" occurred */ - Delete( str_delimiter ); - str_delimiter = 0; - return SWIG_TOKEN_STRING; - } else { /* Incorrect end delimiter occurred */ - if (c == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated raw string, started with R\"%s( is not terminated by )%s\"\n", str_delimiter, str_delimiter); - return SWIG_TOKEN_ERROR; - } - retract( s, i ); - Delete( end_delimiter ); - } - } - } - - break; - - case 3: /* Maybe a not equals */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_LNOT; - else if (c == '=') - return SWIG_TOKEN_NOTEQUAL; - else { - retract(s, 1); - return SWIG_TOKEN_LNOT; - } - break; - - case 31: /* AND or Logical AND or ANDEQUAL */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_AND; - else if (c == '&') - return SWIG_TOKEN_LAND; - else if (c == '=') - return SWIG_TOKEN_ANDEQUAL; - else { - retract(s, 1); - return SWIG_TOKEN_AND; - } - break; - - case 32: /* OR or Logical OR */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_OR; - else if (c == '|') - return SWIG_TOKEN_LOR; - else if (c == '=') - return SWIG_TOKEN_OREQUAL; - else { - retract(s, 1); - return SWIG_TOKEN_OR; - } - break; - - case 33: /* EQUAL or EQUALTO */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_EQUAL; - else if (c == '=') - return SWIG_TOKEN_EQUALTO; - else { - retract(s, 1); - return SWIG_TOKEN_EQUAL; - } - break; - - case 4: /* A wrapper generator directive (maybe) */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_PERCENT; - if (c == '{') { - state = 40; /* Include block */ - Clear(s->text); - Setline(s->text, Getline(s->str)); - Setfile(s->text, Getfile(s->str)); - s->start_line = s->line; - } else if (s->idstart && strchr(s->idstart, '%') && - ((isalpha(c)) || (c == '_'))) { - state = 7; - } else if (c == '=') { - return SWIG_TOKEN_MODEQUAL; - } else if (c == '}') { - Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '%%}'\n"); - Exit(EXIT_FAILURE); - } else { - retract(s, 1); - return SWIG_TOKEN_PERCENT; - } - break; - - case 40: /* Process an include block */ - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated block\n"); - return SWIG_TOKEN_ERROR; - } - if (c == '%') - state = 41; - break; - case 41: /* Still processing include block */ - if ((c = nextchar(s)) == 0) { - set_error(s,s->start_line,"Unterminated code block"); - return 0; - } - if (c == '}') { - Delitem(s->text, DOH_END); - Delitem(s->text, DOH_END); - Seek(s->text,0,SEEK_SET); - return SWIG_TOKEN_CODEBLOCK; - } else { - state = 40; - } - break; - - case 5: /* Maybe a double colon */ - - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_COLON; - if (c == ':') - state = 50; - else { - retract(s, 1); - return SWIG_TOKEN_COLON; - } - break; - - case 50: /* DCOLON, DCOLONSTAR */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_DCOLON; - else if (c == '*') - return SWIG_TOKEN_DCOLONSTAR; - else { - retract(s, 1); - return SWIG_TOKEN_DCOLON; - } - break; - - case 60: /* shift operators */ - if ((c = nextchar(s)) == 0) { - brackets_increment(s); - return SWIG_TOKEN_LESSTHAN; - } - if (c == '<') - state = 240; - else if (c == '=') { - if ((c = nextchar(s)) == 0) { - return SWIG_TOKEN_LTEQUAL; - } else if (c == '>' && cparse_cplusplus) { /* Spaceship operator */ - return SWIG_TOKEN_LTEQUALGT; - } else { - retract(s, 1); - return SWIG_TOKEN_LTEQUAL; - } - } else { - retract(s, 1); - brackets_increment(s); - return SWIG_TOKEN_LESSTHAN; - } - break; - case 61: - if ((c = nextchar(s)) == 0) { - brackets_decrement(s); - return SWIG_TOKEN_GREATERTHAN; - } - if (c == '>' && brackets_allow_shift(s)) - state = 250; - else if (c == '=') - return SWIG_TOKEN_GTEQUAL; - else { - retract(s, 1); - brackets_decrement(s); - return SWIG_TOKEN_GREATERTHAN; - } - break; - - case 7: /* Identifier or true/false or unicode/custom delimiter string */ - if (c == 'R') { /* Possibly CUSTOM DELIMITER string */ - state = 72; - break; - } - else if (c == 'L') { /* Probably identifier but may be a wide string literal */ - state = 77; - break; - } - else if (c != 'u' && c != 'U') { /* Definitely an identifier */ - state = 70; - break; - } - - if ((c = nextchar(s)) == 0) { - state = 76; - } - else if (c == '\"') { /* Definitely u, U or L string */ - retract(s, 1); - state = 1000; - } - else if (c == '\'') { /* Definitely u, U or L char */ - retract(s, 1); - state = 77; - } - else if (c == 'R') { /* Possibly CUSTOM DELIMITER u, U, L string */ - state = 73; - } - else if (c == '8') { /* Possibly u8 string/char */ - state = 71; - } - else { - retract(s, 1); /* Definitely an identifier */ - state = 70; - } - break; - - case 70: /* Identifier */ - if ((c = nextchar(s)) == 0) - state = 76; - else if (isalnum(c) || (c == '_') || (c == '$')) { - state = 70; - } else { - retract(s, 1); - state = 76; - } - break; - - case 71: /* Possibly u8 string/char */ - if ((c = nextchar(s)) == 0) { - state = 76; - } - else if (c=='\"') { - retract(s, 1); /* Definitely u8 string */ - state = 1000; - } - else if (c=='\'') { - retract(s, 1); /* Definitely u8 char */ - state = 77; - } - else if (c=='R') { - state = 74; /* Possibly CUSTOM DELIMITER u8 string */ - } - else { - retract(s, 2); /* Definitely an identifier. Retract 8" */ - state = 70; - } - - break; - - case 72: /* Possibly CUSTOM DELIMITER string */ - case 73: - case 74: - if ((c = nextchar(s)) == 0) { - state = 76; - } - else if (c=='\"') { - retract(s, 1); /* Definitely custom delimiter u, U or L string */ - str_delimiter = NewStringEmpty(); - state = 1000; - } - else { - if (state==72) { - retract(s, 1); /* Definitely an identifier. Retract ? */ - } - else if (state==73) { - retract(s, 2); /* Definitely an identifier. Retract R? */ - } - else if (state==74) { - retract(s, 3); /* Definitely an identifier. Retract 8R? */ - } - state = 70; - } - - break; - - case 75: /* Special identifier $ */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_DOLLAR; - if (isalnum(c) || (c == '_') || (c == '*') || (c == '&')) { - state = 70; - } else { - retract(s,1); - if (Len(s->text) == 1) return SWIG_TOKEN_DOLLAR; - state = 76; - } - break; - - case 76: /* Identifier or true/false */ - if (cparse_cplusplus) { - if (Strcmp(s->text, "true") == 0) - return SWIG_TOKEN_BOOL; - else if (Strcmp(s->text, "false") == 0) - return SWIG_TOKEN_BOOL; - } - return SWIG_TOKEN_ID; - break; - - case 77: /*identifier or wide string literal*/ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_ID; - else if (c == '\"') { - s->start_line = s->line; - Clear(s->text); - state = 78; - } - else if (c == '\'') { - s->start_line = s->line; - Clear(s->text); - state = 79; - } - else if (isalnum(c) || (c == '_') || (c == '$')) - state = 7; - else { - retract(s, 1); - return SWIG_TOKEN_ID; - } - break; - - case 78: /* Processing a wide string literal*/ - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated wide string\n"); - return SWIG_TOKEN_ERROR; - } - if (c == '\"') { - Delitem(s->text, DOH_END); - return SWIG_TOKEN_WSTRING; - } else if (c == '\\') { - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated wide string\n"); - return SWIG_TOKEN_ERROR; - } - } - break; - - case 79: /* Processing a wide char literal */ - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated wide character constant\n"); - return SWIG_TOKEN_ERROR; - } - if (c == '\'') { - Delitem(s->text, DOH_END); - return (SWIG_TOKEN_WCHAR); - } else if (c == '\\') { - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated wide character literal\n"); - return SWIG_TOKEN_ERROR; - } - } - break; - - case 8: /* A numerical digit */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_INT; - if (c == '.') { - state = 81; - } else if ((c == 'e') || (c == 'E')) { - state = 82; - } else if ((c == 'f') || (c == 'F')) { - Delitem(s->text, DOH_END); - return SWIG_TOKEN_FLOAT; - } else if (isdigit(c)) { - state = 8; - } else if ((c == 'l') || (c == 'L')) { - state = 87; - } else if ((c == 'u') || (c == 'U')) { - state = 88; - } else { - retract(s, 1); - return SWIG_TOKEN_INT; - } - break; - case 81: /* A floating pointer number of some sort */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_DOUBLE; - if (isdigit(c)) - state = 81; - else if ((c == 'e') || (c == 'E')) - state = 820; - else if ((c == 'f') || (c == 'F')) { - Delitem(s->text, DOH_END); - return SWIG_TOKEN_FLOAT; - } else if ((c == 'l') || (c == 'L')) { - Delitem(s->text, DOH_END); - return SWIG_TOKEN_DOUBLE; - } else { - retract(s, 1); - return (SWIG_TOKEN_DOUBLE); - } - break; - case 82: - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n"); - return SWIG_TOKEN_ERROR; - } - if ((isdigit(c)) || (c == '-') || (c == '+')) - state = 86; - else { - retract(s, 2); - Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n"); - return SWIG_TOKEN_ERROR; - } - break; - case 820: - /* Like case 82, but we've seen a decimal point. */ - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n"); - return SWIG_TOKEN_ERROR; - } - if ((isdigit(c)) || (c == '-') || (c == '+')) - state = 86; - else { - retract(s, 2); - Swig_error(cparse_file, cparse_start_line, "Exponent does not have any digits\n"); - return SWIG_TOKEN_ERROR; - } - break; - case 83: - /* Might be a hexadecimal or octal number */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_INT; - if (isdigit(c)) - state = 84; - else if ((c == 'e') || (c == 'E')) - state = 82; - else if ((c == 'x') || (c == 'X')) - state = 85; - else if ((c == 'b') || (c == 'B')) - state = 850; - else if (c == '.') - state = 81; - else if ((c == 'l') || (c == 'L')) { - state = 87; - } else if ((c == 'u') || (c == 'U')) { - state = 88; - } else { - retract(s, 1); - return SWIG_TOKEN_INT; - } - break; - case 84: - /* This is an octal number */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_INT; - if (isdigit(c)) - state = 84; - else if (c == '.') - state = 81; - else if ((c == 'e') || (c == 'E')) - state = 82; - else if ((c == 'l') || (c == 'L')) { - state = 87; - } else if ((c == 'u') || (c == 'U')) { - state = 88; - } else { - retract(s, 1); - return SWIG_TOKEN_INT; - } - break; - case 85: - /* This is an hex number */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_INT; - if (isxdigit(c)) - state = 85; - else if (c == '.') /* hexadecimal float */ - state = 860; - else if ((c == 'p') || (c == 'P')) /* hexadecimal float */ - state = 820; - else if ((c == 'l') || (c == 'L')) { - state = 87; - } else if ((c == 'u') || (c == 'U')) { - state = 88; - } else { - retract(s, 1); - return SWIG_TOKEN_INT; - } - break; - case 850: - /* This is a binary number */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_INT; - if ((c == '0') || (c == '1')) - state = 850; - else if ((c == 'l') || (c == 'L')) { - state = 87; - } else if ((c == 'u') || (c == 'U')) { - state = 88; - } else { - retract(s, 1); - return SWIG_TOKEN_INT; - } - break; - case 860: - /* hexadecimal float */ - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Hexadecimal floating literals require an exponent\n"); - return SWIG_TOKEN_ERROR; - } - if (isxdigit(c)) - state = 860; - else if ((c == 'p') || (c == 'P')) - state = 820; - else { - retract(s, 2); - Swig_error(cparse_file, cparse_start_line, "Hexadecimal floating literals require an exponent\n"); - return SWIG_TOKEN_ERROR; - } - break; - case 86: - /* Rest of floating point number */ - - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_DOUBLE; - if (isdigit(c)) - state = 86; - else if ((c == 'f') || (c == 'F')) { - Delitem(s->text, DOH_END); - return SWIG_TOKEN_FLOAT; - } else if ((c == 'l') || (c == 'L')) { - Delitem(s->text, DOH_END); - return SWIG_TOKEN_DOUBLE; - } else { - retract(s, 1); - return SWIG_TOKEN_DOUBLE; - } - break; - - case 87: - /* A long integer of some sort */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_LONG; - if ((c == 'u') || (c == 'U')) { - return SWIG_TOKEN_ULONG; - } else if ((c == 'l') || (c == 'L')) { - state = 870; - } else { - retract(s, 1); - return SWIG_TOKEN_LONG; - } - break; - - /* A long long integer */ - - case 870: - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_LONGLONG; - if ((c == 'u') || (c == 'U')) { - return SWIG_TOKEN_ULONGLONG; - } else { - retract(s, 1); - return SWIG_TOKEN_LONGLONG; - } - - /* An unsigned number */ - case 88: - - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_UINT; - if ((c == 'l') || (c == 'L')) { - state = 880; - } else { - retract(s, 1); - return SWIG_TOKEN_UINT; - } - break; - - /* Possibly an unsigned long long or unsigned long */ - case 880: - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_ULONG; - if ((c == 'l') || (c == 'L')) - return SWIG_TOKEN_ULONGLONG; - else { - retract(s, 1); - return SWIG_TOKEN_ULONG; - } - - /* A character constant */ - case 9: - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated character constant\n"); - return SWIG_TOKEN_ERROR; - } - if (c == '\'') { - Delitem(s->text, DOH_END); - return (SWIG_TOKEN_CHAR); - } else if (c == '\\') { - Delitem(s->text, DOH_END); - get_escape(s); - } - break; - - /* A period or an ellipsis or maybe a floating point number */ - - case 100: - if ((c = nextchar(s)) == 0) - return (0); - if (isdigit(c)) - state = 81; - else if (c == '.') - state = 101; - else { - retract(s, 1); - return SWIG_TOKEN_PERIOD; - } - break; - - /* An ellipsis */ - - case 101: - if ((c = nextchar(s)) == 0) - return (0); - if (c == '.') { - return SWIG_TOKEN_ELLIPSIS; - } else { - retract(s, 2); - return SWIG_TOKEN_PERIOD; - } - break; - - /* A left bracket or a double left bracket */ - case 102: - - if ((c = nextchar(s)) == 0) { - return SWIG_TOKEN_LBRACKET; - } else if (c == '[') { - return SWIG_TOKEN_LLBRACKET; - } else { - retract(s, 1); - return SWIG_TOKEN_LBRACKET; - } - break; - - /* a right bracket or a double right bracket */ - case 103: - if ((c = nextchar(s)) == 0) { - return SWIG_TOKEN_RBRACKET; - } else if (c == ']') { - return SWIG_TOKEN_RRBRACKET; - } else { - retract(s, 1); - return SWIG_TOKEN_RBRACKET; - } - break; - - case 200: /* PLUS, PLUSPLUS, PLUSEQUAL */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_PLUS; - else if (c == '+') - return SWIG_TOKEN_PLUSPLUS; - else if (c == '=') - return SWIG_TOKEN_PLUSEQUAL; - else { - retract(s, 1); - return SWIG_TOKEN_PLUS; - } - break; - - case 210: /* MINUS, MINUSMINUS, MINUSEQUAL, ARROW */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_MINUS; - else if (c == '-') - return SWIG_TOKEN_MINUSMINUS; - else if (c == '=') - return SWIG_TOKEN_MINUSEQUAL; - else if (c == '>') - state = 211; - else { - retract(s, 1); - return SWIG_TOKEN_MINUS; - } - break; - - case 211: /* ARROW, ARROWSTAR */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_ARROW; - else if (c == '*') - return SWIG_TOKEN_ARROWSTAR; - else { - retract(s, 1); - return SWIG_TOKEN_ARROW; - } - break; - - - case 220: /* STAR, TIMESEQUAL */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_STAR; - else if (c == '=') - return SWIG_TOKEN_TIMESEQUAL; - else { - retract(s, 1); - return SWIG_TOKEN_STAR; - } - break; - - case 230: /* XOR, XOREQUAL */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_XOR; - else if (c == '=') - return SWIG_TOKEN_XOREQUAL; - else { - retract(s, 1); - return SWIG_TOKEN_XOR; - } - break; - - case 240: /* LSHIFT, LSEQUAL */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_LSHIFT; - else if (c == '=') - return SWIG_TOKEN_LSEQUAL; - else { - retract(s, 1); - return SWIG_TOKEN_LSHIFT; - } - break; - - case 250: /* RSHIFT, RSEQUAL */ - if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_RSHIFT; - else if (c == '=') - return SWIG_TOKEN_RSEQUAL; - else { - retract(s, 1); - return SWIG_TOKEN_RSHIFT; - } - break; - - - /* An illegal character */ - - /* Reverse string */ - case 900: - if ((c = nextchar(s)) == 0) { - Swig_error(cparse_file, cparse_start_line, "Unterminated character constant\n"); - return SWIG_TOKEN_ERROR; - } - if (c == '`') { - Delitem(s->text, DOH_END); - return (SWIG_TOKEN_RSTRING); - } - break; - - default: - return SWIG_TOKEN_ILLEGAL; - } - } -} - -/* ----------------------------------------------------------------------------- - * Scanner_token() - * - * Real entry point to return the next token. Returns 0 if at end of input. - * ----------------------------------------------------------------------------- */ - -int Scanner_token(Scanner *s) { - int t; - Delete(s->error); - if (s->nexttoken >= 0) { - t = s->nexttoken; - s->nexttoken = -1; - return t; - } - s->start_line = 0; - t = look(s); - if (!s->start_line) { - Setline(s->text,s->line); - } else { - Setline(s->text,s->start_line); - } - return t; -} - -/* ----------------------------------------------------------------------------- - * Scanner_text() - * - * Return the lexene associated with the last returned token. - * ----------------------------------------------------------------------------- */ - -String *Scanner_text(Scanner *s) { - return s->text; -} - -/* ----------------------------------------------------------------------------- - * Scanner_skip_line() - * - * Skips to the end of a line - * ----------------------------------------------------------------------------- */ - -void Scanner_skip_line(Scanner *s) { - char c; - int done = 0; - Clear(s->text); - Setfile(s->text, Getfile(s->str)); - Setline(s->text, s->line); - while (!done) { - if ((c = nextchar(s)) == 0) - return; - if (c == '\\') { - nextchar(s); - } else if (c == '\n') { - done = 1; - } - } - return; -} - -/* ----------------------------------------------------------------------------- - * Scanner_skip_balanced() - * - * Skips a piece of code enclosed in begin/end symbols such as '{...}' or - * (...). Ignores symbols inside comments or strings. - * ----------------------------------------------------------------------------- */ - -int Scanner_skip_balanced(Scanner *s, int startchar, int endchar) { - char c; - int num_levels = 1; - int state = 0; - char temp[2] = { 0, 0 }; - String *locator = 0; - temp[0] = (char) startchar; - Clear(s->text); - Setfile(s->text, Getfile(s->str)); - Setline(s->text, s->line); - - Append(s->text, temp); - while (num_levels > 0) { - if ((c = nextchar(s)) == 0) { - Delete(locator); - return -1; - } - switch (state) { - case 0: - if (c == startchar) - num_levels++; - else if (c == endchar) - num_levels--; - else if (c == '/') - state = 10; - else if (c == '\"') - state = 20; - else if (c == '\'') - state = 30; - break; - case 10: - if (c == '/') - state = 11; - else if (c == '*') - state = 12; - else if (c == startchar) { - state = 0; - num_levels++; - } - else - state = 0; - break; - case 11: - if (c == '\n') - state = 0; - else - state = 11; - break; - case 12: /* first character inside C comment */ - if (c == '*') - state = 14; - else if (c == '@') - state = 40; - else - state = 13; - break; - case 13: - if (c == '*') - state = 14; - break; - case 14: /* possible end of C comment */ - if (c == '*') - state = 14; - else if (c == '/') - state = 0; - else - state = 13; - break; - case 20: - if (c == '\"') - state = 0; - else if (c == '\\') - state = 21; - break; - case 21: - state = 20; - break; - case 30: - if (c == '\'') - state = 0; - else if (c == '\\') - state = 31; - break; - case 31: - state = 30; - break; - /* 40-45 SWIG locator checks - a C comment with contents starting: @SWIG */ - case 40: - state = (c == 'S') ? 41 : (c == '*') ? 14 : 13; - break; - case 41: - state = (c == 'W') ? 42 : (c == '*') ? 14 : 13; - break; - case 42: - state = (c == 'I') ? 43 : (c == '*') ? 14 : 13; - break; - case 43: - state = (c == 'G') ? 44 : (c == '*') ? 14 : 13; - if (c == 'G') { - Delete(locator); - locator = NewString("/*@SWIG"); - } - break; - case 44: - if (c == '*') - state = 45; - Putc(c, locator); - break; - case 45: /* end of SWIG locator in C comment */ - if (c == '/') { - state = 0; - Putc(c, locator); - Scanner_locator(s, locator); - } else { - /* malformed locator */ - state = (c == '*') ? 14 : 13; - } - break; - default: - break; - } - } - Delete(locator); - return 0; -} - -/* ----------------------------------------------------------------------------- - * Scanner_get_raw_text_balanced() - * - * Returns raw text between 2 braces, does not change scanner state in any way - * ----------------------------------------------------------------------------- */ - -String *Scanner_get_raw_text_balanced(Scanner *s, int startchar, int endchar) { - String *result = 0; - char c; - int old_line = s->line; - String *old_text = Copy(s->text); - long position = Tell(s->str); - - int num_levels = 1; - int state = 0; - char temp[2] = { 0, 0 }; - temp[0] = (char) startchar; - Clear(s->text); - Setfile(s->text, Getfile(s->str)); - Setline(s->text, s->line); - Append(s->text, temp); - while (num_levels > 0) { - if ((c = nextchar(s)) == 0) { - Clear(s->text); - Append(s->text, old_text); - Delete(old_text); - s->line = old_line; - return 0; - } - switch (state) { - case 0: - if (c == startchar) - num_levels++; - else if (c == endchar) - num_levels--; - else if (c == '/') - state = 10; - else if (c == '\"') - state = 20; - else if (c == '\'') - state = 30; - break; - case 10: - if (c == '/') - state = 11; - else if (c == '*') - state = 12; - else if (c == startchar) { - state = 0; - num_levels++; - } - else - state = 0; - break; - case 11: - if (c == '\n') - state = 0; - else - state = 11; - break; - case 12: /* first character inside C comment */ - if (c == '*') - state = 14; - else - state = 13; - break; - case 13: - if (c == '*') - state = 14; - break; - case 14: /* possible end of C comment */ - if (c == '*') - state = 14; - else if (c == '/') - state = 0; - else - state = 13; - break; - case 20: - if (c == '\"') - state = 0; - else if (c == '\\') - state = 21; - break; - case 21: - state = 20; - break; - case 30: - if (c == '\'') - state = 0; - else if (c == '\\') - state = 31; - break; - case 31: - state = 30; - break; - default: - break; - } - } - Seek(s->str, position, SEEK_SET); - result = Copy(s->text); - Clear(s->text); - Append(s->text, old_text); - Delete(old_text); - s->line = old_line; - return result; -} -/* ----------------------------------------------------------------------------- - * Scanner_isoperator() - * - * Returns 0 or 1 depending on whether or not a token corresponds to a C/C++ - * operator. - * ----------------------------------------------------------------------------- */ - -int Scanner_isoperator(int tokval) { - if (tokval >= 100) return 1; - return 0; -} - -/* ---------------------------------------------------------------------- - * locator() - * - * Support for locator strings. These are strings of the form - * @SWIG:filename,line,id@ emitted by the SWIG preprocessor. They - * are primarily used for macro line number reporting. - * We just use the locator to mark when to activate/deactivate linecounting. - * ---------------------------------------------------------------------- */ - - -void Scanner_locator(Scanner *s, String *loc) { - static Locator *locs = 0; - static int expanding_macro = 0; - - if (!follow_locators) { - if (Equal(loc, "/*@SWIG@*/")) { - /* End locator. */ - if (expanding_macro) - --expanding_macro; - } else { - /* Begin locator. */ - ++expanding_macro; - } - /* Freeze line number processing in Scanner */ - freeze_line(s,expanding_macro); - } else { - int c; - Locator *l; - (void)Seek(loc, 7, SEEK_SET); - c = Getc(loc); - if (c == '@') { - /* Empty locator. We pop the last location off */ - if (locs) { - Scanner_set_location(s, locs->filename, locs->line_number); - cparse_file = locs->filename; - cparse_line = locs->line_number; - l = locs->next; - Free(locs); - locs = l; - } - return; - } - - /* We're going to push a new location */ - l = (Locator *) Malloc(sizeof(Locator)); - l->filename = cparse_file; - l->line_number = cparse_line; - l->next = locs; - locs = l; - - /* Now, parse the new location out of the locator string */ - { - String *fn = NewStringEmpty(); - /* Putc(c, fn); */ - - while ((c = Getc(loc)) != EOF) { - if ((c == '@') || (c == ',')) - break; - Putc(c, fn); - } - cparse_file = Swig_copy_string(Char(fn)); - Clear(fn); - cparse_line = 1; - /* Get the line number */ - while ((c = Getc(loc)) != EOF) { - if ((c == '@') || (c == ',')) - break; - Putc(c, fn); - } - cparse_line = atoi(Char(fn)); - Clear(fn); - - /* Get the rest of it */ - while ((c = Getc(loc)) != EOF) { - if (c == '@') - break; - Putc(c, fn); - } - /* Swig_diagnostic(cparse_file, cparse_line, "Scanner_set_location\n"); */ - Scanner_set_location(s, cparse_file, cparse_line); - Delete(fn); - } - } -} - -void Swig_cparse_follow_locators(int v) { - follow_locators = v; -} - - diff --git a/contrib/tools/swig/Source/Swig/stype.c b/contrib/tools/swig/Source/Swig/stype.c deleted file mode 100644 index f227778f6cd..00000000000 --- a/contrib/tools/swig/Source/Swig/stype.c +++ /dev/null @@ -1,1422 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * stype.c - * - * This file provides general support for datatypes that are encoded in - * the form of simple strings. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "cparse.h" -#include <ctype.h> - -/* ----------------------------------------------------------------------------- - * Synopsis - * - * The purpose of this module is to provide a general purpose type representation - * based on simple text strings. - * - * General idea: - * - * Types are represented by a base type (e.g., "int") and a collection of - * type operators applied to the base (e.g., pointers, arrays, etc...). - * - * Encoding: - * - * Types are encoded as strings of type constructors such as follows: - * - * String Encoding C Example - * --------------- --------- - * p.p.int int ** - * a(300).a(400).int int [300][400] - * p.q(const).char char const * - * - * All type constructors are denoted by a trailing '.': - * - * 'p.' = Pointer (*) - * 'r.' = Reference (&) - * 'z.' = Rvalue reference (&&) - * 'a(n).' = Array of size n [n] - * 'f(..,..).' = Function with arguments (args) - * 'q(str).' = Qualifier, such as const or volatile (cv-qualifier) - * 'm(cls).' = Pointer to member (cls::*) - * - * The encoding follows the order that you might describe a type in words. - * For example "p.a(200).int" is "A pointer to array of int's" and - * "p.q(const).char" is "a pointer to a const char". - * - * This representation of types is fairly convenient because ordinary string - * operations can be used for type manipulation. For example, a type could be - * formed by combining two strings such as the following: - * - * "p.p." + "a(400).int" = "p.p.a(400).int" - * - * Similarly, one could strip a 'const' declaration from a type doing something - * like this: - * - * Replace(t,"q(const).","",DOH_REPLACE_ANY) - * - * More examples: - * - * String Encoding C++ Example - * --------------- ----------- - * p.f(bool).r.q(const).long const long & (*)(bool) - * m(Funcs).q(const).f(bool).long long (Funcs::*)(bool) const - * r.q(const).m(Funcs).f(int).long long (Funcs::*const &)(int) - * m(Funcs).z.q(const).f(bool).long long (Funcs::*)(bool) const && - * - * Function decl examples: - * - * f(bool). long a(bool); - * r.f(bool). long b(bool) &; - * z.f(bool). long c(bool) &&; - * z.q(const).f(bool). long d(bool) const &&; - * - * For the most part, this module tries to minimize the use of special - * characters (*, [, <, etc...) in its type encoding. One reason for this - * is that SWIG might be extended to encode data in formats such as XML - * where you might want to do this: - * - * <function> - * <type>p.p.int</type> - * ... - * </function> - * - * Or alternatively, - * - * <function type="p.p.int" ...>blah</function> - * - * In either case, it's probably best to avoid characters such as '&', '*', or '<'. - * - * Why not use C syntax? Well, C syntax is fairly complicated to parse - * and not particularly easy to manipulate---especially for adding, deleting and - * composing type constructors. The string representation presented here makes - * this pretty easy. - * - * Why not use a bunch of nested data structures? Are you kidding? How - * would that be easier to use than a few simple string operations? - * ----------------------------------------------------------------------------- */ - - -SwigType *NewSwigType(int t) { - switch (t) { - case T_BOOL: - return NewString("bool"); - break; - case T_INT: - return NewString("int"); - break; - case T_UINT: - return NewString("unsigned int"); - break; - case T_SHORT: - return NewString("short"); - break; - case T_USHORT: - return NewString("unsigned short"); - break; - case T_LONG: - return NewString("long"); - break; - case T_ULONG: - return NewString("unsigned long"); - break; - case T_FLOAT: - return NewString("float"); - break; - case T_DOUBLE: - return NewString("double"); - break; - case T_COMPLEX: - return NewString("_Complex"); - break; - case T_CHAR: - return NewString("char"); - break; - case T_SCHAR: - return NewString("signed char"); - break; - case T_UCHAR: - return NewString("unsigned char"); - break; - case T_STRING: { - SwigType *t = NewString("char"); - SwigType_add_qualifier(t, "const"); - SwigType_add_pointer(t); - return t; - break; - } - case T_WCHAR: - return NewString("wchar_t"); - break; - case T_WSTRING: { - SwigType *t = NewString("wchar_t"); - SwigType_add_pointer(t); - return t; - break; - } - case T_LONGLONG: - return NewString("long long"); - break; - case T_ULONGLONG: - return NewString("unsigned long long"); - break; - case T_VOID: - return NewString("void"); - break; - case T_AUTO: - return NewString("auto"); - break; - default: - break; - } - return NewStringEmpty(); -} - -/* ----------------------------------------------------------------------------- - * SwigType_push() - * - * Push a type constructor onto the type - * ----------------------------------------------------------------------------- */ - -void SwigType_push(SwigType *t, String *cons) { - if (!cons) - return; - if (!Len(cons)) - return; - - if (Len(t)) { - char *c = Char(cons); - if (c[strlen(c) - 1] != '.') - Insert(t, 0, "."); - } - Insert(t, 0, cons); -} - -/* ----------------------------------------------------------------------------- - * SwigType_ispointer_return() - * - * Testing functions for querying a raw datatype - * ----------------------------------------------------------------------------- */ - -int SwigType_ispointer_return(const SwigType *t) { - char *c; - int idx; - if (!t) - return 0; - c = Char(t); - idx = (int)strlen(c) - 4; - if (idx >= 0) { - return (strcmp(c + idx, ").p.") == 0); - } - return 0; -} - -int SwigType_isreference_return(const SwigType *t) { - char *c; - int idx; - if (!t) - return 0; - c = Char(t); - idx = (int)strlen(c) - 4; - if (idx >= 0) { - return (strcmp(c + idx, ").r.") == 0); - } - return 0; -} - -int SwigType_isconst(const SwigType *t) { - char *c; - if (!t) - return 0; - c = Char(t); - if (strncmp(c, "q(", 2) == 0) { - String *q = SwigType_parm(t); - if (strstr(Char(q), "const")) { - Delete(q); - return 1; - } - Delete(q); - } - /* Hmmm. Might be const through a typedef */ - if (SwigType_issimple(t)) { - int ret; - SwigType *td = SwigType_typedef_resolve(t); - if (td) { - ret = SwigType_isconst(td); - Delete(td); - return ret; - } - } - return 0; -} - -int SwigType_ismutable(const SwigType *t) { - int r; - SwigType *qt = SwigType_typedef_resolve_all(t); - if (SwigType_isreference(qt) || SwigType_isrvalue_reference(qt) || SwigType_isarray(qt)) { - Delete(SwigType_pop(qt)); - } - r = SwigType_isconst(qt); - Delete(qt); - return r ? 0 : 1; -} - -int SwigType_isenum(const SwigType *t) { - char *c = Char(t); - if (!t) - return 0; - if (strncmp(c, "enum ", 5) == 0) { - return 1; - } - return 0; -} - -int SwigType_issimple(const SwigType *t) { - char *c = Char(t); - if (!t) - return 0; - while (*c) { - if (*c == '<') { - int nest = 1; - c++; - while (*c && nest) { - if (*c == '<') - nest++; - if (*c == '>') - nest--; - c++; - } - c--; - } - if (*c == '.') - return 0; - c++; - } - return 1; -} - -/* ----------------------------------------------------------------------------- - * SwigType_default_create() - * - * Create the default type for this datatype. This takes a type and strips it - * down to a generic form first by resolving all typedefs. - * - * Rules: - * Pointers: p.SWIGTYPE - * References: r.SWIGTYPE - * Arrays no dimension: a().SWIGTYPE - * Arrays with dimension: a(ANY).SWIGTYPE - * Member pointer: m(CLASS).SWIGTYPE - * Function pointer: f(ANY).SWIGTYPE - * Enums: enum SWIGTYPE - * Types: SWIGTYPE - * - * Examples (also see SwigType_default_deduce): - * - * int [2][4] - * a(2).a(4).int - * a(ANY).a(ANY).SWIGTYPE - * - * struct A {}; - * typedef A *Aptr; - * Aptr const & - * r.q(const).Aptr - * r.q(const).p.SWIGTYPE - * - * enum E {e1, e2}; - * enum E const & - * r.q(const).enum E - * r.q(const).enum SWIGTYPE - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_default_create(const SwigType *ty) { - SwigType *r = 0; - List *l; - Iterator it; - int numitems; - - if (!SwigType_isvarargs(ty)) { - SwigType *t = SwigType_typedef_resolve_all(ty); - r = NewStringEmpty(); - l = SwigType_split(t); - numitems = Len(l); - - if (numitems >= 1) { - String *last_subtype = Getitem(l, numitems-1); - if (SwigType_isenum(last_subtype)) - Setitem(l, numitems-1, NewString("enum SWIGTYPE")); - else - Setitem(l, numitems-1, NewString("SWIGTYPE")); - } - - for (it = First(l); it.item; it = Next(it)) { - String *subtype = it.item; - if (SwigType_isarray(subtype)) { - if (Equal(subtype, "a().")) - Append(r, NewString("a().")); - else - Append(r, NewString("a(ANY).")); - } else if (SwigType_isfunction(subtype)) { - Append(r, NewString("f(ANY).SWIGTYPE")); - break; - } else if (SwigType_ismemberpointer(subtype)) { - Append(r, NewString("m(CLASS).SWIGTYPE")); - break; - } else { - Append(r, subtype); - } - } - - Delete(l); - Delete(t); - } - - return r; -} - -/* ----------------------------------------------------------------------------- - * SwigType_default_deduce() - * - * This function implements type deduction used in the typemap matching rules - * and is very close to the type deduction used in partial template class - * specialization matching in that the most specialized type is always chosen. - * SWIGTYPE is used as the generic type. The basic idea is to repeatedly call - * this function to find a deduced type until nothing matches. - * - * The type t must have already been converted to the default type via a call to - * SwigType_default_create() before calling this function. - * - * Example deductions (matching the examples described in SwigType_default_create), - * where the most specialized matches are highest in the list: - * - * a(ANY).a(ANY).SWIGTYPE - * a(ANY).a().SWIGTYPE - * a(ANY).p.SWIGTYPE - * a(ANY).SWIGTYPE - * a().SWIGTYPE - * p.SWIGTYPE - * SWIGTYPE - * - * r.q(const).p.SWIGTYPE - * r.q(const).SWIGTYPE - * r.SWIGTYPE - * SWIGTYPE - * - * r.q(const).enum SWIGTYPE - * r.enum SWIGTYPE - * r.SWIGTYPE - * SWIGTYPE - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_default_deduce(const SwigType *t) { - SwigType *r = NewStringEmpty(); - List *l; - Iterator it; - int numitems; - - l = SwigType_split(t); - - numitems = Len(l); - if (numitems >= 1) { - String *last_subtype = Getitem(l, numitems-1); - int is_enum = SwigType_isenum(last_subtype); - - if (numitems >=2 ) { - String *subtype = Getitem(l, numitems-2); /* last but one */ - if (SwigType_isarray(subtype)) { - if (is_enum) { - /* enum deduction, enum SWIGTYPE => SWIGTYPE */ - Setitem(l, numitems-1, NewString("SWIGTYPE")); - } else { - /* array deduction, a(ANY). => a(). => p. */ - String *deduced_subtype = 0; - if (Strcmp(subtype, "a().") == 0) { - deduced_subtype = NewString("p."); - } else if (Strcmp(subtype, "a(ANY).") == 0) { - deduced_subtype = NewString("a()."); - } else { - assert(0); - } - Setitem(l, numitems-2, deduced_subtype); - } - } else if (SwigType_ismemberpointer(subtype)) { - /* member pointer deduction, m(CLASS). => p. */ - Setitem(l, numitems-2, NewString("p.")); - } else if (is_enum && !SwigType_isqualifier(subtype)) { - /* enum deduction, enum SWIGTYPE => SWIGTYPE */ - Setitem(l, numitems-1, NewString("SWIGTYPE")); - } else { - /* simple type deduction, eg, r.p.p. => r.p. */ - /* also function pointers eg, p.f(ANY). => p. */ - Delitem(l, numitems-2); - } - } else { - if (is_enum) { - /* enum deduction, enum SWIGTYPE => SWIGTYPE */ - Setitem(l, numitems-1, NewString("SWIGTYPE")); - } else { - /* delete the only item, we are done with deduction */ - Delitem(l, 0); - } - } - } else { - assert(0); - } - - for (it = First(l); it.item; it = Next(it)) { - Append(r, it.item); - } - - if (Len(r) == 0) { - Delete(r); - r = 0; - } - - Delete(l); - return r; -} - - -/* ----------------------------------------------------------------------------- - * SwigType_namestr() - * - * Returns a string of the base type. Takes care of template expansions - * ----------------------------------------------------------------------------- */ - -String *SwigType_namestr(const SwigType *t) { - String *r; - String *suffix; - List *p; - int i, sz; - char *d = Char(t); - char *c = strstr(d, "<("); - - if (!c || !strstr(c + 2, ")>")) - return NewString(t); - - r = NewStringWithSize(d, (int)(c - d)); - if (*(c - 1) == '<') - Putc(' ', r); - Putc('<', r); - - p = SwigType_parmlist(c + 1); - sz = Len(p); - for (i = 0; i < sz; i++) { - String *str = SwigType_str(Getitem(p, i), 0); - /* Avoid creating a <: token, which is the same as [ in C++ - put a space after '<'. */ - if (i == 0 && Len(str)) - Putc(' ', r); - Append(r, str); - if ((i + 1) < sz) - Putc(',', r); - Delete(str); - } - Putc(' ', r); - Putc('>', r); - suffix = SwigType_templatesuffix(t); - if (Len(suffix) > 0) { - String *suffix_namestr = SwigType_namestr(suffix); - Append(r, suffix_namestr); - Delete(suffix_namestr); - } else { - Append(r, suffix); - } - Delete(suffix); - Delete(p); - return r; -} - -/* ----------------------------------------------------------------------------- - * SwigType_str() - * - * Create a C string representation of a datatype. - * ----------------------------------------------------------------------------- */ - -String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) { - String *result; - String *element = 0; - String *nextelement; - String *forwardelement; - SwigType *member_function_qualifiers = 0; - List *elements; - int nelements, i; - - if (id) { - /* stringify the id expanding templates, for example when the id is a fully qualified templated class name */ - String *id_str = NewString(id); /* unfortunate copy due to current const limitations */ - result = SwigType_str(id_str, 0); - Delete(id_str); - } else { - result = NewStringEmpty(); - } - - elements = SwigType_split(s); - nelements = Len(elements); - - if (nelements > 0) { - element = Getitem(elements, 0); - } - /* Now, walk the type list and start emitting */ - for (i = 0; i < nelements; i++) { - if (i < (nelements - 1)) { - nextelement = Getitem(elements, i + 1); - forwardelement = nextelement; - if (SwigType_isqualifier(nextelement)) { - if (i < (nelements - 2)) - forwardelement = Getitem(elements, i + 2); - } - } else { - nextelement = 0; - forwardelement = 0; - } - if (SwigType_isqualifier(element)) { - if (!member_function_qualifiers) { - DOH *q = 0; - q = SwigType_parm(element); - Insert(result, 0, " "); - Insert(result, 0, q); - Delete(q); - } - } else if (SwigType_ispointer(element)) { - Insert(result, 0, "*"); - if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { - Insert(result, 0, "("); - Append(result, ")"); - } - } else if (SwigType_ismemberpointer(element)) { - String *q; - q = SwigType_parm(element); - Insert(result, 0, "::*"); - Insert(result, 0, q); - if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { - Insert(result, 0, "("); - Append(result, ")"); - } - { - String *next3elements = NewStringEmpty(); - int j; - for (j = i + 1; j < i + 4 && j < nelements; j++) { - Append(next3elements, Getitem(elements, j)); - } - if (SwigType_isfunction(next3elements)) - member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements); - Delete(next3elements); - } - Delete(q); - } else if (SwigType_isreference(element)) { - if (!member_function_qualifiers) - Insert(result, 0, "&"); - if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { - Insert(result, 0, "("); - Append(result, ")"); - } - } else if (SwigType_isrvalue_reference(element)) { - if (!member_function_qualifiers) - Insert(result, 0, "&&"); - if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { - Insert(result, 0, "("); - Append(result, ")"); - } - } else if (SwigType_isarray(element)) { - DOH *size; - Append(result, "["); - size = SwigType_parm(element); - Append(result, size); - Append(result, "]"); - Delete(size); - } else if (SwigType_isfunction(element)) { - DOH *parms, *p; - int j, plen; - Append(result, "("); - parms = SwigType_parmlist(element); - plen = Len(parms); - for (j = 0; j < plen; j++) { - p = SwigType_str(Getitem(parms, j), 0); - Append(result, p); - if (j < (plen - 1)) - Append(result, ","); - } - Append(result, ")"); - if (member_function_qualifiers) { - String *p = SwigType_str(member_function_qualifiers, 0); - Append(result, " "); - Append(result, p); - Delete(p); - Delete(member_function_qualifiers); - member_function_qualifiers = 0; - } - Delete(parms); - } else { - if (strcmp(Char(element), "v(...)") == 0) { - Insert(result, 0, "..."); - } else { - String *bs = SwigType_namestr(element); - Insert(result, 0, " "); - Insert(result, 0, bs); - Delete(bs); - } - } - element = nextelement; - } - Delete(elements); - Chop(result); - return result; -} - -/* ----------------------------------------------------------------------------- - * SwigType_ltype(const SwigType *ty) - * - * Create a locally assignable type - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_ltype(const SwigType *s) { - String *result; - String *element; - SwigType *td, *tc = 0; - List *elements; - int nelements, i; - int firstarray = 1; - int notypeconv = 0; - int ignore_member_function_qualifiers = 0; - - result = NewStringEmpty(); - tc = Copy(s); - /* Nuke all leading qualifiers */ - while (SwigType_isqualifier(tc)) { - Delete(SwigType_pop(tc)); - } - if (SwigType_issimple(tc)) { - /* Resolve any typedef definitions */ - SwigType *tt = Copy(tc); - td = 0; - while ((td = SwigType_typedef_resolve(tt))) { - if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td) || SwigType_isrvalue_reference(td))) { - /* We need to use the typedef type */ - Delete(tt); - break; - } else if (td) { - Delete(tt); - tt = td; - } - } - if (td) { - Delete(tc); - tc = td; - } - } - - elements = SwigType_split(tc); - nelements = Len(elements); - - /* Now, walk the type list and start emitting */ - for (i = 0; i < nelements; i++) { - element = Getitem(elements, i); - /* when we see a function, we need to preserve the following types */ - if (SwigType_isfunction(element)) { - notypeconv = 1; - ignore_member_function_qualifiers = 0; - } - if (ignore_member_function_qualifiers) { - /* cv-qualifiers and ref-qualifiers up until the f() element have already been added */ - } else if (SwigType_isqualifier(element)) { - /* swallow cv-qualifiers */ - } else if (SwigType_ispointer(element)) { - Append(result, element); - firstarray = 0; - } else if (SwigType_ismemberpointer(element)) { - Append(result, element); - { - String *next3elements = NewStringEmpty(); - int j; - for (j = i + 1; j < i + 4 && j < nelements; j++) { - Append(next3elements, Getitem(elements, j)); - } - if (SwigType_isfunction(next3elements)) { - SwigType *member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements); - /* compilers won't let us cast from a member function without qualifiers to one with qualifiers, so the qualifiers are kept in the ltype */ - if (member_function_qualifiers) - Append(result, member_function_qualifiers); - Delete(member_function_qualifiers); - ignore_member_function_qualifiers = 1; - } - Delete(next3elements); - } - firstarray = 0; - } else if (SwigType_isreference(element)) { - if (notypeconv) { - Append(result, element); - } else { - Append(result, "p."); - } - firstarray = 0; - } else if (SwigType_isrvalue_reference(element)) { - if (notypeconv) { - Append(result, element); - } else { - Append(result, "p."); - } - firstarray = 0; - } else if (SwigType_isarray(element) && firstarray) { - if (notypeconv) { - Append(result, element); - } else { - Append(result, "p."); - } - firstarray = 0; - } else if (SwigType_isenum(element)) { - int anonymous_enum = (Cmp(element, "enum ") == 0); - if (notypeconv || !anonymous_enum) { - Append(result, element); - } else { - Append(result, "int"); - } - } else { - Append(result, element); - } - } - Delete(elements); - Delete(tc); - return result; -} - -/* ----------------------------------------------------------------------------- - * SwigType_lstr() - * - * Produces a type-string that is suitable as a lvalue in an expression. - * That is, a type that can be freely assigned a value without violating - * any C assignment rules. - * - * - Qualifiers such as 'const' and 'volatile' are stripped. - * Except for member function cv-qualifiers and ref-qualifiers. - * - Arrays are converted into a *single* pointer (i.e., - * double [][] becomes double *). - * - References are converted into a pointer. - * - Typedef names that refer to read-only types will be replaced - * with an equivalent assignable version. - * -------------------------------------------------------------------- */ - -String *SwigType_lstr(const SwigType *s, const_String_or_char_ptr id) { - String *result; - SwigType *tc; - - tc = SwigType_ltype(s); - result = SwigType_str(tc, id); - Delete(tc); - return result; -} - -/* ----------------------------------------------------------------------------- - * SwigType_rcaststr() - * - * Produces a casting string that maps the type returned by lstr() to the real - * datatype printed by str(). - * ----------------------------------------------------------------------------- */ - -String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) { - String *result, *cast; - String *element = 0; - String *nextelement; - String *forwardelement; - String *member_function_qualifiers = 0; - SwigType *td, *tc = 0; - const SwigType *rs; - List *elements; - int nelements, i; - int clear = 1; - int firstarray = 1; - int isreference = 0; - int isfunction = 0; - - result = NewStringEmpty(); - - if (SwigType_isconst(s)) { - tc = Copy(s); - Delete(SwigType_pop(tc)); - if (SwigType_ismemberpointer(tc)) - rs = s; - else - rs = tc; - } else { - rs = s; - } - - if ((SwigType_isconst(rs) || SwigType_isarray(rs) || SwigType_isreference(rs) || SwigType_isrvalue_reference(rs))) { - td = 0; - } else { - td = SwigType_typedef_resolve(rs); - } - - if (td) { - if ((SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td) || SwigType_isrvalue_reference(td))) { - elements = SwigType_split(td); - } else { - elements = SwigType_split(rs); - } - Delete(td); - } else { - elements = SwigType_split(rs); - } - nelements = Len(elements); - if (nelements > 0) { - element = Getitem(elements, 0); - } - /* Now, walk the type list and start emitting */ - for (i = 0; i < nelements; i++) { - if (i < (nelements - 1)) { - nextelement = Getitem(elements, i + 1); - forwardelement = nextelement; - if (SwigType_isqualifier(nextelement)) { - if (i < (nelements - 2)) - forwardelement = Getitem(elements, i + 2); - } - } else { - nextelement = 0; - forwardelement = 0; - } - if (SwigType_isqualifier(element)) { - if (!member_function_qualifiers) { - DOH *q = 0; - q = SwigType_parm(element); - Insert(result, 0, " "); - Insert(result, 0, q); - Delete(q); - clear = 0; - } - } else if (SwigType_ispointer(element)) { - Insert(result, 0, "*"); - if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { - Insert(result, 0, "("); - Append(result, ")"); - } - firstarray = 0; - } else if (SwigType_ismemberpointer(element)) { - String *q; - Insert(result, 0, "::*"); - q = SwigType_parm(element); - Insert(result, 0, q); - if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { - Insert(result, 0, "("); - Append(result, ")"); - } - { - String *next3elements = NewStringEmpty(); - int j; - for (j = i + 1; j < i + 4 && j < nelements; j++) { - Append(next3elements, Getitem(elements, j)); - } - if (SwigType_isfunction(next3elements)) - member_function_qualifiers = SwigType_pop_function_qualifiers(next3elements); - Delete(next3elements); - } - firstarray = 0; - Delete(q); - } else if (SwigType_isreference(element)) { - if (!member_function_qualifiers) { - Insert(result, 0, "&"); - if (!isfunction) - isreference = 1; - } - if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { - Insert(result, 0, "("); - Append(result, ")"); - } - } else if (SwigType_isrvalue_reference(element)) { - if (!member_function_qualifiers) { - Insert(result, 0, "&&"); - if (!isfunction) - isreference = 1; - } - if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) { - Insert(result, 0, "("); - Append(result, ")"); - } - clear = 0; - } else if (SwigType_isarray(element)) { - DOH *size; - if (firstarray && !isreference) { - Append(result, "(*)"); - firstarray = 0; - } else { - Append(result, "["); - size = SwigType_parm(element); - Append(result, size); - Append(result, "]"); - Delete(size); - clear = 0; - } - } else if (SwigType_isfunction(element)) { - DOH *parms, *p; - int j, plen; - Append(result, "("); - parms = SwigType_parmlist(element); - plen = Len(parms); - for (j = 0; j < plen; j++) { - p = SwigType_str(Getitem(parms, j), 0); - Append(result, p); - Delete(p); - if (j < (plen - 1)) - Append(result, ","); - } - Append(result, ")"); - Delete(parms); - if (member_function_qualifiers) { - String *p = SwigType_str(member_function_qualifiers, 0); - Append(result, " "); - Append(result, p); - Delete(p); - Delete(member_function_qualifiers); - member_function_qualifiers = 0; - clear = 0; - } - isfunction = 1; - } else { - String *bs = SwigType_namestr(element); - Insert(result, 0, " "); - Insert(result, 0, bs); - Delete(bs); - } - element = nextelement; - } - Delete(elements); - if (clear) { - cast = NewStringEmpty(); - } else { - cast = NewStringf("(%s)", result); - } - if (name) { - if (isreference) { - Append(cast, "*"); - } - Append(cast, name); - } - Delete(result); - Delete(tc); - return cast; -} - - -/* ----------------------------------------------------------------------------- - * SwigType_lcaststr() - * - * Casts a variable from the real type to the local datatype. - * ----------------------------------------------------------------------------- */ - -String *SwigType_lcaststr(const SwigType *s, const_String_or_char_ptr name) { - String *result; - - result = NewStringEmpty(); - - if (SwigType_isarray(s)) { - String *lstr = SwigType_lstr(s, 0); - Printf(result, "(%s)%s", lstr, name); - Delete(lstr); - } else if (SwigType_isreference(s)) { - String *str = SwigType_str(s, 0); - Printf(result, "(%s)", str); - Delete(str); - if (name) - Append(result, name); - } else if (SwigType_isrvalue_reference(s)) { - String *str = SwigType_str(s, 0); - Printf(result, "(%s)", str); - Delete(str); - if (name) - Append(result, name); - } else if (SwigType_isqualifier(s)) { - String *lstr = SwigType_lstr(s, 0); - Printf(result, "(%s)%s", lstr, name); - Delete(lstr); - } else { - if (name) - Append(result, name); - } - return result; -} - -#if 0 -/* Alternative implementation for manglestr_default. Mangling is similar to the original - except for a few subtle differences for example in templates: - namespace foo { - template<class T> class bar {}; - typedef int Integer; - void test2(bar<Integer *> *x); - } - Mangling is more consistent and changes from - _p_foo__barT_int_p_t to - _p_foo__barT_p_int_t. -*/ -static void mangle_stringcopy(String *destination, const char *source, int count) { - while (count-- > 0) { - char newc = '_'; - if (!(*source == '.' || *source == ':' || *source == ' ')) - newc = *source; - /* TODO: occasionally '*' or numerics need converting to '_', eg in array dimensions and template expressions */ - Putc(newc, destination); - source++; - } -} - -static void mangle_subtype(String *mangled, SwigType *s); - -/* ----------------------------------------------------------------------------- - * mangle_namestr() - * - * Mangles a type taking care of template expansions. Similar to SwigType_namestr(). - * The type may include a trailing '.', for example "p." - * ----------------------------------------------------------------------------- */ - -static void mangle_namestr(String *mangled, SwigType *t) { - int length = Len(t); - if (SwigType_isqualifier(t)) { - Append(mangled, "q_"); - mangle_stringcopy(mangled, Char(t)+2, length-4); - Append(mangled, "__"); - } else if (SwigType_ismemberpointer(t)) { - Append(mangled, "m_"); - mangle_stringcopy(mangled, Char(t)+2, length-4); - Append(mangled, "__"); - } else if (SwigType_isarray(t)) { - Append(mangled, "a_"); - mangle_stringcopy(mangled, Char(t)+2, length-4); - Append(mangled, "__"); - } else if (SwigType_isfunction(t)) { - List *p = SwigType_parmlist(t); - int sz = Len(p); - int i; - Append(mangled, "f_"); - for (i = 0; i < sz; i++) { - mangle_subtype(mangled, Getitem(p, i)); - Putc('_', mangled); - } - Append(mangled, (sz > 0) ? "_" : "__"); - } else if (SwigType_isvarargs(t)) { - Append(mangled, "___"); - } else { - char *d = Char(t); - char *c = strstr(d, "<("); - if (!c || !strstr(c + 2, ")>")) { - /* not a template type */ - mangle_stringcopy(mangled, Char(t), Len(t)); - } else { - /* a template type */ - String *suffix; - List *p; - int i, sz; - mangle_stringcopy(mangled, d, c-d); - Putc('T', mangled); - Putc('_', mangled); - - p = SwigType_parmlist(c + 1); - sz = Len(p); - for (i = 0; i < sz; i++) { - mangle_subtype(mangled, Getitem(p, i)); - Putc('_', mangled); - } - Putc('t', mangled); - suffix = SwigType_templatesuffix(t); - if (Len(suffix) > 0) { - mangle_namestr(mangled, suffix); - } else { - Append(mangled, suffix); - } - Delete(suffix); - Delete(p); - } - } -} - -static void mangle_subtype(String *mangled, SwigType *s) { - List *elements; - int nelements, i; - - assert(s); - elements = SwigType_split(s); - nelements = Len(elements); - for (i = 0; i < nelements; i++) { - SwigType *element = Getitem(elements, i); - mangle_namestr(mangled, element); - } - Delete(elements); -} - -static String *manglestr_default(const SwigType *s) { - String *mangled = NewString("_"); - SwigType *sr = SwigType_typedef_resolve_all(s); - SwigType *sq = SwigType_typedef_qualified(sr); - SwigType *ss = SwigType_remove_global_scope_prefix(sq); - SwigType *type = ss; - SwigType *lt; - - if (SwigType_istemplate(ss)) { - SwigType *ty = Swig_symbol_template_deftype(ss, 0); - Delete(ss); - ss = ty; - type = ss; - } - - lt = SwigType_ltype(type); - - Replace(lt, "struct ", "", DOH_REPLACE_ANY); - Replace(lt, "class ", "", DOH_REPLACE_ANY); - Replace(lt, "union ", "", DOH_REPLACE_ANY); - Replace(lt, "enum ", "", DOH_REPLACE_ANY); - - mangle_subtype(mangled, lt); - - Delete(ss); - Delete(sq); - Delete(sr); - - return mangled; -} - -#else - -static String *manglestr_default(const SwigType *s) { - char *c; - String *result = 0; - String *base = 0; - SwigType *lt; - SwigType *sr = SwigType_typedef_resolve_all(s); - SwigType *sq = SwigType_typedef_qualified(sr); - SwigType *ss = SwigType_remove_global_scope_prefix(sq); - SwigType *type = ss; - - if (SwigType_istemplate(ss)) { - SwigType *ty = Swig_symbol_template_deftype(ss, 0); - Delete(ss); - ss = ty; - type = ss; - } - - lt = SwigType_ltype(type); - result = SwigType_prefix(lt); - base = SwigType_base(lt); - - c = Char(result); - while (*c) { - if (!isalnum((int) *c)) - *c = '_'; - c++; - } - if (SwigType_istemplate(base)) { - String *b = SwigType_namestr(base); - Delete(base); - base = b; - } - - Replace(base, "struct ", "", DOH_REPLACE_ANY); /* This might be problematic */ - Replace(base, "class ", "", DOH_REPLACE_ANY); - Replace(base, "union ", "", DOH_REPLACE_ANY); - Replace(base, "enum ", "", DOH_REPLACE_ANY); - - c = Char(base); - while (*c) { - if (*c == '<') - *c = 'T'; - else if (*c == '>') - *c = 't'; - else if (*c == '*') - *c = 'p'; - else if (*c == '[') - *c = 'a'; - else if (*c == ']') - *c = 'A'; - else if (*c == '&') - *c = 'R'; - else if (*c == '(') - *c = 'f'; - else if (*c == ')') - *c = 'F'; - else if (!isalnum((int) *c)) - *c = '_'; - c++; - } - Append(result, base); - Insert(result, 0, "_"); - Delete(lt); - Delete(base); - Delete(ss); - Delete(sq); - Delete(sr); - return result; -} -#endif - -String *SwigType_manglestr(const SwigType *s) { -#if 0 - /* Debugging checks to ensure a proper SwigType is passed in and not a stringified type */ - String *angle = Strstr(s, "<"); - if (angle && Strncmp(angle, "<(", 2) != 0) - Printf(stderr, "SwigType_manglestr error: %s\n", s); - else if (Strstr(s, "*") || Strstr(s, "&") || Strstr(s, "[")) - Printf(stderr, "SwigType_manglestr error: %s\n", s); -#endif - return manglestr_default(s); -} - -/* ----------------------------------------------------------------------------- - * SwigType_typename_replace() - * - * Replaces a typename in a type with something else. Needed for templates. - * ----------------------------------------------------------------------------- */ - -void SwigType_typename_replace(SwigType *t, String *pat, String *rep) { - String *nt; - int i, ilen; - List *elem; - - if (!Strstr(t, pat)) - return; - - if (Equal(t, pat)) { - Replace(t, pat, rep, DOH_REPLACE_ANY); - return; - } - nt = NewStringEmpty(); - elem = SwigType_split(t); - ilen = Len(elem); - for (i = 0; i < ilen; i++) { - String *e = Getitem(elem, i); - if (SwigType_issimple(e)) { - if (Equal(e, pat)) { - /* Replaces a type of the form 'pat' with 'rep<args>' */ - Replace(e, pat, rep, DOH_REPLACE_ANY); - } else if (SwigType_istemplate(e)) { - /* Replaces a type of the form 'pat<args>' with 'rep' */ - { - /* To match "e=TemplateTemplateT<(float)>" - * with "pat=TemplateTemplateT" - * we need to compare only the first part of the string e. - */ - int len = Len(pat); - - /* Len(e) > len, not >= (because we expect at least a - * character '<' following the template typename) - */ - if (Len(e) > len) { - String *firstPartOfType = NewStringWithSize(e, len); - const char* e_as_char = Char(e); - - if (Equal(firstPartOfType, pat) && e_as_char[len] == '<') { - String *repbase = SwigType_templateprefix(rep); - Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST); - Delete(repbase); - } - Delete(firstPartOfType); - } - } - - { - String *tsuffix; - List *tparms = SwigType_parmlist(e); - int j, jlen; - String *nt = SwigType_templateprefix(e); - Append(nt, "<("); - jlen = Len(tparms); - for (j = 0; j < jlen; j++) { - SwigType_typename_replace(Getitem(tparms, j), pat, rep); - Append(nt, Getitem(tparms, j)); - if (j < (jlen - 1)) - Putc(',', nt); - } - tsuffix = SwigType_templatesuffix(e); - SwigType_typename_replace(tsuffix, pat, rep); - Printf(nt, ")>%s", tsuffix); - Delete(tsuffix); - Clear(e); - Append(e, nt); - Delete(nt); - Delete(tparms); - } - } else if (Swig_scopename_check(e)) { - String *first = 0; - String *rest = 0; - Swig_scopename_split(e, &first, &rest); - - /* Swig_scopename_split doesn't handle :: prefix very well ... could do with a rework */ - if (Strncmp(rest, "::", 2) == 0) { - String *tmp = NewString(Char(rest) + 2); - Clear(rest); - Printv(rest, tmp, NIL); - Delete(tmp); - assert(!first); - } - - Clear(e); - if (first) - SwigType_typename_replace(first, pat, rep); - SwigType_typename_replace(rest, pat, rep); - Printv(e, first ? first : "", "::", rest, NIL); - Delete(first); - Delete(rest); - } - } else if (SwigType_isfunction(e)) { - int j, jlen; - List *fparms = SwigType_parmlist(e); - Clear(e); - Append(e, "f("); - jlen = Len(fparms); - for (j = 0; j < jlen; j++) { - SwigType_typename_replace(Getitem(fparms, j), pat, rep); - Append(e, Getitem(fparms, j)); - if (j < (jlen - 1)) - Putc(',', e); - } - Append(e, ")."); - Delete(fparms); - } else if (SwigType_isarray(e)) { - Replace(e, pat, rep, DOH_REPLACE_ID); - } - Append(nt, e); - } - Clear(t); - Append(t, nt); - Delete(nt); - Delete(elem); -} - -/* ----------------------------------------------------------------------------- - * SwigType_remove_global_scope_prefix() - * - * Removes the unary scope operator (::) prefix indicating global scope in all - * components of the type - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_remove_global_scope_prefix(const SwigType *t) { - SwigType *result; - const char *type = Char(t); - if (strncmp(type, "::", 2) == 0) - type += 2; - result = NewString(type); - Replaceall(result, ".::", "."); - Replaceall(result, "(::", "("); - Replaceall(result, "enum ::", "enum "); - return result; -} - -/* ----------------------------------------------------------------------------- - * SwigType_check_decl() - * - * Checks type declarators for a match - * ----------------------------------------------------------------------------- */ - -int SwigType_check_decl(const SwigType *ty, const SwigType *decl) { - SwigType *t, *t1, *t2; - int r; - t = SwigType_typedef_resolve_all(ty); - t1 = SwigType_strip_qualifiers(t); - t2 = SwigType_prefix(t1); - r = Equal(t2, decl); - Delete(t); - Delete(t1); - Delete(t2); - return r == 1; -} diff --git a/contrib/tools/swig/Source/Swig/swig.h b/contrib/tools/swig/Source/Swig/swig.h deleted file mode 100644 index 19e61b45583..00000000000 --- a/contrib/tools/swig/Source/Swig/swig.h +++ /dev/null @@ -1,451 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * swig.h - * - * Header file for the SWIG core. - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_SWIG_H -#define SWIG_SWIG_H - -#include "swigconfig.h" - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <assert.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#include "doh.h" - -/* Status codes */ - -#define SWIG_OK 1 -#define SWIG_ERROR 0 -#define SWIG_NOWRAP 0 - -/* Global macros */ -#define NSPACE_SEPARATOR "." /* Namespace separator for the nspace feature - this should be changed to a target language configurable variable */ -#define NSPACE_TODO 0 /* Languages that still need to implement and test the nspace feature use this */ - -/* Short names for common data types */ - - typedef DOH String; - typedef DOH Hash; - typedef DOH List; - typedef DOH String_or_char; - typedef DOH File; - typedef DOH Parm; - typedef DOH ParmList; - typedef DOH Node; - typedef DOH Symtab; - typedef DOH Typetab; - typedef DOH SwigType; - -/* --- Legacy DataType interface. These type codes are provided solely - for backwards compatibility with older modules --- */ - -/* --- The ordering of type values is used to determine type-promotion - in the parser. Do not change */ - -/* Numeric types */ - -#define T_BOOL 1 -#define T_SCHAR 2 -#define T_UCHAR 3 -#define T_SHORT 4 -#define T_USHORT 5 -#define T_ENUM 6 -#define T_INT 7 -#define T_UINT 8 -#define T_LONG 9 -#define T_ULONG 10 -#define T_LONGLONG 11 -#define T_ULONGLONG 12 -#define T_FLOAT 20 -#define T_DOUBLE 21 -#define T_LONGDOUBLE 22 -#define T_FLTCPLX 23 -#define T_DBLCPLX 24 -#define T_NUMERIC 25 -#define T_AUTO 26 - -#define T_COMPLEX T_DBLCPLX - -/* non-numeric */ - -#define T_CHAR 29 -#define T_WCHAR 30 -#define T_USER 31 -#define T_VOID 32 -#define T_STRING 33 -#define T_POINTER 34 -#define T_REFERENCE 35 -#define T_ARRAY 36 -#define T_FUNCTION 37 -#define T_MPOINTER 38 -#define T_VARARGS 39 -#define T_RVALUE_REFERENCE 40 -#define T_WSTRING 41 - -#define T_SYMBOL 98 -#define T_ERROR 99 - - - -/* --- File interface --- */ - -#include "swigfile.h" - -/* --- Command line parsing --- */ - -#include "swigopt.h" - -/* --- Scanner Interface --- */ - -#include "swigscan.h" - -/* --- Functions for manipulating the string-based type encoding --- */ - - extern SwigType *NewSwigType(int typecode); - extern SwigType *SwigType_del_element(SwigType *t); - extern SwigType *SwigType_add_pointer(SwigType *t); - extern SwigType *SwigType_add_memberpointer(SwigType *t, const_String_or_char_ptr qual); - extern SwigType *SwigType_del_memberpointer(SwigType *t); - extern SwigType *SwigType_del_pointer(SwigType *t); - extern SwigType *SwigType_add_array(SwigType *t, const_String_or_char_ptr size); - extern SwigType *SwigType_del_array(SwigType *t); - extern SwigType *SwigType_pop_arrays(SwigType *t); - extern SwigType *SwigType_add_reference(SwigType *t); - extern SwigType *SwigType_del_reference(SwigType *t); - extern SwigType *SwigType_add_rvalue_reference(SwigType *t); - extern SwigType *SwigType_del_rvalue_reference(SwigType *t); - extern SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual); - extern SwigType *SwigType_del_qualifier(SwigType *t); - extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms); - extern SwigType *SwigType_add_template(SwigType *t, ParmList *parms); - extern SwigType *SwigType_pop_function(SwigType *t); - extern SwigType *SwigType_pop_function_qualifiers(SwigType *t); - extern ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node); - extern List *SwigType_split(const SwigType *t); - extern String *SwigType_pop(SwigType *t); - extern void SwigType_push(SwigType *t, String *s); - extern SwigType *SwigType_last(SwigType *t); - extern List *SwigType_parmlist(const SwigType *p); - extern String *SwigType_parm(const SwigType *p); - extern String *SwigType_str(const SwigType *s, const_String_or_char_ptr id); - extern String *SwigType_lstr(const SwigType *s, const_String_or_char_ptr id); - extern String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr id); - extern String *SwigType_lcaststr(const SwigType *s, const_String_or_char_ptr id); - extern String *SwigType_manglestr(const SwigType *t); - extern SwigType *SwigType_ltype(const SwigType *t); - extern int SwigType_ispointer(const SwigType *t); - extern int SwigType_ispointer_return(const SwigType *t); - extern int SwigType_isfunctionpointer(const SwigType *t); - extern int SwigType_ismemberpointer(const SwigType *t); - extern int SwigType_isreference(const SwigType *t); - extern int SwigType_isreference_return(const SwigType *t); - extern int SwigType_isrvalue_reference(const SwigType *t); - extern int SwigType_isarray(const SwigType *t); - extern int SwigType_prefix_is_simple_1D_array(const SwigType *t); - extern int SwigType_isfunction(const SwigType *t); - extern int SwigType_isqualifier(const SwigType *t); - extern int SwigType_isconst(const SwigType *t); - extern int SwigType_issimple(const SwigType *t); - extern int SwigType_ismutable(const SwigType *t); - extern int SwigType_isvarargs(const SwigType *t); - extern int SwigType_istemplate(const SwigType *t); - extern int SwigType_isenum(const SwigType *t); - extern int SwigType_check_decl(const SwigType *t, const_String_or_char_ptr decl); - extern SwigType *SwigType_strip_qualifiers(const SwigType *t); - extern SwigType *SwigType_strip_single_qualifier(const SwigType *t); - extern SwigType *SwigType_functionpointer_decompose(SwigType *t); - extern String *SwigType_base(const SwigType *t); - extern String *SwigType_namestr(const SwigType *t); - extern String *SwigType_templateprefix(const SwigType *t); - extern String *SwigType_templatesuffix(const SwigType *t); - extern String *SwigType_istemplate_templateprefix(const SwigType *t); - extern String *SwigType_istemplate_only_templateprefix(const SwigType *t); - extern String *SwigType_templateargs(const SwigType *t); - extern String *SwigType_prefix(const SwigType *t); - extern int SwigType_array_ndim(const SwigType *t); - extern String *SwigType_array_getdim(const SwigType *t, int n); - extern void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep); - extern SwigType *SwigType_array_type(const SwigType *t); - extern SwigType *SwigType_default_create(const SwigType *ty); - extern SwigType *SwigType_default_deduce(const SwigType *t); - extern void SwigType_typename_replace(SwigType *t, String *pat, String *rep); - extern SwigType *SwigType_remove_global_scope_prefix(const SwigType *t); - extern SwigType *SwigType_alttype(const SwigType *t, int ltmap); - -/* --- Type-system management --- */ - extern void SwigType_typesystem_init(void); - extern int SwigType_typedef(const SwigType *type, const_String_or_char_ptr name); - extern int SwigType_typedef_class(const_String_or_char_ptr name); - extern int SwigType_typedef_using(const_String_or_char_ptr qname); - extern void SwigType_inherit(String *subclass, String *baseclass, String *cast, String *conversioncode); - extern int SwigType_issubtype(const SwigType *subtype, const SwigType *basetype); - extern void SwigType_scope_alias(String *aliasname, Typetab *t); - extern void SwigType_using_scope(Typetab *t); - extern void SwigType_new_scope(const_String_or_char_ptr name); - extern void SwigType_inherit_scope(Typetab *scope); - extern Typetab *SwigType_pop_scope(void); - extern Typetab *SwigType_set_scope(Typetab *h); - extern void SwigType_print_scope(void); - extern SwigType *SwigType_typedef_resolve(const SwigType *t); - extern SwigType *SwigType_typedef_resolve_all(const SwigType *t); - extern SwigType *SwigType_typedef_qualified(const SwigType *t); - extern int SwigType_istypedef(const SwigType *t); - extern int SwigType_isclass(const SwigType *t); - extern void SwigType_attach_symtab(Symtab *syms); - extern void SwigType_remember(const SwigType *t); - extern void SwigType_remember_clientdata(const SwigType *t, const_String_or_char_ptr clientdata); - extern void SwigType_remember_mangleddata(String *mangled, const_String_or_char_ptr clientdata); - extern void (*SwigType_remember_trace(void (*tf) (const SwigType *, String *, String *))) (const SwigType *, String *, String *); - extern void SwigType_emit_type_table(File *f_headers, File *f_table); - extern int SwigType_type(const SwigType *t); - -/* --- Symbol table module --- */ - - extern void Swig_symbol_print_tables(Symtab *symtab); - extern void Swig_symbol_print_tables_summary(void); - extern void Swig_symbol_print_symbols(void); - extern void Swig_symbol_print_csymbols(void); - extern void Swig_symbol_init(void); - extern void Swig_symbol_setscopename(const_String_or_char_ptr name); - extern String *Swig_symbol_getscopename(void); - extern String *Swig_symbol_qualifiedscopename(Symtab *symtab); - extern String *Swig_symbol_qualified_language_scopename(Symtab *symtab); - extern Symtab *Swig_symbol_newscope(void); - extern Symtab *Swig_symbol_setscope(Symtab *); - extern Symtab *Swig_symbol_getscope(const_String_or_char_ptr symname); - extern Symtab *Swig_symbol_global_scope(void); - extern Symtab *Swig_symbol_current(void); - extern Symtab *Swig_symbol_popscope(void); - extern Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *node); - extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *node); - extern Node *Swig_symbol_clookup(const_String_or_char_ptr symname, Symtab *tab); - extern Node *Swig_symbol_clookup_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *)); - extern Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n); - extern Symtab *Swig_symbol_cscope(const_String_or_char_ptr symname, Symtab *tab); - extern Node *Swig_symbol_clookup_local(const_String_or_char_ptr symname, Symtab *tab); - extern Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *)); - extern String *Swig_symbol_qualified(Node *node); - extern Node *Swig_symbol_isoverloaded(Node *node); - extern void Swig_symbol_remove(Node *node); - extern void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *tab); - extern void Swig_symbol_inherit(Symtab *tab); - extern SwigType *Swig_symbol_type_qualify(const SwigType *ty, Symtab *tab); - extern String *Swig_symbol_string_qualify(String *s, Symtab *tab); - extern SwigType *Swig_symbol_typedef_reduce(const SwigType *ty, Symtab *tab); - - extern ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl); - extern SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope); - extern SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab); - -/* --- Parameters and Parameter Lists --- */ - -#include "swigparm.h" - -extern String *ParmList_errorstr(ParmList *); -extern int ParmList_is_compactdefargs(ParmList *p); - -/* --- Parse tree support --- */ - -#include "swigtree.h" - -/* -- Wrapper function Object */ - -#include "swigwrap.h" - -/* --- Naming functions --- */ - - extern void Swig_name_register(const_String_or_char_ptr method, const_String_or_char_ptr format); - extern void Swig_name_unregister(const_String_or_char_ptr method); - extern String *Swig_name_mangle(const_String_or_char_ptr s); - extern String *Swig_name_wrapper(const_String_or_char_ptr fname); - extern String *Swig_name_member(const_String_or_char_ptr nspace, const_String_or_char_ptr classname, const_String_or_char_ptr membername); - extern String *Swig_name_get(const_String_or_char_ptr nspace, const_String_or_char_ptr vname); - extern String *Swig_name_set(const_String_or_char_ptr nspace, const_String_or_char_ptr vname); - extern String *Swig_name_construct(const_String_or_char_ptr nspace, const_String_or_char_ptr classname); - extern String *Swig_name_copyconstructor(const_String_or_char_ptr nspace, const_String_or_char_ptr classname); - extern String *Swig_name_destroy(const_String_or_char_ptr nspace, const_String_or_char_ptr classname); - extern String *Swig_name_disown(const_String_or_char_ptr nspace, const_String_or_char_ptr classname); - - extern void Swig_naming_init(void); - extern void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn); - extern void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *namewrn, ParmList *declaratorparms); - extern void Swig_name_inherit(String *base, String *derived); - extern List *Swig_make_inherit_list(String *clsname, List *names, String *Namespaceprefix); - extern void Swig_inherit_base_symbols(List *bases); - extern int Swig_need_protected(Node *n); - extern int Swig_need_redefined_warn(Node *a, Node *b, int InClass); - - extern String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, SwigType *decl, String *oldname); - extern String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl); - extern String *Swig_name_str(Node *n); - extern String *Swig_name_decl(Node *n); - extern String *Swig_name_fulldecl(Node *n); - -/* --- parameterized rename functions --- */ - - extern void Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object); - extern DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl); - extern void Swig_name_object_inherit(Hash *namehash, String *base, String *derived); - extern void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *n); - extern void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, const_String_or_char_ptr value, Hash *featureattribs); - -/* --- Misc --- */ - extern char *Swig_copy_string(const char *c); - extern void Swig_set_fakeversion(const char *version); - extern const char *Swig_package_version(void); - extern String *Swig_package_version_hex(void); - extern void Swig_obligatory_macros(String *f_runtime, const char *language); - extern void Swig_banner(File *f); - extern void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar); - extern String *Swig_strip_c_comments(const String *s); - extern String *Swig_new_subdirectory(String *basedirectory, String *subdirectory); - extern void Swig_filename_correct(String *filename); - extern String *Swig_filename_escape(String *filename); - extern String *Swig_filename_escape_space(String *filename); - extern void Swig_filename_unescape(String *filename); - extern int Swig_storage_isextern(Node *n); - extern int Swig_storage_isexternc(Node *n); - extern int Swig_storage_isstatic_custom(Node *n, const_String_or_char_ptr storage); - extern int Swig_storage_isstatic(Node *n); - extern String *Swig_string_escape(String *s); - extern String *Swig_string_mangle(const String *s); - extern void Swig_scopename_split(const String *s, String **prefix, String **last); - extern String *Swig_scopename_prefix(const String *s); - extern String *Swig_scopename_last(const String *s); - extern String *Swig_scopename_first(const String *s); - extern String *Swig_scopename_suffix(const String *s); - extern List *Swig_scopename_tolist(const String *s); - extern int Swig_scopename_check(const String *s); - extern String *Swig_string_lower(String *s); - extern String *Swig_string_upper(String *s); - extern String *Swig_string_title(String *s); - extern void Swig_offset_string(String *s, int number); - extern String *Swig_pcre_version(void); - extern void Swig_init(void); - - extern int Swig_value_wrapper_mode(int mode); - extern int Swig_is_generated_overload(Node *n); - - typedef enum { EMF_STANDARD, EMF_MICROSOFT } ErrorMessageFormat; - - extern void Swig_warning(int num, const_String_or_char_ptr filename, int line, const char *fmt, ...); - extern void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...); - extern int Swig_error_count(void); - extern void Swig_error_silent(int s); - extern void Swig_warnfilter(const_String_or_char_ptr wlist, int val); - extern void Swig_warnall(void); - extern int Swig_warn_count(void); - extern void Swig_error_msg_format(ErrorMessageFormat format); - extern void Swig_diagnostic(const_String_or_char_ptr filename, int line, const char *fmt, ...); - extern String *Swig_stringify_with_location(DOH *object); - -/* --- C Wrappers --- */ - extern void Swig_cresult_name_set(const char *new_name); - extern const char *Swig_cresult_name(void); - extern String *Swig_cparm_name(Parm *p, int i); - extern String *Swig_wrapped_var_type(SwigType *t, int varcref); - extern int Swig_cargs(Wrapper *w, ParmList *l); - extern String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr decl); - - extern String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms); - extern String *Swig_cconstructor_call(const_String_or_char_ptr name); - extern String *Swig_cppconstructor_call(const_String_or_char_ptr name, ParmList *parms); - extern String *Swig_unref_call(Node *n); - extern String *Swig_ref_call(Node *n, const String *lname); - extern String *Swig_cdestructor_call(Node *n); - extern String *Swig_cppdestructor_call(Node *n); - extern String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, String *self, int varcref); - extern String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String *self, int varcref); - - extern int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self); - extern void Swig_replace_special_variables(Node *n, Node *parentnode, String *code); - -/* --- Transformations --- */ - - extern int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int flags, SwigType *director_type, int is_director); - extern int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags, String *directorname); - extern int Swig_DestructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int cplus, int flags); - extern int Swig_MembersetToFunction(Node *n, String *classname, int flags); - extern int Swig_MembergetToFunction(Node *n, String *classname, int flags); - extern int Swig_VargetToFunction(Node *n, int flags); - extern int Swig_VarsetToFunction(Node *n, int flags); - -#define CWRAP_EXTEND 0x01 -#define CWRAP_SMART_POINTER 0x02 -#define CWRAP_NATURAL_VAR 0x04 -#define CWRAP_DIRECTOR_ONE_CALL 0x08 -#define CWRAP_DIRECTOR_TWO_CALLS 0x10 -#define CWRAP_ALL_PROTECTED_ACCESS 0x20 -#define CWRAP_SMART_POINTER_OVERLOAD 0x40 - -/* --- Director Helpers --- */ - extern Node *Swig_methodclass(Node *n); - extern int Swig_directorclass(Node *n); - extern Node *Swig_directormap(Node *n, String *type); - -/* --- Legacy Typemap API (somewhat simplified, ha!) --- */ - - extern void Swig_typemap_init(void); - extern void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *pattern, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs); - extern int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcpattern, ParmList *pattern); - extern void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *pattern); - extern int Swig_typemap_apply(ParmList *srcpat, ParmList *destpat); - extern void Swig_typemap_clear_apply(ParmList *pattern); - extern void Swig_typemap_replace_embedded_typemap(String *s, Node *file_line_node); - extern void Swig_typemap_debug(void); - extern void Swig_typemap_search_debug_set(void); - extern void Swig_typemap_used_debug_set(void); - extern void Swig_typemap_register_debug_set(void); - - extern String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f); - extern String *Swig_typemap_lookup_out(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f, String *actioncode); - - extern void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f); - -/* --- Code fragment support --- */ - - extern void Swig_fragment_register(Node *fragment); - extern void Swig_fragment_emit(String *name); - extern void Swig_fragment_clear(String *section); - -/* --- Extension support --- */ - - extern Hash *Swig_extend_hash(void); - extern void Swig_extend_merge(Node *cls, Node *am); - extern void Swig_extend_append_previous(Node *cls, Node *am); - extern void Swig_extend_unused_check(void); - -/* hacks defined in C++ ! */ - extern int Swig_director_mode(void); - extern int Swig_director_protected_mode(void); - extern int Swig_all_protected_mode(void); - extern void Wrapper_director_mode_set(int); - extern void Wrapper_director_protected_mode_set(int); - extern void Wrapper_all_protected_mode_set(int); - extern void Language_replace_special_variables(String *method, String *tm, Parm *parm); - extern void Swig_print(DOH *object, int count); - extern void Swig_print_with_location(DOH *object, int count); - -/* -- template init -- */ - extern void SwigType_template_init(void); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/contrib/tools/swig/Source/Swig/swigfile.h b/contrib/tools/swig/Source/Swig/swigfile.h deleted file mode 100644 index 009599a112e..00000000000 --- a/contrib/tools/swig/Source/Swig/swigfile.h +++ /dev/null @@ -1,41 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * swigfile.h - * - * File handling functions in the SWIG core - * ----------------------------------------------------------------------------- */ - -extern List *Swig_add_directory(const_String_or_char_ptr dirname); -extern void Swig_push_directory(const_String_or_char_ptr dirname); -extern void Swig_pop_directory(void); -extern String *Swig_last_file(void); -extern List *Swig_search_path(void); -extern FILE *Swig_include_open(const_String_or_char_ptr name); -extern FILE *Swig_open(const_String_or_char_ptr name); -extern String *Swig_read_file(FILE *f); -extern String *Swig_include(const_String_or_char_ptr name); -extern String *Swig_include_sys(const_String_or_char_ptr name); -extern int Swig_insert_file(const_String_or_char_ptr name, File *outfile); -extern void Swig_set_push_dir(int dopush); -extern int Swig_get_push_dir(void); -extern void Swig_register_filebyname(const_String_or_char_ptr filename, File *outfile); -extern File *Swig_filebyname(const_String_or_char_ptr filename); -extern String *Swig_file_extension(const_String_or_char_ptr filename); -extern String *Swig_file_basename(const_String_or_char_ptr filename); -extern String *Swig_file_filename(const_String_or_char_ptr filename); -extern String *Swig_file_dirname(const_String_or_char_ptr filename); -extern void Swig_file_debug_set(void); - -/* Delimiter used in accessing files and directories */ - -#if defined(_WIN32) -# define SWIG_FILE_DELIMITER "\\" -#else -# define SWIG_FILE_DELIMITER "/" -#endif diff --git a/contrib/tools/swig/Source/Swig/swigopt.h b/contrib/tools/swig/Source/Swig/swigopt.h deleted file mode 100644 index 86a477b8f76..00000000000 --- a/contrib/tools/swig/Source/Swig/swigopt.h +++ /dev/null @@ -1,18 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * swigopt.h - * - * Header file for the SWIG command line processing functions - * ----------------------------------------------------------------------------- */ - - extern void Swig_init_args(int argc, char **argv); - extern void Swig_mark_arg(int n); - extern int Swig_check_marked(int n); - extern void Swig_check_options(int check_input); - extern void Swig_arg_error(void); diff --git a/contrib/tools/swig/Source/Swig/swigparm.h b/contrib/tools/swig/Source/Swig/swigparm.h deleted file mode 100644 index 7b63546ec07..00000000000 --- a/contrib/tools/swig/Source/Swig/swigparm.h +++ /dev/null @@ -1,35 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * swigparm.h - * - * Functions related to the handling of function/method parameters and - * parameter lists. - * ----------------------------------------------------------------------------- */ - -/* Individual parameters */ -extern Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *from_node); -extern Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name); -extern Parm *NewParmNode(SwigType *type, Node *from_node); -extern Parm *CopyParm(Parm *p); - -/* Parameter lists */ -extern ParmList *CopyParmList(ParmList *); -extern ParmList *CopyParmListMax(ParmList *, int count); -extern int ParmList_len(ParmList *); -extern int ParmList_numrequired(ParmList *); -extern int ParmList_has_defaultargs(ParmList *p); -extern int ParmList_has_varargs(ParmList *p); - -/* Output functions */ -extern String *ParmList_str(ParmList *); -extern String *ParmList_str_defaultargs(ParmList *); -extern String *ParmList_str_multibrackets(ParmList *); -extern String *ParmList_protostr(ParmList *); - - diff --git a/contrib/tools/swig/Source/Swig/swigscan.h b/contrib/tools/swig/Source/Swig/swigscan.h deleted file mode 100644 index 6c9d1ff7fce..00000000000 --- a/contrib/tools/swig/Source/Swig/swigscan.h +++ /dev/null @@ -1,119 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * swigscan.h - * - * C/C++ scanner. - * ----------------------------------------------------------------------------- */ - -typedef struct Scanner Scanner; - -extern Scanner *NewScanner(void); -extern void DelScanner(Scanner *); -extern void Scanner_clear(Scanner *); -extern void Scanner_push(Scanner *, String *); -extern void Scanner_pushtoken(Scanner *, int, const_String_or_char_ptr value); -extern int Scanner_token(Scanner *); -extern String *Scanner_text(Scanner *); -extern void Scanner_skip_line(Scanner *); -extern int Scanner_skip_balanced(Scanner *, int startchar, int endchar); -extern String *Scanner_get_raw_text_balanced(Scanner *, int startchar, int endchar); -extern void Scanner_set_location(Scanner *, String *file, int line); -extern String *Scanner_file(Scanner *); -extern int Scanner_line(Scanner *); -extern int Scanner_start_line(Scanner *); -extern void Scanner_idstart(Scanner *, const char *idchar); -extern String *Scanner_errmsg(Scanner *); -extern int Scanner_errline(Scanner *); -extern int Scanner_isoperator(int tokval); -extern void Scanner_locator(Scanner *, String *loc); - -/* Note: Tokens in range 100+ are for C/C++ operators */ - -#define SWIG_MAXTOKENS 200 -#define SWIG_TOKEN_LPAREN 1 /* ( */ -#define SWIG_TOKEN_RPAREN 2 /* ) */ -#define SWIG_TOKEN_SEMI 3 /* ; */ -#define SWIG_TOKEN_LBRACE 4 /* { */ -#define SWIG_TOKEN_RBRACE 5 /* } */ -#define SWIG_TOKEN_LBRACKET 6 /* [ */ -#define SWIG_TOKEN_RBRACKET 7 /* ] */ -#define SWIG_TOKEN_BACKSLASH 8 /* \ */ -#define SWIG_TOKEN_ENDLINE 9 /* \n */ -#define SWIG_TOKEN_STRING 10 /* "str" */ -#define SWIG_TOKEN_POUND 11 /* # */ -#define SWIG_TOKEN_COLON 12 /* : */ -#define SWIG_TOKEN_DCOLON 13 /* :: */ -#define SWIG_TOKEN_DCOLONSTAR 14 /* ::* */ -#define SWIG_TOKEN_ID 15 /* identifier */ -#define SWIG_TOKEN_FLOAT 16 /* 3.1415F */ -#define SWIG_TOKEN_DOUBLE 17 /* 3.1415 */ -#define SWIG_TOKEN_INT 18 /* 314 */ -#define SWIG_TOKEN_UINT 19 /* 314U */ -#define SWIG_TOKEN_LONG 20 /* 314L */ -#define SWIG_TOKEN_ULONG 21 /* 314UL */ -#define SWIG_TOKEN_CHAR 22 /* 'charconst' */ -#define SWIG_TOKEN_PERIOD 23 /* . */ -#define SWIG_TOKEN_AT 24 /* @ */ -#define SWIG_TOKEN_DOLLAR 25 /* $ */ -#define SWIG_TOKEN_CODEBLOCK 26 /* %{ ... %} ... */ -#define SWIG_TOKEN_RSTRING 27 /* `charconst` */ -#define SWIG_TOKEN_LONGLONG 28 /* 314LL */ -#define SWIG_TOKEN_ULONGLONG 29 /* 314ULL */ -#define SWIG_TOKEN_QUESTION 30 /* ? */ -#define SWIG_TOKEN_COMMENT 31 /* C or C++ comment */ -#define SWIG_TOKEN_BOOL 32 /* true or false */ -#define SWIG_TOKEN_WSTRING 33 /* L"str" */ -#define SWIG_TOKEN_WCHAR 34 /* L'c' */ -#define SWIG_TOKEN_ELLIPSIS 35 /* ... */ -#define SWIG_TOKEN_LLBRACKET 36 /* [[ */ -#define SWIG_TOKEN_RRBRACKET 37 /* ]] */ - -#define SWIG_TOKEN_ILLEGAL 99 -#define SWIG_TOKEN_ERROR -1 - -#define SWIG_TOKEN_COMMA 101 /* , */ -#define SWIG_TOKEN_STAR 102 /* * */ -#define SWIG_TOKEN_TIMES 102 /* * */ -#define SWIG_TOKEN_EQUAL 103 /* = */ -#define SWIG_TOKEN_EQUALTO 104 /* == */ -#define SWIG_TOKEN_NOTEQUAL 105 /* != */ -#define SWIG_TOKEN_PLUS 106 /* + */ -#define SWIG_TOKEN_MINUS 107 /* - */ -#define SWIG_TOKEN_AND 108 /* & */ -#define SWIG_TOKEN_LAND 109 /* && */ -#define SWIG_TOKEN_OR 110 /* | */ -#define SWIG_TOKEN_LOR 111 /* || */ -#define SWIG_TOKEN_XOR 112 /* ^ */ -#define SWIG_TOKEN_LESSTHAN 113 /* < */ -#define SWIG_TOKEN_GREATERTHAN 114 /* > */ -#define SWIG_TOKEN_LTEQUAL 115 /* <= */ -#define SWIG_TOKEN_GTEQUAL 116 /* >= */ -#define SWIG_TOKEN_NOT 117 /* ~ */ -#define SWIG_TOKEN_LNOT 118 /* ! */ -#define SWIG_TOKEN_SLASH 119 /* / */ -#define SWIG_TOKEN_DIVIDE 119 /* / */ -#define SWIG_TOKEN_PERCENT 120 /* % */ -#define SWIG_TOKEN_MODULO 120 /* % */ -#define SWIG_TOKEN_LSHIFT 121 /* << */ -#define SWIG_TOKEN_RSHIFT 122 /* >> */ -#define SWIG_TOKEN_PLUSPLUS 123 /* ++ */ -#define SWIG_TOKEN_MINUSMINUS 124 /* -- */ -#define SWIG_TOKEN_PLUSEQUAL 125 /* += */ -#define SWIG_TOKEN_MINUSEQUAL 126 /* -= */ -#define SWIG_TOKEN_TIMESEQUAL 127 /* *= */ -#define SWIG_TOKEN_DIVEQUAL 128 /* /= */ -#define SWIG_TOKEN_ANDEQUAL 129 /* &= */ -#define SWIG_TOKEN_OREQUAL 130 /* |= */ -#define SWIG_TOKEN_XOREQUAL 131 /* ^= */ -#define SWIG_TOKEN_LSEQUAL 132 /* <<= */ -#define SWIG_TOKEN_RSEQUAL 133 /* >>= */ -#define SWIG_TOKEN_MODEQUAL 134 /* %= */ -#define SWIG_TOKEN_ARROW 135 /* -> */ -#define SWIG_TOKEN_ARROWSTAR 136 /* ->* */ -#define SWIG_TOKEN_LTEQUALGT 137 /* <=> */ diff --git a/contrib/tools/swig/Source/Swig/swigtree.h b/contrib/tools/swig/Source/Swig/swigtree.h deleted file mode 100644 index 8d63d8fd33f..00000000000 --- a/contrib/tools/swig/Source/Swig/swigtree.h +++ /dev/null @@ -1,54 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * swigtree.h - * - * These functions are used to access and manipulate the SWIG parse tree. - * The structure of this tree is modeled directly after XML-DOM. The attribute - * and function names are meant to be similar. - * ----------------------------------------------------------------------------- */ - -/* Macros to traverse the DOM tree */ - -#define nodeType(x) Getattr(x,"nodeType") -#define parentNode(x) Getattr(x,"parentNode") -#define previousSibling(x) Getattr(x,"previousSibling") -#define nextSibling(x) Getattr(x,"nextSibling") -#define firstChild(x) Getattr(x,"firstChild") -#define lastChild(x) Getattr(x,"lastChild") - -/* Macros to set up the DOM tree (mostly used by the parser) */ - -#define set_nodeType(x,v) Setattr(x,"nodeType",v) -#define set_parentNode(x,v) Setattr(x,"parentNode",v) -#define set_previousSibling(x,v) Setattr(x,"previousSibling",v) -#define set_nextSibling(x,v) Setattr(x,"nextSibling",v) -#define set_firstChild(x,v) Setattr(x,"firstChild",v) -#define set_lastChild(x,v) Setattr(x,"lastChild",v) - -/* Utility functions */ - -extern int checkAttribute(Node *obj, const_String_or_char_ptr name, const_String_or_char_ptr value); -extern void appendChild(Node *node, Node *child); -extern void prependChild(Node *node, Node *child); -extern void removeNode(Node *node); -extern Node *copyNode(Node *node); -extern void appendSibling(Node *node, Node *child); - -/* Node restoration/restore functions */ - -extern void Swig_require(const char *ns, Node *node, ...); -extern void Swig_save(const char *ns, Node *node, ...); -extern void Swig_restore(Node *node); - -/* Debugging of parse trees */ - -extern void Swig_print_tags(File *obj, Node *root); -extern void Swig_print_tree(Node *obj); -extern void Swig_print_node(Node *obj); -extern int Swig_print_quiet(int quiet); diff --git a/contrib/tools/swig/Source/Swig/swigwrap.h b/contrib/tools/swig/Source/Swig/swigwrap.h deleted file mode 100644 index b584ca495ba..00000000000 --- a/contrib/tools/swig/Source/Swig/swigwrap.h +++ /dev/null @@ -1,31 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * swigwrap.h - * - * Functions related to wrapper objects. - * ----------------------------------------------------------------------------- */ - -typedef struct Wrapper { - Hash *localh; - String *def; - String *locals; - String *code; -} Wrapper; - -extern Wrapper *NewWrapper(void); -extern void DelWrapper(Wrapper *w); -extern void Wrapper_compact_print_mode_set(int flag); -extern void Wrapper_pretty_print(String *str, File *f); -extern void Wrapper_compact_print(String *str, File *f); -extern void Wrapper_print(Wrapper *w, File *f); -extern int Wrapper_add_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl); -extern int Wrapper_add_localv(Wrapper *w, const_String_or_char_ptr name, ...); -extern int Wrapper_check_local(Wrapper *w, const_String_or_char_ptr name); -extern char *Wrapper_new_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl); -extern char *Wrapper_new_localv(Wrapper *w, const_String_or_char_ptr name, ...); diff --git a/contrib/tools/swig/Source/Swig/symbol.c b/contrib/tools/swig/Source/Swig/symbol.c deleted file mode 100644 index 107b1caef9d..00000000000 --- a/contrib/tools/swig/Source/Swig/symbol.c +++ /dev/null @@ -1,2128 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * symbol.c - * - * This file implements the SWIG symbol table. See details below. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "cparse.h" -#include <ctype.h> - -/* #define SWIG_DEBUG*/ -/* ----------------------------------------------------------------------------- - * Synopsis - * - * This module provides symbol table management for all of SWIG. In previous - * releases, the management of symbols was rather haphazard. This module tries - * to correct that. - * - * All symbols are associated with simple identifiers. For example, here are some - * declarations that generate symbol table entries: - * - * decl symbol - * -------------- ------------ - * void foo(int); foo - * int x; x - * typedef int *blah; blah - * - * Associated with each symbol is a Hash table that can contain any set of - * attributes that make sense for that object. For example: - * - * typedef int *blah; ----> "name" : 'blah' - * "type" : 'int' - * "decl" : 'p.' - * "storage" : 'typedef' - * - * In some cases, the symbol table needs to manage overloaded entries. For instance, - * overloaded functions. In this case, a linked list is built. The "sym:nextSibling" - * attribute is reserved to hold a link to the next entry. For example: - * - * int foo(int); --> "name" : "foo" "name" : "foo" - * int foo(int,double); "type" : "int" "type" : "int" - * "decl" : "f(int)." "decl" : "f(int,double)." - * ... ... - * "sym:nextSibling" : --------> "sym:nextSibling": --------> ... - * - * When more than one symbol has the same name, the symbol declarator is - * used to detect duplicates. For example, in the above case, foo(int) and - * foo(int,double) are different because their "decl" attribute is different. - * However, if a third declaration "foo(int)" was made, it would generate a - * conflict (due to having a declarator that matches a previous entry). - * - * Structures and classes: - * - * C/C++ symbol tables are normally managed in a few different spaces. The - * most visible namespace is reserved for functions, variables, typedef, enum values - * and such. In C, a separate tag-space is reserved for 'struct name', 'class name', - * and 'union name' declarations. In SWIG, a single namespace is used for everything - * this means that certain incompatibilities will arise with some C programs. For instance: - * - * struct Foo { - * ... - * } - * - * int Foo(); // Error. Name clash. Works in C though - * - * Due to the unified namespace for structures, special handling is performed for - * the following: - * - * typedef struct Foo { - * - * } Foo; - * - * In this case, the symbol table contains an entry for the structure itself. The - * typedef is left out of the symbol table. - * - * Target language vs C: - * - * The symbol tables are normally managed *in the namespace of the target language*. - * This means that name-collisions can be resolved using %rename and related - * directives. A quirk of this is that sometimes the symbol tables need to - * be used for C type resolution as well. To handle this, each symbol table - * also has a C-symbol table lurking behind the scenes. This is used to locate - * symbols in the C namespace. However, this symbol table is not used for error - * reporting nor is it used for anything else during code generation. - * - * Symbol table structure: - * - * Symbol tables themselves are a special kind of node that is organized just like - * a normal parse tree node. Symbol tables are organized in a tree that can be - * traversed using the SWIG-DOM API. The following attributes names are reserved. - * - * name -- Name of the scope defined by the symbol table (if any) - * This name is the C-scope name and is not affected by - * %renaming operations - * symtab -- Hash table mapping identifiers to nodes. - * csymtab -- Hash table mapping C identifiers to nodes. - * - * Reserved attributes on symbol objects: - * - * When a symbol is placed in the symbol table, the following attributes - * are set: - * - * sym:name -- Symbol name - * sym:nextSibling -- Next symbol (if overloaded) - * sym:previousSibling -- Previous symbol (if overloaded) - * sym:symtab -- Symbol table object holding the symbol - * sym:overloaded -- Set to the first symbol if overloaded - * - * These names are modeled after XML namespaces. In particular, every attribute - * pertaining to symbol table management is prefaced by the "sym:" prefix. - * - * An example dump of the parse tree showing symbol table entries for the - * following code should clarify this: - * - * namespace OuterNamespace { - * namespace InnerNamespace { - * class Class { - * }; - * struct Struct { - * int Var; - * }; - * } - * } - * - * +++ namespace ---------------------------------------- - * | sym:name - "OuterNamespace" - * | symtab - 0xa064bf0 - * | sym:symtab - 0xa041690 - * | sym:overname - "__SWIG_0" - * - * +++ namespace ---------------------------------------- - * | sym:name - "InnerNamespace" - * | symtab - 0xa064cc0 - * | sym:symtab - 0xa064bf0 - * | sym:overname - "__SWIG_0" - * - * +++ class ---------------------------------------- - * | sym:name - "Class" - * | symtab - 0xa064d80 - * | sym:symtab - 0xa064cc0 - * | sym:overname - "__SWIG_0" - * | - * +++ class ---------------------------------------- - * | sym:name - "Struct" - * | symtab - 0xa064f00 - * | sym:symtab - 0xa064cc0 - * | sym:overname - "__SWIG_0" - * - * +++ cdecl ---------------------------------------- - * | sym:name - "Var" - * | sym:symtab - 0xa064f00 - * | sym:overname - "__SWIG_0" - * | - * - * - * Each class and namespace has its own scope and thus a new symbol table (sym) - * is created. The sym attribute is only set for the first entry in the symbol - * table. The sym:symtab entry points to the symbol table in which the symbol - * exists, so for example, Struct is in the scope OuterNamespace::InnerNamespace - * so sym:symtab points to this symbol table (0xa064cc0). - * - * ----------------------------------------------------------------------------- */ - -static Hash *current = 0; /* The current symbol table hash */ -static Hash *ccurrent = 0; /* The current c symbol table hash */ -static Hash *current_symtab = 0; /* Current symbol table node */ -static Hash *symtabs = 0; /* Hash of all symbol tables by fully-qualified name */ -static Hash *global_scope = 0; /* Global scope */ - -static int use_inherit = 1; - -/* common attribute keys, to avoid calling find_key all the times */ - - -/* ----------------------------------------------------------------------------- - * Swig_symbol_print_tables() - * - * Debug display of symbol tables - * ----------------------------------------------------------------------------- */ - -void Swig_symbol_print_tables(Symtab *symtab) { - if (!symtab) - symtab = current_symtab; - - Printf(stdout, "SYMBOL TABLES start =======================================\n"); - Swig_print_tree(symtab); - Printf(stdout, "SYMBOL TABLES finish =======================================\n"); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_print_tables_summary() - * - * Debug summary display of all symbol tables by fully-qualified name - * ----------------------------------------------------------------------------- */ - -void Swig_symbol_print_tables_summary(void) { - Printf(stdout, "SYMBOL TABLES SUMMARY start =======================================\n"); - Swig_print_node(symtabs); - Printf(stdout, "SYMBOL TABLES SUMMARY finish =======================================\n"); -} - -/* ----------------------------------------------------------------------------- - * symbol_print_symbols() - * ----------------------------------------------------------------------------- */ - -static void symbol_print_symbols(const char *symboltabletype, const char *nextSibling) { - Node *table = symtabs; - Iterator ki = First(table); - int show_pointers = 0; - while (ki.key) { - String *k = ki.key; - Printf(stdout, "===================================================\n"); - Printf(stdout, "%s -\n", k); - { - Symtab *symtab = Getattr(Getattr(table, k), symboltabletype); - Iterator it = First(symtab); - while (it.key) { - String *symname = it.key; - Printf(stdout, " %s (%s)", symname, nodeType(it.item)); - if (show_pointers) - Printf(stdout, " %p", it.item); - Printf(stdout, "\n"); - { - Node *sibling = Getattr(it.item, nextSibling); - while (sibling) { - Printf(stdout, " %s (%s)", symname, nodeType(sibling)); - if (show_pointers) - Printf(stdout, " %p", sibling); - Printf(stdout, "\n"); - sibling = Getattr(sibling, nextSibling); - } - } - it = Next(it); - } - } - ki = Next(ki); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_print_symbols() - * - * Debug display of all the target language symbols - * ----------------------------------------------------------------------------- */ - -void Swig_symbol_print_symbols(void) { - Printf(stdout, "SYMBOLS start =======================================\n"); - symbol_print_symbols("symtab", "sym:nextSibling"); - Printf(stdout, "SYMBOLS finish =======================================\n"); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_print_csymbols() - * - * Debug display of all the C symbols - * ----------------------------------------------------------------------------- */ - -void Swig_symbol_print_csymbols(void) { - Printf(stdout, "CSYMBOLS start =======================================\n"); - symbol_print_symbols("csymtab", "csym:nextSibling"); - Printf(stdout, "CSYMBOLS finish =======================================\n"); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_init() - * - * Create a new symbol table object - * ----------------------------------------------------------------------------- */ - -void Swig_symbol_init(void) { - - current = NewHash(); - current_symtab = NewHash(); - ccurrent = NewHash(); - set_nodeType(current_symtab, "symboltable"); - Setattr(current_symtab, "symtab", current); - Delete(current); - Setattr(current_symtab, "csymtab", ccurrent); - Delete(ccurrent); - - /* Set the global scope */ - symtabs = NewHash(); - Setattr(symtabs, "", current_symtab); - Delete(current_symtab); - global_scope = current_symtab; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_setscopename() - * - * Set the C scopename of the current symbol table. - * ----------------------------------------------------------------------------- */ - -void Swig_symbol_setscopename(const_String_or_char_ptr name) { - String *qname; - /* assert(!Getattr(current_symtab,"name")); */ - Setattr(current_symtab, "name", name); - - /* Set nested scope in parent */ - - qname = Swig_symbol_qualifiedscopename(current_symtab); - - /* Save a reference to this scope */ - Setattr(symtabs, qname, current_symtab); - Delete(qname); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_getscopename() - * - * Get the C scopename of the current symbol table - * ----------------------------------------------------------------------------- */ - -String *Swig_symbol_getscopename(void) { - return Getattr(current_symtab, "name"); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_getscope() - * - * Given a fully qualified C scopename, this function returns a symbol table - * ----------------------------------------------------------------------------- */ - -Symtab *Swig_symbol_getscope(const_String_or_char_ptr name) { - if (!symtabs) - return 0; - if (Equal("::", (const_String_or_char_ptr ) name)) - name = ""; - return Getattr(symtabs, name); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_qualifiedscopename() - * - * Get the fully qualified C scopename of a symbol table. Note, this only pertains - * to the C/C++ scope name. It is not affected by renaming. - * ----------------------------------------------------------------------------- */ - -String *Swig_symbol_qualifiedscopename(Symtab *symtab) { - String *result = 0; - Hash *parent; - String *name; - if (!symtab) - symtab = current_symtab; - parent = Getattr(symtab, "parentNode"); - if (parent) { - result = Swig_symbol_qualifiedscopename(parent); - } - name = Getattr(symtab, "name"); - if (name) { - if (!result) { - result = NewStringEmpty(); - } - if (Len(result)) { - Printv(result, "::", name, NIL); - } else { - Append(result, name); - } - } - return result; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_qualified_language_scopename() - * - * Get the fully qualified C scopename of a symbol table but using a language - * specific separator for the scopenames. Basically the same as - * Swig_symbol_qualifiedscopename() but using the different separator. - * ----------------------------------------------------------------------------- */ - -String *Swig_symbol_qualified_language_scopename(Symtab *n) { - /* TODO: fix for %rename to work */ - String *result = Swig_symbol_qualifiedscopename(n); - Replaceall(result, "::", NSPACE_SEPARATOR); - return result; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_newscope() - * - * Create a new scope. Returns the newly created scope. - * ----------------------------------------------------------------------------- */ - -Symtab *Swig_symbol_newscope(void) { - Hash *n; - Hash *hsyms, *h; - - hsyms = NewHash(); - h = NewHash(); - - set_nodeType(h, "symboltable"); - Setattr(h, "symtab", hsyms); - Delete(hsyms); - set_parentNode(h, current_symtab); - - n = lastChild(current_symtab); - if (!n) { - set_firstChild(current_symtab, h); - } else { - set_nextSibling(n, h); - Delete(h); - } - set_lastChild(current_symtab, h); - current = hsyms; - ccurrent = NewHash(); - Setattr(h, "csymtab", ccurrent); - Delete(ccurrent); - current_symtab = h; - return h; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_setscope() - * - * Set the current scope. Returns the previous current scope. - * ----------------------------------------------------------------------------- */ - -Symtab *Swig_symbol_setscope(Symtab *sym) { - Symtab *ret = current_symtab; - current_symtab = sym; - current = Getattr(sym, "symtab"); - assert(current); - ccurrent = Getattr(sym, "csymtab"); - assert(ccurrent); - return ret; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_popscope() - * - * Pop out of the current scope. Returns the popped scope and sets the - * scope to the parent scope. - * ----------------------------------------------------------------------------- */ - -Symtab *Swig_symbol_popscope(void) { - Hash *h = current_symtab; - current_symtab = Getattr(current_symtab, "parentNode"); - assert(current_symtab); - current = Getattr(current_symtab, "symtab"); - assert(current); - ccurrent = Getattr(current_symtab, "csymtab"); - assert(ccurrent); - return h; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_global_scope() - * - * Return the symbol table for the global scope. - * ----------------------------------------------------------------------------- */ - -Symtab *Swig_symbol_global_scope(void) { - return global_scope; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_current() - * - * Return the current symbol table. - * ----------------------------------------------------------------------------- */ - -Symtab *Swig_symbol_current(void) { - return current_symtab; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_alias() - * - * Makes an alias for a symbol in the global symbol table. - * Primarily for namespace aliases such as 'namespace X = Y;'. - * ----------------------------------------------------------------------------- */ - -void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *s) { - String *qname = Swig_symbol_qualifiedscopename(current_symtab); - if (qname) { - Printf(qname, "::%s", aliasname); - } else { - qname = NewString(aliasname); - } - if (!Getattr(symtabs, qname)) { - Setattr(symtabs, qname, s); - } - Delete(qname); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_inherit() - * - * Inherit symbols from another scope. Primarily for C++ inheritance and - * for using directives, such as 'using namespace X;' - * but not for using declarations, such as 'using A;'. - * ----------------------------------------------------------------------------- */ - -void Swig_symbol_inherit(Symtab *s) { - int i, ilen; - List *inherit = Getattr(current_symtab, "inherit"); - if (!inherit) { - inherit = NewList(); - Setattr(current_symtab, "inherit", inherit); - Delete(inherit); - } - - if (s == current_symtab) { - Swig_warning(WARN_PARSE_REC_INHERITANCE, Getfile(s), Getline(s), "Recursive scope inheritance of '%s'.\n", Getattr(s, "name")); - return; - } - assert(s != current_symtab); - ilen = Len(inherit); - for (i = 0; i < ilen; i++) { - Node *n = Getitem(inherit, i); - if (n == s) - return; /* Already inherited */ - } - Append(inherit, s); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_cadd() - * - * Adds a node to the C symbol table only. - * ----------------------------------------------------------------------------- */ - -void Swig_symbol_cadd(const_String_or_char_ptr name, Node *n) { - Node *append = 0; - Node *cn; - /* There are a few options for weak symbols. A "weak" symbol - is any symbol that can be replaced by another symbol in the C symbol - table. An example would be a forward class declaration. A forward - class sits in the symbol table until a real class declaration comes along. - - Certain symbols are marked as "sym:typename". These are important - symbols related to the C++ type-system and take precedence in the C - symbol table. An example might be code like this: - - template<class T> T foo(T x); - int foo(int); - - In this case, the template is marked with "sym:typename" so that it - stays in the C symbol table (so that it can be expanded using %template). - */ - - if (!name) - return; - - if (SwigType_istemplate(name)) { - String *cname = NewString(name); - String *dname = Swig_symbol_template_deftype(cname, 0); - if (!Equal(dname, name)) { - Swig_symbol_cadd(dname, n); - } - Delete(dname); - Delete(cname); - } -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_cadd %s %p\n", name, n); -#endif - cn = Getattr(ccurrent, name); - - if (cn && (Getattr(cn, "sym:typename"))) { - /* The node in the C symbol table is a typename. Do nothing */ - /* We might append the symbol at the end */ - append = n; - } else if (cn && (Getattr(cn, "sym:weak"))) { - /* The node in the symbol table is weak. Replace it */ - if (checkAttribute(cn, "nodeType", "template") - && checkAttribute(cn, "templatetype", "classforward")) { - /* The node is a template classforward declaration, and the - default template parameters here take precedence. */ - ParmList *pc = Getattr(cn, "templateparms"); - ParmList *pn = Getattr(n, "templateparms"); -#ifdef SWIG_DEBUG - Printf(stderr, "found template classforward %s\n", Getattr(cn, "name")); -#endif - while (pc && pn) { - String *value = Getattr(pc, "value"); - if (value) { -#ifdef SWIG_DEBUG - Printf(stderr, "add default template value %s %s\n", Getattr(pc, "name"), value); -#endif - Setattr(pn, "value", value); - } - pc = nextSibling(pc); - pn = nextSibling(pn); - } - Setattr(n, "templateparms", Getattr(cn, "templateparms")); - } - Setattr(ccurrent, name, n); - - } else if (cn && (Getattr(n, "sym:weak"))) { - /* The node being added is weak. Don't worry about it */ - } else if (cn && (Getattr(n, "sym:typename"))) { - /* The node being added is a typename. We definitely add it */ - Setattr(ccurrent, name, n); - append = cn; - } else if (cn && (Checkattr(cn, "nodeType", "templateparm"))) { - Swig_error(Getfile(n), Getline(n), "Declaration of '%s' shadows template parameter,\n", name); - Swig_error(Getfile(cn), Getline(cn), "previous template parameter declaration '%s'.\n", name); - return; - } else if (cn) { - append = n; - } else if (!cn) { - /* No conflict. Add the symbol */ - Setattr(ccurrent, name, n); - } - - /* Multiple entries in the C symbol table. We append to the symbol table */ - if (append) { - Node *fn, *pn = 0; - cn = Getattr(ccurrent, name); - fn = cn; - while (fn) { - pn = fn; - if (fn == append) { - /* already added. Bail */ - return; - } - fn = Getattr(fn, "csym:nextSibling"); - } - if (pn) { - Setattr(pn, "csym:nextSibling", append); - } - } - - /* Special typedef handling. When a typedef node is added to the symbol table, we - might have to add a type alias. This would occur if the typedef mapped to another - scope in the system. For example: - - class Foo { - }; - - typedef Foo OtherFoo; - - In this case, OtherFoo becomes an alias for Foo. */ - - { - Node *td = n; - while (td && ((Equal(nodeType(td), "cdecl") && Checkattr(td, "storage", "typedef")) || (Equal(nodeType(td), "using") && !Getattr(n, "namespace")))) { - SwigType *type; - Node *td1; - int using_not_typedef = Equal(nodeType(td), "using"); - type = Copy(Getattr(td, using_not_typedef ? "uname" : "type")); - SwigType_push(type, Getattr(td, "decl")); - td1 = Swig_symbol_clookup(type, 0); - - /* Fix pathetic case #1214313: - - class Foo - { - }; - - typedef Foo FooBar; - - class CBaz - { - public: - typedef FooBar Foo; - }; - - ie, when Foo -> FooBar -> Foo, jump one scope up when possible. - - */ - if (td1) { - String *st = 0; - String *sn = Getattr(td, "name"); - if (Equal(nodeType(td1), "cdecl") && Checkattr(td1, "storage", "typedef")) - st = Getattr(td1, "type"); - else if (Equal(nodeType(td1), "using") && !Getattr(td1, "namespace")) - st = Getattr(td1, "uname"); - if (st && sn && Equal(st, sn)) { - Symtab *sc = Getattr(current_symtab, "parentNode"); - if (sc) - td1 = Swig_symbol_clookup(type, sc); - } - } - - Delete(type); - if (td1 == td) - break; - td = td1; - if (td) { - Symtab *st = Getattr(td, "symtab"); - if (st) { - Swig_symbol_alias(Getattr(n, "name"), st); - break; - } - } - } - } -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_add() - * - * Adds a node to the symbol table. Returns the node itself if successfully - * added. Otherwise, it returns the symbol table entry of the conflicting node. - * - * Also places the symbol in a behind-the-scenes C symbol table. This is needed - * for namespace support, type resolution, and other issues. - * ----------------------------------------------------------------------------- */ - -Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) { - Hash *c, *cl = 0; - SwigType *decl, *ndecl; - String *cstorage, *nstorage; - int nt = 0, ct = 0; - int pn = 0; - int u1 = 0, u2 = 0; - String *name, *overname; - - /* See if the node has a name. If so, we place in the C symbol table for this - scope. We don't worry about overloading here---the primary purpose of this - is to record information for type/name resolution for later. Conflicts - in C namespaces are errors, but these will be caught by the C++ compiler - when compiling the wrapper code */ - - - /* There are a few options for weak symbols. A "weak" symbol - is any symbol that can be replaced by another symbol in the C symbol - table. An example would be a forward class declaration. A forward - class sits in the symbol table until a real class declaration comes along. - - Certain symbols are marked as "sym:typename". These are important - symbols related to the C++ type-system and take precedence in the C - symbol table. An example might be code like this: - - template<class T> T foo(T x); - int foo(int); - - In this case, the template is marked with "sym:typename" so that it - stays in the C symbol table (so that it can be expanded using %template). - */ - - name = Getattr(n, "name"); - if (name && Len(name)) { - Swig_symbol_cadd(name, n); - } - - /* No symbol name defined. We return. */ - if (!symname) { - Setattr(n, "sym:symtab", current_symtab); - return n; - } - - /* If node is ignored. We don't proceed any further */ - if (GetFlag(n, "feature:ignore")) - return n; - - /* See if the symbol already exists in the table */ - c = Getattr(current, symname); - - /* Check for a weak symbol. A weak symbol is allowed to be in the - symbol table, but is silently overwritten by other symbols. An example - would be a forward class declaration. For instance: - - class Foo; - - In this case, "Foo" sits in the symbol table. However, the - definition of Foo would replace the entry if it appeared later. */ - - if (c && Getattr(c, "sym:weak")) { - c = 0; - } - if (c) { - /* There is a symbol table conflict. There are a few cases to consider here: - (1) A conflict between a class/enum and a typedef declaration is okay. - In this case, the symbol table entry is set to the class/enum declaration - itself, not the typedef. - (2) A conflict between namespaces is okay--namespaces are open - (3) Otherwise, overloading is only allowed for functions - (4) This special case is okay: a class template instantiated with same name as the template's name - */ - - /* Check for namespaces */ - String *ntype = Getattr(n, "nodeType"); - if ((Equal(ntype, Getattr(c, "nodeType"))) && ((Equal(ntype, "namespace")))) { - Node *cl, *pcl = 0; - cl = c; - while (cl) { - pcl = cl; - cl = Getattr(cl, "sym:nextSibling"); - } - Setattr(pcl, "sym:nextSibling", n); - Setattr(n, "sym:symtab", current_symtab); - Setattr(n, "sym:name", symname); - Setattr(n, "sym:previousSibling", pcl); - return n; - } - - /* Special case: class template instantiated with same name as the template's name eg: %template(X) X<int>; */ - if (Equal(nodeType(c), "template")) { - String *nt1 = Getattr(c, "templatetype"); - String *nt2 = nodeType(n); - if (Equal(nt1, "class") && Equal(nt1, nt2)) { - if (Getattr(n, "template")) { - /* Finally check that another %template with same name doesn't already exist */ - if (!Getattr(c, "sym:nextSibling")) { - Setattr(c, "sym:nextSibling", n); - Setattr(n, "sym:symtab", current_symtab); - Setattr(n, "sym:name", symname); - Setattr(n, "sym:previousSibling", c); - return n; - } - } - } - } - - if (Getattr(n, "allows_typedef")) - nt = 1; - if (Getattr(c, "allows_typedef")) - ct = 1; - if (nt || ct) { - Node *td, *other; - String *s; - /* At least one of the nodes allows typedef overloading. Make sure that - both don't--this would be a conflict */ - - if (nt && ct) - return c; - - /* Figure out which node allows the typedef */ - if (nt) { - td = n; - other = c; - } else { - td = c; - other = n; - } - /* Make sure the other node is a typedef */ - s = Getattr(other, "storage"); - if (!s || (!Equal(s, "typedef"))) - return c; /* No. This is a conflict */ - - /* Hmmm. This appears to be okay. Make sure the symbol table refers to the allow_type node */ - - if (td != c) { - Setattr(current, symname, td); - Setattr(td, "sym:symtab", current_symtab); - Setattr(td, "sym:name", symname); - } - return n; - } - - decl = Getattr(c, "decl"); - ndecl = Getattr(n, "decl"); - - { - String *nt1, *nt2; - nt1 = Getattr(n, "nodeType"); - if (Equal(nt1, "template")) - nt1 = Getattr(n, "templatetype"); - nt2 = Getattr(c, "nodeType"); - if (Equal(nt2, "template")) - nt2 = Getattr(c, "templatetype"); - if (Equal(nt1, "using")) - u1 = 1; - if (Equal(nt2, "using")) - u2 = 1; - - if ((!Equal(nt1, nt2)) && !(u1 || u2)) - return c; - } - if (!(u1 || u2)) { - if ((!SwigType_isfunction(decl)) || (!SwigType_isfunction(ndecl))) { - /* Symbol table conflict */ - return c; - } - } - - /* Hmmm. Declarator seems to indicate that this is a function */ - /* Look at storage class to see if compatible */ - cstorage = Getattr(c, "storage"); - nstorage = Getattr(n, "storage"); - - /* If either one is declared as typedef, forget it. We're hosed */ - if (Cmp(cstorage, "typedef") == 0) { - return c; - } - if (Cmp(nstorage, "typedef") == 0) { - return c; - } - - /* Okay. Walk down the list of symbols and see if we get a declarator match */ - { - String *nt = Getattr(n, "nodeType"); - int n_template = Equal(nt, "template") && Checkattr(n, "templatetype", "cdecl"); - int n_plain_cdecl = Equal(nt, "cdecl"); - Node *cn = c; - pn = 0; - while (cn) { - decl = Getattr(cn, "decl"); - if (!(u1 || u2)) { - if (Cmp(ndecl, decl) == 0) { - /* Declarator conflict */ - /* Now check we don't have a non-templated function overloaded by a templated function with same params, - * eg void foo(); template<typename> void foo(); */ - String *cnt = Getattr(cn, "nodeType"); - int cn_template = Equal(cnt, "template") && Checkattr(cn, "templatetype", "cdecl"); - int cn_plain_cdecl = Equal(cnt, "cdecl"); - if (!((n_template && cn_plain_cdecl) || (cn_template && n_plain_cdecl))) { - /* found a conflict */ - return cn; - } - } - } - cl = cn; - cn = Getattr(cn, "sym:nextSibling"); - pn++; - } - } - /* Well, we made it this far. Guess we can drop the symbol in place */ - Setattr(n, "sym:symtab", current_symtab); - Setattr(n, "sym:name", symname); - /* Printf(stdout,"%s %p\n", Getattr(n,"sym:overname"), current_symtab); */ - assert(!Getattr(n, "sym:overname")); - overname = NewStringf("__SWIG_%d", pn); - Setattr(n, "sym:overname", overname); - /*Printf(stdout,"%s %s %s\n", symname, Getattr(n,"decl"), Getattr(n,"sym:overname")); */ - Setattr(cl, "sym:nextSibling", n); - Setattr(n, "sym:previousSibling", cl); - Setattr(cl, "sym:overloaded", c); - Setattr(n, "sym:overloaded", c); - Delete(overname); - return n; - } - - /* No conflict. Just add it */ - Setattr(n, "sym:symtab", current_symtab); - Setattr(n, "sym:name", symname); - /* Printf(stdout,"%s\n", Getattr(n,"sym:overname")); */ - overname = NewStringf("__SWIG_%d", pn); - Setattr(n, "sym:overname", overname); - Delete(overname); - /* Printf(stdout,"%s %s %s\n", symname, Getattr(n,"decl"), Getattr(n,"sym:overname")); */ - Setattr(current, symname, n); - return n; -} - -/* ----------------------------------------------------------------------------- - * symbol_lookup() - * - * Internal function to handle fully qualified symbol table lookups. This - * works from the symbol table supplied in symtab and unwinds its way out - * towards the global scope. - * - * This function operates in the C namespace, not the target namespace. - * - * The check function is an optional callback that can be used to verify a particular - * symbol match. This is only used in some of the more exotic parts of SWIG. For instance, - * verifying that a class hierarchy implements all pure virtual methods. - * ----------------------------------------------------------------------------- */ - -static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (Node *n)) { - Node *n; - List *inherit; - Hash *sym = Getattr(symtab, "csymtab"); - if (Getmark(symtab)) - return 0; - Setmark(symtab, 1); - - n = Getattr(sym, name); - -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_look %s %p %p %s\n", name, n, symtab, Getattr(symtab, "name")); -#endif - - if (n) { - /* if a check-function is defined. Call it to determine a match */ - if (check) { - int c = check(n); - if (c == 1) { - Setmark(symtab, 0); - return n; - } - if (c < 0) { - /* Terminate the search right away */ - Setmark(symtab, 0); - return 0; - } - } else { - Setmark(symtab, 0); - return n; - } - } - - if (!n && SwigType_istemplate(name)) { - String *dname = 0; - Setmark(symtab, 0); - dname = Swig_symbol_template_deftype(name, symtab); - if (!Equal(dname, name)) { - n = _symbol_lookup(dname, symtab, check); - } - Delete(dname); - if (n) - return n; - Setmark(symtab, 1); - } - - inherit = Getattr(symtab, "inherit"); - if (inherit && use_inherit) { - int i, len; - len = Len(inherit); - for (i = 0; i < len; i++) { - n = _symbol_lookup(name, Getitem(inherit, i), check); - if (n) { - Setmark(symtab, 0); - return n; - } - } - } - - Setmark(symtab, 0); - return 0; -} - -static Node *symbol_lookup(const_String_or_char_ptr name, Symtab *symtab, int (*check) (Node *n)) { - Node *n = 0; - if (DohCheck(name)) { - n = _symbol_lookup(name, symtab, check); - } else { - String *sname = NewString(name); - n = _symbol_lookup(sname, symtab, check); - Delete(sname); - } - return n; -} - - - -/* ----------------------------------------------------------------------------- - * symbol_lookup_qualified() - * ----------------------------------------------------------------------------- */ - -static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symtab, const String *prefix, int local, int (*checkfunc) (Node *n)) { - /* This is a little funky, we search by fully qualified names */ - - if (!symtab) - return 0; - if (!prefix) { - Node *n; - String *bname = 0; - String *prefix = 0; - Swig_scopename_split(name, &prefix, &bname); - n = symbol_lookup_qualified(bname, symtab, prefix, local, checkfunc); - Delete(bname); - Delete(prefix); - return n; - } else { - Symtab *st; - Node *n = 0; - /* Make qualified name of current scope */ - String *qalloc = 0; - String *qname = Swig_symbol_qualifiedscopename(symtab); - const String *cqname; - if (qname) { - if (Len(qname)) { - if (prefix && Len(prefix)) { - Printv(qname, "::", prefix, NIL); - } - } else { - Append(qname, prefix); - } - qalloc = qname; - cqname = qname; - } else { - cqname = prefix; - } - st = Getattr(symtabs, cqname); - /* Found a scope match */ - if (st) { - if (!name) { - if (qalloc) - Delete(qalloc); - return st; - } - n = symbol_lookup(name, st, checkfunc); - } - if (qalloc) - Delete(qalloc); - - if (!n) { - if (!local) { - Node *pn = Getattr(symtab, "parentNode"); - if (pn) - n = symbol_lookup_qualified(name, pn, prefix, local, checkfunc); - - /* Check inherited scopes */ - if (!n) { - List *inherit = Getattr(symtab, "inherit"); - if (inherit && use_inherit) { - int i, len; - len = Len(inherit); - for (i = 0; i < len; i++) { - Node *prefix_node = symbol_lookup(prefix, Getitem(inherit, i), checkfunc); - if (prefix_node) { - Node *prefix_symtab = Getattr(prefix_node, "symtab"); - if (prefix_symtab) { - n = symbol_lookup(name, prefix_symtab, checkfunc); - break; - } - } - } - } - } - } else { - n = 0; - } - } - return n; - } -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_clookup() - * - * Look up a symbol in the symbol table. This uses the C name, not scripting - * names. Note: If we come across a using declaration, we follow it to - * to get the real node. Any using directives are also followed (but this is - * implemented in symbol_lookup()). - * ----------------------------------------------------------------------------- */ - -Node *Swig_symbol_clookup(const_String_or_char_ptr name, Symtab *n) { - Hash *hsym = 0; - Node *s = 0; - - if (!n) { - hsym = current_symtab; - } else { - if (!Checkattr(n, "nodeType", "symboltable")) { - n = Getattr(n, "sym:symtab"); - } - assert(n); - if (n) { - hsym = n; - } - } - - if (Swig_scopename_check(name)) { - char *cname = Char(name); - if (strncmp(cname, "::", 2) == 0) { - String *nname = NewString(cname + 2); - if (Swig_scopename_check(nname)) { - s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0); - } else { - s = symbol_lookup(nname, global_scope, 0); - } - Delete(nname); - } else { - String *prefix = Swig_scopename_prefix(name); - if (prefix) { - s = symbol_lookup_qualified(name, hsym, 0, 0, 0); - Delete(prefix); - if (!s) { - return 0; - } - } - } - } - if (!s) { - while (hsym) { - s = symbol_lookup(name, hsym, 0); - if (s) - break; - hsym = Getattr(hsym, "parentNode"); - if (!hsym) - break; - } - } - - if (!s) { - return 0; - } - /* Check if s is a 'using' node */ - while (s && Checkattr(s, "nodeType", "using")) { - String *uname = Getattr(s, "uname"); - Symtab *un = Getattr(s, "sym:symtab"); - Node *ss = (!Equal(name, uname) || (un != n)) ? Swig_symbol_clookup(uname, un) : 0; /* avoid infinity loop */ - if (!ss) { - SWIG_WARN_NODE_BEGIN(s); - Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname"))); - SWIG_WARN_NODE_END(s); - } - s = ss; - } - return s; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_clookup_check() - * - * This function is identical to Swig_symbol_clookup() except that it - * accepts a callback function that is invoked to determine a symbol match. - * The purpose of this function is to support complicated algorithms that need - * to examine multiple definitions of the same symbol that might appear in an - * inheritance hierarchy. - * ----------------------------------------------------------------------------- */ - -Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *n)) { - Hash *hsym = 0; - Node *s = 0; - - if (!n) { - hsym = current_symtab; - } else { - if (!Checkattr(n, "nodeType", "symboltable")) { - n = Getattr(n, "sym:symtab"); - } - assert(n); - if (n) { - hsym = n; - } - } - - if (Swig_scopename_check(name)) { - char *cname = Char(name); - if (strncmp(cname, "::", 2) == 0) { - String *nname = NewString(cname + 2); - if (Swig_scopename_check(nname)) { - s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc); - } else { - s = symbol_lookup(nname, global_scope, checkfunc); - } - Delete(nname); - } else { - String *prefix = Swig_scopename_prefix(name); - if (prefix) { - s = symbol_lookup_qualified(name, hsym, 0, 0, checkfunc); - Delete(prefix); - if (!s) { - return 0; - } - } - } - } - if (!s) { - while (hsym) { - s = symbol_lookup(name, hsym, checkfunc); - if (s) - break; - hsym = Getattr(hsym, "parentNode"); - if (!hsym) - break; - } - } - if (!s) { - return 0; - } - /* Check if s is a 'using' node */ - while (s && Checkattr(s, "nodeType", "using")) { - Node *ss; - ss = Swig_symbol_clookup(Getattr(s, "uname"), Getattr(s, "sym:symtab")); - if (!ss && !checkfunc) { - SWIG_WARN_NODE_BEGIN(s); - Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname"))); - SWIG_WARN_NODE_END(s); - } - s = ss; - } - return s; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_clookup_local() - * - * Same as Swig_symbol_clookup but parent nodes are not searched, that is, just - * this symbol table is searched. - * ----------------------------------------------------------------------------- */ - -Node *Swig_symbol_clookup_local(const_String_or_char_ptr name, Symtab *n) { - Hash *hsym; - Node *s = 0; - - if (!n) { - hsym = current_symtab; - } else { - if (!Checkattr(n, "nodeType", "symboltable")) { - n = Getattr(n, "sym:symtab"); - } - assert(n); - hsym = n; - } - - if (Swig_scopename_check(name)) { - char *cname = Char(name); - if (strncmp(cname, "::", 2) == 0) { - String *nname = NewString(cname + 2); - if (Swig_scopename_check(nname)) { - s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0); - } else { - s = symbol_lookup(nname, global_scope, 0); - } - Delete(nname); - } else { - s = symbol_lookup_qualified(name, hsym, 0, 0, 0); - } - } - if (!s) { - s = symbol_lookup(name, hsym, 0); - } - if (!s) - return 0; - /* Check if s is a 'using' node */ - while (s && Checkattr(s, "nodeType", "using")) { - Node *ss = Swig_symbol_clookup_local(Getattr(s, "uname"), Getattr(s, "sym:symtab")); - if (!ss) { - SWIG_WARN_NODE_BEGIN(s); - Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname"))); - SWIG_WARN_NODE_END(s); - } - s = ss; - } - return s; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_clookup_local_check() - * ----------------------------------------------------------------------------- */ - -Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *)) { - Hash *hsym; - Node *s = 0; - - if (!n) { - hsym = current_symtab; - } else { - if (!Checkattr(n, "nodeType", "symboltable")) { - n = Getattr(n, "sym:symtab"); - } - assert(n); - hsym = n; - } - - if (Swig_scopename_check(name)) { - char *cname = Char(name); - if (strncmp(cname, "::", 2) == 0) { - String *nname = NewString(cname + 2); - if (Swig_scopename_check(nname)) { - s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc); - } else { - s = symbol_lookup(nname, global_scope, checkfunc); - } - Delete(nname); - } else { - s = symbol_lookup_qualified(name, hsym, 0, 0, checkfunc); - } - } - if (!s) { - s = symbol_lookup(name, hsym, checkfunc); - } - if (!s) - return 0; - /* Check if s is a 'using' node */ - while (s && Checkattr(s, "nodeType", "using")) { - Node *ss = Swig_symbol_clookup_local_check(Getattr(s, "uname"), Getattr(s, "sym:symtab"), checkfunc); - if (!ss && !checkfunc) { - SWIG_WARN_NODE_BEGIN(s); - Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname"))); - SWIG_WARN_NODE_END(s); - } - s = ss; - } - return s; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_clookup_no_inherit() - * - * Symbol lookup like Swig_symbol_clookup but does not follow using declarations. - * ----------------------------------------------------------------------------- */ - -Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n) { - Node *s = 0; - assert(use_inherit==1); - use_inherit = 0; - s = Swig_symbol_clookup(name, n); - use_inherit = 1; - return s; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_cscope() - * - * Look up a scope name. - * ----------------------------------------------------------------------------- */ - -Symtab *Swig_symbol_cscope(const_String_or_char_ptr name, Symtab *symtab) { - char *cname = Char(name); - if (strncmp(cname, "::", 2) == 0) - return symbol_lookup_qualified(0, global_scope, name, 0, 0); - return symbol_lookup_qualified(0, symtab, name, 0, 0); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_remove() - * - * Remove a symbol. If the symbol is an overloaded function and the symbol removed - * is not the last in the list of overloaded functions, then the overloaded - * names (sym:overname attribute) are changed to start from zero, eg __SWIG_0. - * ----------------------------------------------------------------------------- */ - -void Swig_symbol_remove(Node *n) { - Symtab *symtab; - String *symname; - String *overname; - Node *symprev; - Node *symnext; - Node *fixovername = 0; - symtab = Getattr(n, "sym:symtab"); /* Get symbol table object */ - symtab = Getattr(symtab, "symtab"); /* Get actual hash table of symbols */ - symname = Getattr(n, "sym:name"); - symprev = Getattr(n, "sym:previousSibling"); - symnext = Getattr(n, "sym:nextSibling"); - - /* If previous symbol, just fix the links */ - if (symprev) { - if (symnext) { - Setattr(symprev, "sym:nextSibling", symnext); - fixovername = symprev; /* fix as symbol to remove is somewhere in the middle of the linked list */ - } else { - Delattr(symprev, "sym:nextSibling"); - } - } else { - /* If no previous symbol, see if there is a next symbol */ - if (symnext) { - Setattr(symtab, symname, symnext); - fixovername = symnext; /* fix as symbol to remove is at head of linked list */ - } else { - if (symname) - Delattr(symtab, symname); - } - } - if (symnext) { - if (symprev) { - Setattr(symnext, "sym:previousSibling", symprev); - } else { - Delattr(symnext, "sym:previousSibling"); - } - } - Delattr(n, "sym:symtab"); - Delattr(n, "sym:previousSibling"); - Delattr(n, "sym:nextSibling"); - Delattr(n, "csym:nextSibling"); - Delattr(n, "sym:overname"); - Delattr(n, "csym:previousSibling"); - Delattr(n, "sym:overloaded"); - n = 0; - - if (fixovername) { - Node *nn = fixovername; - Node *head = fixovername; - int pn = 0; - - /* find head of linked list */ - while (nn) { - head = nn; - nn = Getattr(nn, "sym:previousSibling"); - } - - /* adjust all the sym:overname strings to start from 0 and increment by one */ - nn = head; - while (nn) { - assert(Getattr(nn, "sym:overname")); - Delattr(nn, "sym:overname"); - overname = NewStringf("__SWIG_%d", pn); - Setattr(nn, "sym:overname", overname); - Delete(overname); - pn++; - nn = Getattr(nn, "sym:nextSibling"); - } - } -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_qualified() - * - * Return the qualified name of a symbol - * ----------------------------------------------------------------------------- */ - -String *Swig_symbol_qualified(Node *n) { - Hash *symtab; - if (Checkattr(n, "nodeType", "symboltable")) { - symtab = n; - } else { - symtab = Getattr(n, "sym:symtab"); - } - if (!symtab) - return NewStringEmpty(); -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_qscope %s %p %s\n", Getattr(n, "name"), symtab, Getattr(symtab, "name")); -#endif - return Swig_symbol_qualifiedscopename(symtab); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_isoverloaded() - * - * Check if a symbol is overloaded. Returns the first symbol if so. - * ----------------------------------------------------------------------------- */ - -Node *Swig_symbol_isoverloaded(Node *n) { - return Getattr(n, "sym:overloaded"); -} - -/* ----------------------------------------------------------------------------- - * symbol_template_qualify() - * - * Internal function to create a fully qualified type name for templates - * ----------------------------------------------------------------------------- */ - -/* This cache produces problems with OSS, don't active it */ -/* #define SWIG_TEMPLATE_QUALIFY_CACHE */ -static SwigType *symbol_template_qualify(const SwigType *e, Symtab *st) { - String *tprefix, *tsuffix; - SwigType *qprefix; - String *targs; - List *targslist; - Node *tempn; - Symtab *tscope; - Iterator ti; -#ifdef SWIG_TEMPLATE_QUALIFY_CACHE - static Hash *qualify_cache = 0; - String *scopetype = st ? NewStringf("%s::%s", Getattr(st, "name"), e) - : NewStringf("%s::%s", Swig_symbol_getscopename(), e); - if (!qualify_cache) { - qualify_cache = NewHash(); - } - if (scopetype) { - String *cres = Getattr(qualify_cache, scopetype); - if (cres) { - Delete(scopetype); - return Copy(cres); - } - } -#endif - - tprefix = SwigType_templateprefix(e); - tsuffix = SwigType_templatesuffix(e); - qprefix = Swig_symbol_type_qualify(tprefix, st); - targs = SwigType_templateargs(e); - targslist = SwigType_parmlist(targs); - tempn = Swig_symbol_clookup_local(tprefix, st); - tscope = tempn ? Getattr(tempn, "sym:symtab") : 0; - Append(qprefix, "<("); - for (ti = First(targslist); ti.item;) { - String *vparm; - /* TODO: the logic here should be synchronised with that in SwigType_typedef_qualified() */ - /* TODO: ti.item might be a non-type parameter possibly within (), eg: (std::is_integral_v<(A)>||std::is_same_v<(A,node_t)>) */ - String *qparm = Swig_symbol_type_qualify(ti.item, st); - if (tscope && (tscope != st)) { - String *ty = Swig_symbol_type_qualify(qparm, tscope); - Delete(qparm); - qparm = ty; - } - - vparm = Swig_symbol_template_param_eval(qparm, st); - Append(qprefix, vparm); - ti = Next(ti); - if (ti.item) { - Putc(',', qprefix); - } - Delete(qparm); - Delete(vparm); - } - Append(qprefix, ")>"); - Append(qprefix, tsuffix); - Delete(tprefix); - Delete(tsuffix); - Delete(targs); - Delete(targslist); -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_temp_qual %s %s\n", e, qprefix); -#endif -#ifdef SWIG_TEMPLATE_QUALIFY_CACHE - Setattr(qualify_cache, scopetype, qprefix); - Delete(scopetype); -#endif - - return qprefix; -} - - -static int symbol_no_constructor(Node *n) { - return !Checkattr(n, "nodeType", "constructor"); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_type_qualify() - * - * Create a fully qualified type name - * Note: Does not resolve a constructor if passed in as the 'type'. - * ----------------------------------------------------------------------------- */ - -SwigType *Swig_symbol_type_qualify(const SwigType *t, Symtab *st) { - List *elements; - String *result = NewStringEmpty(); - int i, len; - char *c = Char(t); - if (strncmp(c, "::", 2) == 0) { - Append(result, t); - return result; - } - - elements = SwigType_split(t); - - len = Len(elements); - for (i = 0; i < len; i++) { - String *e = Getitem(elements, i); - if (SwigType_issimple(e)) { - /* Note: the unary scope operator (::) is being removed from the template parameters here. */ - Node *n = Swig_symbol_clookup_check(e, st, symbol_no_constructor); - if (n) { - String *name = Getattr(n, "name"); - Clear(e); - Append(e, name); -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_qual_ei %d %s %s %p\n", i, name, e, st); -#endif - if (!Swig_scopename_check(name)) { - String *qname = Swig_symbol_qualified(n); - if (qname && Len(qname)) { - Insert(e, 0, "::"); - Insert(e, 0, qname); - } -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_qual_sc %d %s %s %p\n", i, qname, e, st); -#endif - Delete(qname); - } - } else if (SwigType_istemplate(e)) { - SwigType *ty = symbol_template_qualify(e, st); - Clear(e); - Append(e, ty); - Delete(ty); - } - if (strncmp(Char(e), "::", 2) == 0) { - Delitem(e, 0); - Delitem(e, 0); - } - Append(result, e); - } else if (SwigType_isfunction(e)) { - List *parms = SwigType_parmlist(e); - String *s = NewString("f("); - Iterator pi = First(parms); - while (pi.item) { - String *pf = Swig_symbol_type_qualify(pi.item, st); - Append(s, pf); - pi = Next(pi); - if (pi.item) { - Append(s, ","); - } - Delete(pf); - } - Append(s, ")."); - Append(result, s); - Delete(parms); - Delete(s); - } else { - Append(result, e); - } - } - Delete(elements); -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_qualify %s %s %p %s\n", t, result, st, st ? Getattr(st, "name") : 0); -#endif - - return result; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_template_reduce() - * Resolves template parameter types - * For example: - * typedef int Int; - * typedef Int Integer; - * with input: - * Foo<(Int,Integer)> - * returns: - * Foo<(int,int)> - * ----------------------------------------------------------------------------- */ - -static -SwigType *Swig_symbol_template_reduce(SwigType *qt, Symtab *ntab) { - Parm *p; - String *templateargs = SwigType_templateargs(qt); - List *parms = SwigType_parmlist(templateargs); - Iterator pi = First(parms); - String *tprefix = SwigType_templateprefix(qt); - String *tsuffix = SwigType_templatesuffix(qt); - String *qprefix = SwigType_typedef_qualified(tprefix); - Append(qprefix, "<("); - while ((p = pi.item)) { - String *np; - String *tp = Swig_symbol_typedef_reduce(p, ntab); - String *qp = Swig_symbol_type_qualify(tp, ntab); - Node *n = Swig_symbol_clookup(qp, ntab); - if (n) { - String *qual = Swig_symbol_qualified(n); - np = Copy(Getattr(n, "name")); - Delete(tp); - tp = np; - if (qual && Len(qual)) { - Insert(np, 0, "::"); - Insert(np, 0, qual); - } - Delete(qual); - } else { - np = qp; - } - Append(qprefix, np); - pi = Next(pi); - if (pi.item) { - Append(qprefix, ","); - } - Delete(qp); - Delete(tp); - } - Append(qprefix, ")>"); - Append(qprefix, tsuffix); - Delete(parms); - Delete(tprefix); - Delete(tsuffix); - Delete(templateargs); - return qprefix; -} - - -/* ----------------------------------------------------------------------------- - * Swig_symbol_typedef_reduce() - * - * Chase a typedef through symbol tables looking for a match. - * ----------------------------------------------------------------------------- */ - -SwigType *Swig_symbol_typedef_reduce(const SwigType *ty, Symtab *tab) { - SwigType *prefix, *base; - Node *n; - String *nt; - - base = SwigType_base(ty); - prefix = SwigType_prefix(ty); - - n = Swig_symbol_clookup(base, tab); - if (!n) { - if (SwigType_istemplate(ty)) { - SwigType *qt = Swig_symbol_template_reduce(base, tab); - Append(prefix, qt); - Delete(qt); -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_reduce (a) %s %s\n", ty, prefix); -#endif - Delete(base); - return prefix; - } else { - Delete(prefix); -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_reduce (b) %s %s\n", ty, ty); -#endif - return Copy(ty); - } - } - nt = Getattr(n, "nodeType"); - if (Equal(nt, "using")) { - String *uname = Getattr(n, "uname"); - if (uname) { - n = Swig_symbol_clookup(base, Getattr(n, "sym:symtab")); - if (!n) { - Delete(base); - Delete(prefix); -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_reduce (c) %s %s\n", ty, ty); -#endif - return Copy(ty); - } - } - } - if (Equal(nt, "cdecl")) { - String *storage = Getattr(n, "storage"); - if (storage && (Equal(storage, "typedef"))) { - SwigType *decl; - SwigType *rt; - SwigType *qt; - Symtab *ntab; - SwigType *nt = Copy(Getattr(n, "type")); - - /* Fix for case 'typedef struct Hello hello;' */ - { - const char *dclass[3] = { "struct ", "union ", "class " }; - int i; - char *c = Char(nt); - for (i = 0; i < 3; i++) { - if (strstr(c, dclass[i]) == c) { - Replace(nt, dclass[i], "", DOH_REPLACE_FIRST); - } - } - } - decl = Getattr(n, "decl"); - if (decl) { - SwigType_push(nt, decl); - } - SwigType_push(nt, prefix); - Delete(base); - Delete(prefix); - ntab = Getattr(n, "sym:symtab"); - rt = Swig_symbol_typedef_reduce(nt, ntab); - qt = Swig_symbol_type_qualify(rt, ntab); - if (SwigType_istemplate(qt)) { - SwigType *qtr = Swig_symbol_template_reduce(qt, ntab); - Delete(qt); - qt = qtr; - } - Delete(nt); - Delete(rt); -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_reduce (d) %s %s\n", qt, ty); -#endif - return qt; - } - } - Delete(base); - Delete(prefix); -#ifdef SWIG_DEBUG - Printf(stderr, "symbol_reduce (e) %s %s\n", ty, ty); -#endif - return Copy(ty); -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_string_qualify() - * - * This function takes a string and looks for identifiers. Identifiers are - * then qualified according to scope rules. This function is used in a number - * of settings including expression evaluation, scoping of conversion operators, - * and so forth. - * ----------------------------------------------------------------------------- */ - -String *Swig_symbol_string_qualify(String *s, Symtab *st) { - int have_id = 0; - String *id = NewStringEmpty(); - String *r = NewStringEmpty(); - char *c = Char(s); - int first_char = 1; - while (*c) { - if (isalpha((int) *c) || (*c == '_') || (*c == ':') || (*c == '~' && first_char) || (isdigit((int) *c) && !first_char)) { - Putc(*c, id); - have_id = 1; - } else { - if (have_id) { - String *qid = Swig_symbol_type_qualify(id, st); - Append(r, qid); - Clear(id); - Delete(qid); - have_id = 0; - } - Putc(*c, r); - } - first_char = (*c == ':'); - c++; - } - if (have_id) { - String *qid = Swig_symbol_type_qualify(id, st); - Append(r, qid); - Delete(qid); - } - Delete(id); - return r; -} - - -/* ----------------------------------------------------------------------------- - * Swig_symbol_template_defargs() - * - * Apply default arg from generic template default args - * Returns a parameter list which contains missing default arguments (if any) - * Note side effects: parms will also contain the extra parameters in its list - * (but only if non-zero). - * ----------------------------------------------------------------------------- */ - - -ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, Symtab *tsdecl) { - ParmList *expandedparms = parms; - if (Len(parms) < Len(targs)) { - Parm *lp = parms; - Parm *p = lp; - Parm *tp = targs; - while (p && tp) { - p = nextSibling(p); - tp = nextSibling(tp); - if (p) - lp = p; - } - while (tp) { - String *value = Getattr(tp, "value"); - if (value) { - Parm *cp; - Parm *ta = targs; - Parm *p = parms; - SwigType *nt = Swig_symbol_string_qualify(value, tsdecl); - SwigType *ntq = 0; -#ifdef SWIG_DEBUG - Printf(stderr, "value %s %s %s\n", value, nt, tsdecl ? Getattr(tsdecl, "name") : tsdecl); -#endif - while (p && ta) { - String *name = Getattr(ta, "name"); - String *pvalue = Getattr(p, "value"); - String *value = pvalue ? pvalue : Getattr(p, "type"); - String *ttq = Swig_symbol_type_qualify(value, tscope); - /* value = SwigType_typedef_resolve_all(value); */ - Replaceid(nt, name, ttq); - p = nextSibling(p); - ta = nextSibling(ta); - Delete(ttq); - } - ntq = Swig_symbol_type_qualify(nt, tsdecl); - if (SwigType_istemplate(ntq)) { - String *ty = Swig_symbol_template_deftype(ntq, tscope); - Delete(ntq); - ntq = ty; - } - cp = NewParmWithoutFileLineInfo(ntq, 0); - if (lp) { - set_nextSibling(lp, cp); - Delete(cp); - } else { - expandedparms = cp; - } - lp = cp; - tp = nextSibling(tp); - Delete(nt); - Delete(ntq); - } else { - tp = 0; - } - } - } - return expandedparms; -} - -/* ----------------------------------------------------------------------------- - * Swig_symbol_template_deftype() - * - * Apply default args to generic template type - * ----------------------------------------------------------------------------- */ - -#define SWIG_TEMPLATE_DEFTYPE_CACHE -SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) { - String *result = NewStringEmpty(); - List *elements = SwigType_split(type); - int len = Len(elements); - int i; -#ifdef SWIG_TEMPLATE_DEFTYPE_CACHE - static Hash *s_cache = 0; - Hash *scope_cache; - /* The lookup depends on the current scope and potential namespace qualification. - Looking up x in namespace y is not the same as looking up x::y in outer scope. - -> we use a 2-level hash: first scope and then symbol. */ - String *scope_name = tscope - ? Swig_symbol_qualifiedscopename(tscope) - : Swig_symbol_qualifiedscopename(current_symtab); - String *type_name = tscope - ? NewStringf("%s::%s", Getattr(tscope, "name"), type) - : NewStringf("%s::%s", Swig_symbol_getscopename(), type); - if (!scope_name) scope_name = NewString("::"); - if (!s_cache) { - s_cache = NewHash(); - } - scope_cache = Getattr(s_cache, scope_name); - if (scope_cache) { - String *cres = Getattr(scope_cache, type_name); - if (cres) { - Append(result, cres); -#ifdef SWIG_DEBUG - Printf(stderr, "cached deftype %s(%s) -> %s\n", type, scope_name, result); -#endif - Delete(type_name); - Delete(scope_name); - return result; - } - } else { - scope_cache = NewHash(); - Setattr(s_cache, scope_name, scope_cache); - Delete(scope_name); - } -#endif - -#ifdef SWIG_DEBUG - Printf(stderr, "finding deftype %s\n", type); -#endif - - for (i = 0; i < len; i++) { - String *e = Getitem(elements, i); - if (SwigType_isfunction(e)) { - String *s = NewString("f("); - List *parms = SwigType_parmlist(e); - Iterator pi = First(parms); - while (pi.item) { - String *pf = SwigType_istemplate(e) ? Swig_symbol_template_deftype(pi.item, tscope) - : Swig_symbol_type_qualify(pi.item, tscope); - Append(s, pf); - pi = Next(pi); - if (pi.item) { - Append(s, ","); - } - Delete(pf); - } - Append(s, ")."); - Append(result, s); - Delete(s); - Delete(parms); - } else if (SwigType_istemplate(e)) { - String *prefix = SwigType_prefix(e); - String *base = SwigType_base(e); - String *tprefix = SwigType_templateprefix(base); - String *targs = SwigType_templateargs(base); - String *tsuffix = SwigType_templatesuffix(base); - ParmList *tparms = SwigType_function_parms(targs, 0); - Node *tempn = Swig_symbol_clookup_local(tprefix, tscope); - if (!tempn && tsuffix && Len(tsuffix)) { - tempn = Swig_symbol_clookup(tprefix, 0); - } -#ifdef SWIG_DEBUG - Printf(stderr, "deftype type %s %s %d\n", e, tprefix, (long) tempn); -#endif - if (tempn) { - ParmList *tnargs = Getattr(tempn, "templateparms"); - ParmList *expandedparms; - Parm *p; - Symtab *tsdecl = Getattr(tempn, "sym:symtab"); - -#ifdef SWIG_DEBUG - Printf(stderr, "deftype type %s %s %s\n", tprefix, targs, tsuffix); -#endif - Append(tprefix, "<("); - expandedparms = Swig_symbol_template_defargs(tparms, tnargs, tscope, tsdecl); - p = expandedparms; - tscope = tsdecl; - while (p) { - SwigType *ptype = Getattr(p, "type"); - SwigType *ttr = ptype ? ptype : Getattr(p, "value"); - SwigType *ttf = Swig_symbol_type_qualify(ttr, tscope); - SwigType *ttq = Swig_symbol_template_param_eval(ttf, tscope); -#ifdef SWIG_DEBUG - Printf(stderr, "arg type %s\n", ttq); -#endif - if (SwigType_istemplate(ttq)) { - SwigType *ttd = Swig_symbol_template_deftype(ttq, tscope); - Delete(ttq); - ttq = ttd; -#ifdef SWIG_DEBUG - Printf(stderr, "arg deftype %s\n", ttq); -#endif - } - Append(tprefix, ttq); - p = nextSibling(p); - if (p) - Putc(',', tprefix); - Delete(ttf); - Delete(ttq); - } - Append(tprefix, ")>"); - Append(tprefix, tsuffix); - Append(prefix, tprefix); -#ifdef SWIG_DEBUG - Printf(stderr, "deftype %s %s \n", type, tprefix); -#endif - Append(result, prefix); - } else { - Append(result, e); - } - Delete(prefix); - Delete(base); - Delete(tprefix); - Delete(tsuffix); - Delete(targs); - Delete(tparms); - } else { - Append(result, e); - } - } - Delete(elements); -#ifdef SWIG_TEMPLATE_DEFTYPE_CACHE - Setattr(scope_cache, type_name, result); - Delete(type_name); -#endif - - return result; -} - -SwigType *Swig_symbol_template_param_eval(const SwigType *p, Symtab *symtab) { - String *value = Copy(p); - Node *lastnode = 0; - while (1) { - Node *n = Swig_symbol_clookup(value, symtab); - if (n == lastnode) - break; - lastnode = n; - if (n) { - String *nt = Getattr(n, "nodeType"); - if (Equal(nt, "enumitem")) { - /* An enum item. Generate a fully qualified name */ - String *qn = Swig_symbol_qualified(n); - if (qn && Len(qn)) { - Append(qn, "::"); - Append(qn, Getattr(n, "name")); - Delete(value); - value = qn; - continue; - } else { - Delete(qn); - break; - } - } else if ((Equal(nt, "cdecl"))) { - String *nv = Getattr(n, "value"); - if (nv) { - Delete(value); - value = Copy(nv); - continue; - } - } - } - break; - } - return value; -} diff --git a/contrib/tools/swig/Source/Swig/tree.c b/contrib/tools/swig/Source/Swig/tree.c deleted file mode 100644 index 438e8b73dc3..00000000000 --- a/contrib/tools/swig/Source/Swig/tree.c +++ /dev/null @@ -1,426 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * tree.c - * - * This file provides some general purpose functions for manipulating - * parse trees. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include <stdarg.h> -#include <assert.h> - -static int debug_quiet = 0; - -/* ----------------------------------------------------------------------------- - * Swig_print_quiet() - * - * Set quiet mode when printing a parse tree node - * ----------------------------------------------------------------------------- */ - -int Swig_print_quiet(int quiet) { - int previous_quiet = debug_quiet; - debug_quiet = quiet; - return previous_quiet; -} - -/* ----------------------------------------------------------------------------- - * Swig_print_tags() - * - * Dump the tag structure of a parse tree to standard output - * ----------------------------------------------------------------------------- */ - -void Swig_print_tags(DOH *obj, DOH *root) { - DOH *croot, *newroot; - DOH *cobj; - - if (!root) - croot = NewStringEmpty(); - else - croot = root; - - while (obj) { - Swig_diagnostic(Getfile(obj), Getline(obj), "%s . %s\n", croot, nodeType(obj)); - cobj = firstChild(obj); - if (cobj) { - newroot = NewStringf("%s . %s", croot, nodeType(obj)); - Swig_print_tags(cobj, newroot); - Delete(newroot); - } - obj = nextSibling(obj); - } - if (!root) - Delete(croot); -} - -static int indent_level = 0; - -static void print_indent(int l) { - int i; - for (i = 0; i < indent_level; i++) { - fputc(' ', stdout); - } - if (l) { - fputc('|', stdout); - fputc(' ', stdout); - } -} - - -/* ----------------------------------------------------------------------------- - * Swig_print_node(Node *n) - * ----------------------------------------------------------------------------- */ - -void Swig_print_node(Node *obj) { - Iterator ki; - Node *cobj; - List *keys = Keys(obj); - - print_indent(0); - if (debug_quiet) - Printf(stdout, "+++ %s ----------------------------------------\n", nodeType(obj)); - else - Printf(stdout, "+++ %s - %p ----------------------------------------\n", nodeType(obj), obj); - - SortList(keys, 0); - ki = First(keys); - while (ki.item) { - String *k = ki.item; - DOH *value = Getattr(obj, k); - if (Equal(k, "nodeType") || (*(Char(k)) == '$')) { - /* Do nothing */ - } else if (debug_quiet && (Equal(k, "firstChild") || Equal(k, "lastChild") || Equal(k, "parentNode") || Equal(k, "nextSibling") || - Equal(k, "previousSibling") || Equal(k, "symtab") || Equal(k, "csymtab") || Equal(k, "sym:symtab") || Equal(k, "sym:nextSibling") || - Equal(k, "sym:previousSibling") || Equal(k, "csym:nextSibling") || Equal(k, "csym:previousSibling"))) { - /* Do nothing */ - } else if (Equal(k, "kwargs") || Equal(k, "parms") || Equal(k, "wrap:parms") || Equal(k, "pattern") || Equal(k, "templateparms") || Equal(k, "throws")) { - print_indent(2); - /* Differentiate parameter lists by displaying within single quotes */ - Printf(stdout, "%-12s - \'%s\'\n", k, ParmList_str_defaultargs(value)); - } else { - DOH *o; - const char *trunc = ""; - print_indent(2); - if (DohIsString(value)) { - o = Str(value); - if (Len(o) > 80) { - trunc = "..."; - } - Printf(stdout, "%-12s - \"%(escape)-0.80s%s\"\n", k, o, trunc); - Delete(o); - } else { - Printf(stdout, "%-12s - %p\n", k, value); - } - } - ki = Next(ki); - } - cobj = firstChild(obj); - if (cobj) { - indent_level += 6; - Printf(stdout, "\n"); - Swig_print_tree(cobj); - indent_level -= 6; - } else { - print_indent(1); - Printf(stdout, "\n"); - } - Delete(keys); -} - -/* ----------------------------------------------------------------------------- - * Swig_print_tree() - * - * Dump the tree structure of a parse tree to standard output - * ----------------------------------------------------------------------------- */ - -void Swig_print_tree(DOH *obj) { - while (obj) { - Swig_print_node(obj); - obj = nextSibling(obj); - } -} - -/* ----------------------------------------------------------------------------- - * appendChild() - * - * Appends a new child to a node - * ----------------------------------------------------------------------------- */ - -void appendChild(Node *node, Node *chd) { - Node *lc; - - if (!chd) - return; - - lc = lastChild(node); - if (!lc) { - set_firstChild(node, chd); - } else { - set_nextSibling(lc, chd); - set_previousSibling(chd, lc); - } - while (chd) { - lc = chd; - set_parentNode(chd, node); - chd = nextSibling(chd); - } - set_lastChild(node, lc); -} - -/* ----------------------------------------------------------------------------- - * prependChild() - * - * Prepends a new child to a node - * ----------------------------------------------------------------------------- */ - -void prependChild(Node *node, Node *chd) { - Node *fc; - - if (!chd) - return; - - fc = firstChild(node); - if (fc) { - set_nextSibling(chd, fc); - set_previousSibling(fc, chd); - } - set_firstChild(node, chd); - while (chd) { - set_parentNode(chd, node); - chd = nextSibling(chd); - } -} - -void appendSibling(Node *node, Node *chd) { - Node *parent; - Node *lc = node; - while (nextSibling(lc)) - lc = nextSibling(lc); - set_nextSibling(lc, chd); - set_previousSibling(chd, lc); - parent = parentNode(node); - if (parent) { - while (chd) { - lc = chd; - set_parentNode(chd, parent); - chd = nextSibling(chd); - } - set_lastChild(parent, lc); - } -} - -/* ----------------------------------------------------------------------------- - * removeNode() - * - * Removes a node from the parse tree. Detaches it from its parent's child list. - * ----------------------------------------------------------------------------- */ - -void removeNode(Node *n) { - Node *parent; - Node *prev; - Node *next; - - parent = parentNode(n); - if (!parent) return; - - prev = previousSibling(n); - next = nextSibling(n); - if (prev) { - set_nextSibling(prev, next); - } else { - if (parent) { - set_firstChild(parent, next); - } - } - if (next) { - set_previousSibling(next, prev); - } else { - if (parent) { - set_lastChild(parent, prev); - } - } - - /* Delete attributes */ - Delattr(n,"parentNode"); - Delattr(n,"nextSibling"); - Delattr(n,"previousSibling"); -} - -/* ----------------------------------------------------------------------------- - * copyNode() - * - * Copies a node, but only copies simple attributes (no lists, hashes). - * ----------------------------------------------------------------------------- */ - -Node *copyNode(Node *n) { - Iterator ki; - Node *c = NewHash(); - for (ki = First(n); ki.key; ki = Next(ki)) { - if (DohIsString(ki.item)) { - Setattr(c, ki.key, Copy(ki.item)); - } - } - Setfile(c, Getfile(n)); - Setline(c, Getline(n)); - return c; -} - -/* ----------------------------------------------------------------------------- - * checkAttribute() - * ----------------------------------------------------------------------------- */ - -int checkAttribute(Node *n, const_String_or_char_ptr name, const_String_or_char_ptr value) { - String *v = Getattr(n, name); - return v ? Equal(v, value) : 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_require() - * ns - namespace for the view name for saving any attributes under - * n - node - * ... - list of attribute names of type char* - * - * An attribute is optional if it is prefixed by ?, eg "?value". All - * non-optional attributes are checked for on node n and if any do not exist - * SWIG exits with a fatal error. - * - * If the attribute name is prefixed by * or ?, eg "*value" then a copy of the - * attribute is saved. The saved attributes will be restored on a subsequent - * call to Swig_restore(). All the saved attributes are saved in the view - * namespace (prefixed by ns). - * - * This function can be called more than once with different namespaces. - * ----------------------------------------------------------------------------- */ - -void Swig_require(const char *ns, Node *n, ...) { - va_list ap; - char *name; - DOH *obj; - - va_start(ap, n); - name = va_arg(ap, char *); - while (name) { - int newref = 0; - int opt = 0; - if (*name == '*') { - newref = 1; - name++; - } else if (*name == '?') { - newref = 1; - opt = 1; - name++; - } - obj = Getattr(n, name); - if (!opt && !obj) { - Swig_error(Getfile(n), Getline(n), "Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n", name, nodeType(n)); - Exit(EXIT_FAILURE); - } - if (!obj) - obj = DohNone; - if (newref) { - /* Save a copy of the attribute */ - Setattr(n, NewStringf("%s:%s", ns, name), obj); - } - name = va_arg(ap, char *); - } - va_end(ap); - - /* Save the view */ - { - String *view = Getattr(n, "view"); - if (view) { - if (Strcmp(view, ns) != 0) { - Setattr(n, NewStringf("%s:view", ns), view); - Setattr(n, "view", NewString(ns)); - } - } else { - Setattr(n, "view", NewString(ns)); - } - } -} - - -/* ----------------------------------------------------------------------------- - * Swig_save() - * Same as Swig_require(), but all attribute names are optional and all attributes - * are saved, ie behaves as if all the attribute names were prefixed by ?. - * ----------------------------------------------------------------------------- */ - -void Swig_save(const char *ns, Node *n, ...) { - va_list ap; - char *name; - DOH *obj; - - va_start(ap, n); - name = va_arg(ap, char *); - while (name) { - if (*name == '*') { - name++; - } else if (*name == '?') { - name++; - } - obj = Getattr(n, name); - if (!obj) - obj = DohNone; - - /* Save a copy of the attribute */ - if (Setattr(n, NewStringf("%s:%s", ns, name), obj)) { - Printf(stderr, "Swig_save('%s','%s'): Warning, attribute '%s' was already saved.\n", ns, nodeType(n), name); - } - name = va_arg(ap, char *); - } - va_end(ap); - - /* Save the view */ - { - String *view = Getattr(n, "view"); - if (view) { - if (Strcmp(view, ns) != 0) { - Setattr(n, NewStringf("%s:view", ns), view); - Setattr(n, "view", NewString(ns)); - } - } else { - Setattr(n, "view", NewString(ns)); - } - } -} - -/* ----------------------------------------------------------------------------- - * Swig_restore() - * Restores attributes saved by a previous call to Swig_require() or Swig_save(). - * ----------------------------------------------------------------------------- */ - -void Swig_restore(Node *n) { - String *temp; - int len; - List *l; - String *ns; - Iterator ki; - - ns = Getattr(n, "view"); - assert(ns); - - l = NewList(); - - temp = NewStringf("%s:", ns); - len = Len(temp); - - for (ki = First(n); ki.key; ki = Next(ki)) { - if (Strncmp(temp, ki.key, len) == 0) { - Append(l, ki.key); - } - } - for (ki = First(l); ki.item; ki = Next(ki)) { - DOH *obj = Getattr(n, ki.item); - Setattr(n, Char(ki.item) + len, obj); - Delattr(n, ki.item); - } - Delete(l); - Delete(temp); -} diff --git a/contrib/tools/swig/Source/Swig/typemap.c b/contrib/tools/swig/Source/Swig/typemap.c deleted file mode 100644 index f0dee59d9e8..00000000000 --- a/contrib/tools/swig/Source/Swig/typemap.c +++ /dev/null @@ -1,2210 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * typemap.c - * - * A somewhat generalized implementation of SWIG1.1 typemaps. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "cparse.h" -#include <ctype.h> - -#if 0 -#define SWIG_DEBUG -#endif - -static int typemap_search_debug = 0; -static int typemaps_used_debug = 0; -static int typemap_register_debug = 0; -static int in_typemap_search_multi = 0; - -static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f, Node *file_line_node); - -/* ----------------------------------------------------------------------------- - * Typemaps are stored in a collection of nested hash tables. Something like - * this: - * - * [ type ] - * +-------- [ name ] - * +-------- [ name ] - * - * Each hash table [ type ] or [ name ] then contains references to the - * different typemap methods. These are referenced by names such as - * "tmap:in", "tmap:out", "tmap:argout", and so forth. - * - * The object corresponding to a specific typemap method has the following attributes: - * - * "type" - Typemap type - * "pname" - Parameter name - * "code" - Typemap code - * "source" - Source directive (%apply or %typemap) for the typemap - * "locals" - Local variables (if any) - * "kwargs" - Typemap attributes - * - * Example for a typemap method named "in": - * %typemap(in, warning="987:my warning", noblock=1) int &my_int (int tmp) "$1 = $input;" - * - * "type" - r.int - * "pname" - my_int - * "code" - $1 = $input; - * "source" - typemap(in) int &my_int - * "locals" - int tmp - * "kwargs" - warning="987:my typemap warning", foo=123 - * - * ----------------------------------------------------------------------------- */ - -static Hash *typemaps; - -/* ----------------------------------------------------------------------------- - * typemap_identifier_fix() - * - * Create a type that can be used as a hash key lookup independent of the various - * ways a template parameter list can be defined. This is achieved by fully - * resolving the template parameters. - * - * This is a copy and modification of feature_identifier_fix in parser.y. - * ----------------------------------------------------------------------------- */ - -static SwigType *typemap_identifier_fix(const SwigType *s) { - String *tp = SwigType_istemplate_templateprefix(s); - if (tp) { - String *ts, *ta, *tq, *tr; - ts = SwigType_templatesuffix(s); - ta = SwigType_templateargs(s); - tq = Swig_symbol_type_qualify(ta, 0); - tr = SwigType_typedef_resolve_all(ta); - Append(tp,tr); - Append(tp,ts); - Delete(ts); - Delete(ta); - Delete(tq); - Delete(tr); - return tp; - } else { - return NewString(s); - } -} - -static Hash *get_typemap(const SwigType *type) { - Hash *tm = 0; - SwigType *dtype = 0; - SwigType *hashtype; - - if (SwigType_istemplate(type)) { - SwigType *rty = typemap_identifier_fix(type); - String *ty = Swig_symbol_template_deftype(rty, 0); - dtype = Swig_symbol_type_qualify(ty, 0); - type = dtype; - Delete(ty); - } - - /* remove unary scope operator (::) prefix indicating global scope for looking up in the hashmap */ - hashtype = SwigType_remove_global_scope_prefix(type); - tm = Getattr(typemaps, hashtype); - - Delete(dtype); - Delete(hashtype); - - return tm; -} - -static void set_typemap(const SwigType *type, Hash **tmhash) { - SwigType *hashtype = 0; - Hash *new_tm = 0; - assert(*tmhash == 0); - if (SwigType_istemplate(type)) { - SwigType *rty = typemap_identifier_fix(type); - String *ty = Swig_symbol_template_deftype(rty, 0); - String *tyq = Swig_symbol_type_qualify(ty, 0); - hashtype = SwigType_remove_global_scope_prefix(tyq); - *tmhash = Getattr(typemaps, hashtype); - Delete(rty); - Delete(tyq); - Delete(ty); - } else { - hashtype = SwigType_remove_global_scope_prefix(type); - } - - if (!*tmhash) { - /* this type has not been seen before even after resolving template parameter types */ - new_tm = NewHash(); - *tmhash = new_tm; - } - - /* note that the unary scope operator (::) prefix indicating global scope has been removed from the type */ - Setattr(typemaps, hashtype, *tmhash); - - Delete(hashtype); - Delete(new_tm); -} - - -/* ----------------------------------------------------------------------------- - * Swig_typemap_init() - * - * Initialize the typemap system - * ----------------------------------------------------------------------------- */ - -void Swig_typemap_init(void) { - typemaps = NewHash(); -} - -static String *typemap_method_name(const_String_or_char_ptr tmap_method) { - static Hash *names = 0; - String *s; - /* Due to "interesting" object-identity semantics of DOH, - we have to make sure that we only intern strings without object - identity into the hash table. - - (typemap_attach_kwargs calls typemap_method_name several times with - the "same" String *tmap_method (i.e., same object identity) but differing - string values.) - - Most other callers work around this by using char* rather than - String *. - -- mkoeppe, Jun 17, 2003 - */ - const char *method_without_object_identity = Char(tmap_method); - if (!names) - names = NewHash(); - s = Getattr(names, method_without_object_identity); - if (s) - return s; - s = NewStringf("tmap:%s", tmap_method); - Setattr(names, method_without_object_identity, s); - Delete(s); - return s; -} - -/* ----------------------------------------------------------------------------- - * typemap_register() - * - * Internal implementation for Swig_typemap_register() - * ----------------------------------------------------------------------------- */ - -static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs, String *source_directive) { - Hash *tm; - Hash *tm1; - Hash *tm2; - Parm *np; - String *tm_method; - SwigType *type; - String *pname; - if (!parms) - return; - - if (typemap_register_debug) { - Printf(stdout, "Registering - %s\n", tmap_method); - Swig_print_node(parms); - } - - tm_method = typemap_method_name(tmap_method); - - /* Register the first type in the parameter list */ - - type = Getattr(parms, "type"); - pname = Getattr(parms, "name"); - - /* See if this type has been seen before */ - tm = get_typemap(type); - if (!tm) { - set_typemap(type, &tm); - } - if (pname) { - /* See if parameter has been seen before */ - tm1 = Getattr(tm, pname); - if (!tm1) { - tm1 = NewHash(); - Setattr(tm, pname, tm1); - Delete(tm1); - } - tm = tm1; - } - - /* Now see if this typemap method has been seen before */ - tm2 = Getattr(tm, tm_method); - if (!tm2) { - tm2 = NewHash(); - Setattr(tm, tm_method, tm2); - Delete(tm2); - } - - /* For a multi-argument typemap, the typemap code and information - is really only stored in the last argument. However, to - make this work, we perform a really neat trick using - the typemap method name. - - For example, consider this typemap - - %typemap(in) (int foo, int *bar, char *blah[]) { - ... - } - - To store it, we look at typemaps for the following: - - typemap method type-name - ---------------------------------------------- - "in" int foo - "in-int+foo:" int *bar - "in-int+foo:-p.int+bar: char *blah[] - - Notice how the typemap method name expands to encode information about - previous arguments. - - */ - - np = nextSibling(parms); - if (np) { - /* Make an entirely new typemap method key */ - String *multi_tmap_method = NewStringf("%s-%s+%s:", tmap_method, type, pname); - - /* Now reregister on the remaining arguments */ - typemap_register(multi_tmap_method, np, code, locals, kwargs, source_directive); - - Delete(multi_tmap_method); - } else { - ParmList *clocals = CopyParmList(locals); - ParmList *ckwargs = CopyParmList(kwargs); - - Setfile(tm2, Getfile(code)); - Setline(tm2, Getline(code)); - Setattr(tm2, "code", code); - Setattr(tm2, "type", type); - Setattr(tm2, "source", source_directive); - if (pname) { - Setattr(tm2, "pname", pname); - } - Setattr(tm2, "locals", clocals); - Setattr(tm2, "kwargs", ckwargs); - - Delete(clocals); - Delete(ckwargs); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_typemap_register() - * - * Add a new, possibly multi-argument, typemap - * ----------------------------------------------------------------------------- */ - -void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs) { - String *parms_str = ParmList_str_multibrackets(parms); - String *source_directive = NewStringf("typemap(%s) %s", tmap_method, parms_str); - - typemap_register(tmap_method, parms, code, locals, kwargs, source_directive); - - Delete(source_directive); - Delete(parms_str); -} - -/* ----------------------------------------------------------------------------- - * typemap_get() - * - * Retrieve typemap information. - * ----------------------------------------------------------------------------- */ - -static Hash *typemap_get(SwigType *type, const_String_or_char_ptr name) { - Hash *tm, *tm1; - tm = get_typemap(type); - if (!tm) { - return 0; - } - if ((name) && Len(name)) { - tm1 = Getattr(tm, name); - return tm1; - } - return tm; -} - -/* ----------------------------------------------------------------------------- - * Swig_typemap_copy() - * - * Copy a typemap - * ----------------------------------------------------------------------------- */ - -int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcparms, ParmList *parms) { - Hash *tm = 0; - String *tm_method; - Parm *p; - String *pname; - SwigType *ptype; - String *tm_methods, *multi_tmap_method; - if (ParmList_len(parms) != ParmList_len(srcparms)) - return -1; - - tm_method = typemap_method_name(tmap_method); - p = srcparms; - tm_methods = NewString(tm_method); - while (p) { - ptype = Getattr(p, "type"); - pname = Getattr(p, "name"); - - /* Lookup the type */ - tm = typemap_get(ptype, pname); - if (!tm) - break; - - tm = Getattr(tm, tm_methods); - if (!tm) - break; - - /* Got a match. Look for next typemap */ - multi_tmap_method = NewStringf("%s-%s+%s:", tm_methods, ptype, pname); - Delete(tm_methods); - tm_methods = multi_tmap_method; - p = nextSibling(p); - } - Delete(tm_methods); - - if (!p && tm) { - /* Got some kind of match */ - String *parms_str = ParmList_str_multibrackets(parms); - String *srcparms_str = ParmList_str_multibrackets(srcparms); - String *source_directive = NewStringf("typemap(%s) %s = %s", tmap_method, parms_str, srcparms_str); - - typemap_register(tmap_method, parms, Getattr(tm, "code"), Getattr(tm, "locals"), Getattr(tm, "kwargs"), source_directive); - - Delete(source_directive); - Delete(srcparms_str); - Delete(parms_str); - return 0; - } - - /* Not found */ - return -1; - -} - -/* ----------------------------------------------------------------------------- - * Swig_typemap_clear() - * - * Delete a multi-argument typemap - * ----------------------------------------------------------------------------- */ - -void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *parms) { - SwigType *type; - String *name; - Parm *p; - String *multi_tmap_method; - Hash *tm = 0; - - /* This might not work */ - multi_tmap_method = NewString(tmap_method); - p = parms; - while (p) { - type = Getattr(p, "type"); - name = Getattr(p, "name"); - tm = typemap_get(type, name); - if (!tm) - return; - p = nextSibling(p); - if (p) - Printf(multi_tmap_method, "-%s+%s:", type, name); - } - if (tm) { - tm = Getattr(tm, typemap_method_name(multi_tmap_method)); - if (tm) { - Delattr(tm, "code"); - Delattr(tm, "locals"); - Delattr(tm, "kwargs"); - } - } - Delete(multi_tmap_method); -} - -/* ----------------------------------------------------------------------------- - * Swig_typemap_apply() - * - * Multi-argument %apply directive. This is pretty horrible so I sure hope - * it works. - * ----------------------------------------------------------------------------- */ - -static int count_args(String *s) { - /* Count up number of arguments */ - int na = 0; - char *c = Char(s); - while (*c) { - if (*c == '+') - na++; - c++; - } - return na; -} - -int Swig_typemap_apply(ParmList *src, ParmList *dest) { - String *ssig, *dsig; - Parm *p, *np, *lastp, *dp, *lastdp = 0; - int narg = 0; - SwigType *type = 0, *name; - Hash *tm, *sm; - int match = 0; - - /* Printf(stdout,"apply : %s --> %s\n", ParmList_str(src), ParmList_str(dest)); */ - - /* Create type signature of source */ - ssig = NewStringEmpty(); - dsig = NewStringEmpty(); - p = src; - dp = dest; - lastp = 0; - while (p) { - lastp = p; - lastdp = dp; - np = nextSibling(p); - if (np) { - Printf(ssig, "-%s+%s:", Getattr(p, "type"), Getattr(p, "name")); - Printf(dsig, "-%s+%s:", Getattr(dp, "type"), Getattr(dp, "name")); - narg++; - } - p = np; - dp = nextSibling(dp); - } - - /* make sure a typemap node exists for the last destination node */ - type = Getattr(lastdp, "type"); - tm = get_typemap(type); - if (!tm) { - set_typemap(type, &tm); - } - name = Getattr(lastdp, "name"); - if (name) { - Hash *tm1 = Getattr(tm, name); - if (!tm1) { - tm1 = NewHash(); - Setattr(tm, NewString(name), tm1); - Delete(tm1); - } - tm = tm1; - } - - /* This is a little nasty. We need to go searching for all possible typemaps in the - source and apply them to the target */ - - type = Getattr(lastp, "type"); - name = Getattr(lastp, "name"); - - /* See if there is a matching typemap in this scope */ - sm = typemap_get(type, name); - - /* if there is not matching, look for a typemap in the - original typedef, if any, like in: - - typedef unsigned long size_t; - ... - %apply(size_t) {my_size}; ==> %apply(unsigned long) {my_size}; - */ - if (!sm) { - SwigType *ntype = SwigType_typedef_resolve(type); - if (ntype && (Cmp(ntype, type) != 0)) { - sm = typemap_get(ntype, name); - } - Delete(ntype); - } - - if (sm) { - /* Got a typemap. Need to only merge attributes for methods that match our signature */ - Iterator ki; - Hash *deferred_add; - match = 1; - - /* Since typemap_register can modify the `sm` hash, we *cannot* call typemap_register while iterating over sm. - * Create a temporary hash of typemaps to add immediately after. */ - deferred_add = NewHash(); - for (ki = First(sm); ki.key; ki = Next(ki)) { - /* Check for a signature match with the source signature */ - if ((count_args(ki.key) == narg) && (Strstr(ki.key, ssig))) { - String *oldm; - /* A typemap we have to copy */ - String *nkey = Copy(ki.key); - Replace(nkey, ssig, dsig, DOH_REPLACE_ANY); - - /* Make sure the typemap doesn't already exist in the target map */ - oldm = Getattr(tm, nkey); - if (!oldm || (!Getattr(tm, "code"))) { - String *code; - Hash *sm1 = ki.item; - - code = Getattr(sm1, "code"); - if (code) { - Replace(nkey, dsig, "", DOH_REPLACE_ANY); - Replace(nkey, "tmap:", "", DOH_REPLACE_ANY); - Setattr(deferred_add, nkey, sm1); - } - } - Delete(nkey); - } - } - - /* After assembling the key/item pairs, add the resulting typemaps */ - for (ki = First(deferred_add); ki.key; ki = Next(ki)) { - Hash *sm1 = ki.item; - String *src_str = ParmList_str_multibrackets(src); - String *dest_str = ParmList_str_multibrackets(dest); - String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str); - - typemap_register(ki.key, dest, Getattr(sm1, "code"), Getattr(sm1, "locals"), Getattr(sm1, "kwargs"), source_directive); - - Delete(source_directive); - Delete(dest_str); - Delete(src_str); - } - Delete(deferred_add); - } - Delete(ssig); - Delete(dsig); - return match; -} - -/* ----------------------------------------------------------------------------- - * Swig_typemap_clear_apply() - * - * %clear directive. Clears all typemaps for a type (in the current scope only). - * ----------------------------------------------------------------------------- */ - -/* Multi-argument %clear directive */ -void Swig_typemap_clear_apply(Parm *parms) { - String *tsig; - Parm *p, *np, *lastp; - int narg = 0; - Hash *tm; - String *name; - - /* Create a type signature of the parameters */ - tsig = NewStringEmpty(); - p = parms; - lastp = 0; - while (p) { - lastp = p; - np = nextSibling(p); - if (np) { - Printf(tsig, "-%s+%s:", Getattr(p, "type"), Getattr(p, "name")); - narg++; - } - p = np; - } - tm = get_typemap(Getattr(lastp, "type")); - if (!tm) { - Delete(tsig); - return; - } - name = Getattr(lastp, "name"); - if (name) { - tm = Getattr(tm, name); - } - if (tm) { - /* Clear typemaps that match our signature */ - Iterator ki, ki2; - char *ctsig = Char(tsig); - for (ki = First(tm); ki.key; ki = Next(ki)) { - char *ckey = Char(ki.key); - if (strncmp(ckey, "tmap:", 5) == 0) { - int na = count_args(ki.key); - if ((na == narg) && strstr(ckey, ctsig)) { - Hash *h = ki.item; - for (ki2 = First(h); ki2.key; ki2 = Next(ki2)) { - Delattr(h, ki2.key); - } - } - } - } - } - Delete(tsig); -} - -/* Internal function to strip array dimensions. */ -static SwigType *strip_arrays(SwigType *type) { - SwigType *t; - int ndim; - int i; - t = Copy(type); - ndim = SwigType_array_ndim(t); - for (i = 0; i < ndim; i++) { - SwigType_array_setdim(t, i, "ANY"); - } - return t; -} - -static void debug_search_result_display(Node *tm) { - if (tm) - Printf(stdout, " Using: %%%s\n", Getattr(tm, "source")); - else - Printf(stdout, " None found\n"); -} - -/* ----------------------------------------------------------------------------- - * typemap_search_helper() - * - * Helper function for typemap_search to see if there is a type match in the typemap - * tm. A match is sought in this order: - * %typemap(tm_method) ctype cqualifiedname - * %typemap(tm_method) ctype cname - * %typemap(tm_method) ctype - * ----------------------------------------------------------------------------- */ - -static Hash *typemap_search_helper(int debug_display, Hash *tm, const String *tm_method, SwigType *ctype, const String *cqualifiedname, const String *cname, Hash **backup) { - Hash *result = 0; - Hash *tm1; - if (debug_display && cqualifiedname) - Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, cqualifiedname)); - if (tm && cqualifiedname) { - tm1 = Getattr(tm, cqualifiedname); - if (tm1) { - result = Getattr(tm1, tm_method); /* See if there is a type - qualified name match */ - if (result && Getattr(result, "code")) - goto ret_result; - if (result) - *backup = result; - } - } - if (debug_display && cname) - Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, cname)); - if (tm && cname) { - tm1 = Getattr(tm, cname); - if (tm1) { - result = Getattr(tm1, tm_method); /* See if there is a type - name match */ - if (result && Getattr(result, "code")) - goto ret_result; - if (result) - *backup = result; - } - } - if (debug_display) - Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, 0)); - if (tm) { - result = Getattr(tm, tm_method); /* See if there is simply a type without name match */ - if (result && Getattr(result, "code")) - goto ret_result; - if (result) - *backup = result; - } -ret_result: - return result; -} - -/* ----------------------------------------------------------------------------- - * typemap_search() - * - * Search for a typemap match. This is where the typemap pattern matching rules - * are implemented... tries to find the most specific typemap that includes a - * 'code' attribute. - * ----------------------------------------------------------------------------- */ - -static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type, const_String_or_char_ptr name, const_String_or_char_ptr qualifiedname, SwigType **matchtype, Node *node) { - Hash *result = 0; - Hash *tm; - Hash *backup = 0; - SwigType *primitive = 0; - SwigType *ctype = 0; - SwigType *ctype_unstripped = 0; - int isarray; - const String *cname = 0; - const String *cqualifiedname = 0; - String *tm_method = typemap_method_name(tmap_method); - int debug_display = (in_typemap_search_multi == 0) && typemap_search_debug; - - if ((name) && Len(name)) - cname = name; - if ((qualifiedname) && Len(qualifiedname)) - cqualifiedname = qualifiedname; - - if (debug_display) { - String *typestr = SwigType_str(type, cqualifiedname ? cqualifiedname : cname); - Swig_diagnostic(Getfile(node), Getline(node), "Searching for a suitable '%s' typemap for: %s\n", tmap_method, typestr); - Delete(typestr); - } - ctype = Copy(type); - ctype_unstripped = Copy(ctype); - while (ctype) { - /* Try to get an exact type-match */ - tm = get_typemap(ctype); - result = typemap_search_helper(debug_display, tm, tm_method, ctype, cqualifiedname, cname, &backup); - if (result && Getattr(result, "code")) - goto ret_result; - - { - /* Look for the type reduced to just the template prefix - for templated types without the template parameter list being specified */ - SwigType *template_prefix = SwigType_istemplate_only_templateprefix(ctype); - if (template_prefix) { - tm = get_typemap(template_prefix); - result = typemap_search_helper(debug_display, tm, tm_method, template_prefix, cqualifiedname, cname, &backup); - Delete(template_prefix); - if (result && Getattr(result, "code")) - goto ret_result; - } - } - - /* look for [ANY] arrays */ - isarray = SwigType_isarray(ctype); - if (isarray) { - /* If working with arrays, strip away all of the dimensions and replace with "ANY". - See if that generates a match */ - SwigType *noarrays = strip_arrays(ctype); - tm = get_typemap(noarrays); - result = typemap_search_helper(debug_display, tm, tm_method, noarrays, cqualifiedname, cname, &backup); - Delete(noarrays); - if (result && Getattr(result, "code")) - goto ret_result; - } - - /* No match so far - try with a qualifier stripped (strip one qualifier at a time until none remain) - * The order of stripping in SwigType_strip_single_qualifier is used to provide some sort of consistency - * with the default (SWIGTYPE) typemap matching rules for the first qualifier to be stripped. */ - { - SwigType *oldctype = ctype; - ctype = SwigType_strip_single_qualifier(oldctype); - if (!Equal(ctype, oldctype)) { - Delete(oldctype); - continue; - } - Delete(oldctype); - } - - /* Once all qualifiers are stripped try resolve a typedef */ - { - SwigType *oldctype = ctype; - ctype = SwigType_typedef_resolve(ctype_unstripped); - Delete(oldctype); - Delete(ctype_unstripped); - ctype_unstripped = Copy(ctype); - } - } - - /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default (SWIGTYPE) mapping */ - - primitive = SwigType_default_create(type); - while (primitive) { - tm = get_typemap(primitive); - result = typemap_search_helper(debug_display, tm, tm_method, primitive, cqualifiedname, cname, &backup); - if (result && Getattr(result, "code")) - goto ret_result; - - { - SwigType *nprim = SwigType_default_deduce(primitive); - Delete(primitive); - primitive = nprim; - } - } - if (ctype != type) { - Delete(ctype); - ctype = 0; - } - result = backup; - -ret_result: - Delete(primitive); - if (matchtype) - *matchtype = Copy(ctype); - Delete(ctype); - Delete(ctype_unstripped); - return result; -} - - -/* ----------------------------------------------------------------------------- - * typemap_search_multi() - * - * Search for a multi-argument typemap. - * ----------------------------------------------------------------------------- */ - -static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList *parms, int *nmatch) { - SwigType *type; - SwigType *mtype = 0; - String *name; - String *multi_tmap_method; - Hash *tm; - Hash *tm1 = 0; - - if (!parms) { - *nmatch = 0; - return 0; - } - type = Getattr(parms, "type"); - name = Getattr(parms, "name"); - - /* Try to find a match on the first type */ - tm = typemap_search(tmap_method, type, name, 0, &mtype, parms); - if (tm) { - if (mtype && SwigType_isarray(mtype)) { - Setattr(parms, "tmap:match", mtype); - } - Delete(mtype); - multi_tmap_method = NewStringf("%s-%s+%s:", tmap_method, type, name); - in_typemap_search_multi++; - tm1 = typemap_search_multi(multi_tmap_method, nextSibling(parms), nmatch); - in_typemap_search_multi--; - if (tm1) - tm = tm1; - if (Getattr(tm, "code")) { - *(nmatch) = *nmatch + 1; - if (typemap_search_debug && tm1 && (in_typemap_search_multi == 0)) { - Printf(stdout, " Multi-argument typemap found...\n"); - } - } else { - tm = 0; - } - Delete(multi_tmap_method); - } - - if (typemap_search_debug && (in_typemap_search_multi == 0)) - debug_search_result_display(tm); - if (typemaps_used_debug && (in_typemap_search_multi == 0) && tm) { - String *typestr = SwigType_str(type, name); - Swig_diagnostic(Getfile(parms), Getline(parms), "Typemap for %s (%s) : %%%s\n", typestr, tmap_method, Getattr(tm, "source")); - assert(Getfile(parms) && Len(Getfile(parms)) > 0); /* Missing file and line numbering information */ - Delete(typestr); - } - - return tm; -} - - -/* ----------------------------------------------------------------------------- - * typemap_replace_vars() - * - * Replaces typemap variables on a string. index is the $n variable. - * type and pname are the type and parameter name. - * ----------------------------------------------------------------------------- */ - -static void replace_local_types(ParmList *p, const String *name, const String *rep) { - SwigType *t; - while (p) { - t = Getattr(p, "type"); - Replace(t, name, rep, DOH_REPLACE_ANY); - p = nextSibling(p); - } -} - -static int check_locals(ParmList *p, const char *s) { - while (p) { - char *c = GetChar(p, "type"); - if (strstr(c, s)) - return 1; - p = nextSibling(p); - } - return 0; -} - -static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType *rtype, String *pname, String *lname, int index) { - char var[512]; - char *varname; - SwigType *ftype; - int bare_substitution_count = 0; - - Replaceall(s, "$typemap", "$TYPEMAP"); /* workaround for $type substitution below */ - - ftype = SwigType_typedef_resolve_all(type); - - if (!pname) - pname = lname; - { - Parm *p; - int rep = 0; - p = locals; - while (p) { - if (Strchr(Getattr(p, "type"), '$')) - rep = 1; - p = nextSibling(p); - } - if (!rep) - locals = 0; - } - - sprintf(var, "$%d_", index); - varname = &var[strlen(var)]; - - /* If the original datatype was an array. We're going to go through and substitute - its array dimensions */ - - if (SwigType_isarray(type) || SwigType_isarray(ftype)) { - String *size; - int ndim; - int i; - if (SwigType_array_ndim(type) != SwigType_array_ndim(ftype)) - type = ftype; - ndim = SwigType_array_ndim(type); - size = NewStringEmpty(); - for (i = 0; i < ndim; i++) { - String *dim = SwigType_array_getdim(type, i); - if (index == 1) { - char t[32]; - sprintf(t, "$dim%d", i); - Replace(s, t, dim, DOH_REPLACE_ANY); - replace_local_types(locals, t, dim); - } - sprintf(varname, "dim%d", i); - Replace(s, var, dim, DOH_REPLACE_ANY); - replace_local_types(locals, var, dim); - if (Len(size)) - Putc('*', size); - Append(size, dim); - Delete(dim); - } - sprintf(varname, "size"); - Replace(s, var, size, DOH_REPLACE_ANY); - replace_local_types(locals, var, size); - Delete(size); - } - - /* Parameter name substitution */ - if (index == 1) { - Replace(s, "$parmname", pname, DOH_REPLACE_ANY); - } - strcpy(varname, "name"); - Replace(s, var, pname, DOH_REPLACE_ANY); - - /* Type-related stuff */ - { - SwigType *star_type, *amp_type, *base_type, *lex_type; - SwigType *ltype, *star_ltype, *amp_ltype; - String *mangle, *star_mangle, *amp_mangle, *base_mangle, *base_name, *base_type_str; - String *descriptor, *star_descriptor, *amp_descriptor; - String *ts; - char *sc; - - sc = Char(s); - - if (strstr(sc, "type") || check_locals(locals, "type")) { - /* Given type : $type */ - ts = SwigType_str(type, 0); - if (index == 1) { - Replace(s, "$type", ts, DOH_REPLACE_ANY); - replace_local_types(locals, "$type", type); - } - strcpy(varname, "type"); - Replace(s, var, ts, DOH_REPLACE_ANY); - replace_local_types(locals, var, type); - Delete(ts); - sc = Char(s); - } - if (strstr(sc, "ltype") || check_locals(locals, "ltype")) { - /* Local type: $ltype */ - ltype = SwigType_ltype(type); - ts = SwigType_str(ltype, 0); - if (index == 1) { - Replace(s, "$ltype", ts, DOH_REPLACE_ANY); - replace_local_types(locals, "$ltype", ltype); - } - strcpy(varname, "ltype"); - Replace(s, var, ts, DOH_REPLACE_ANY); - replace_local_types(locals, var, ltype); - Delete(ts); - Delete(ltype); - sc = Char(s); - } - if (strstr(sc, "mangle") || strstr(sc, "descriptor")) { - /* Mangled type */ - - mangle = SwigType_manglestr(type); - if (index == 1) - Replace(s, "$mangle", mangle, DOH_REPLACE_ANY); - strcpy(varname, "mangle"); - Replace(s, var, mangle, DOH_REPLACE_ANY); - - descriptor = NewStringf("SWIGTYPE%s", mangle); - - if (index == 1) - if (Replace(s, "$descriptor", descriptor, DOH_REPLACE_ANY)) - SwigType_remember(type); - - strcpy(varname, "descriptor"); - if (Replace(s, var, descriptor, DOH_REPLACE_ANY)) - SwigType_remember(type); - - Delete(descriptor); - Delete(mangle); - } - - /* One pointer level removed */ - /* This creates variables of the form - $*n_type - $*n_ltype - */ - - if (SwigType_ispointer(ftype) || (SwigType_isarray(ftype)) || (SwigType_isreference(ftype)) || (SwigType_isrvalue_reference(ftype))) { - if (!(SwigType_isarray(type) || SwigType_ispointer(type) || SwigType_isreference(type) || SwigType_isrvalue_reference(type))) { - star_type = Copy(ftype); - } else { - star_type = Copy(type); - } - if (!(SwigType_isreference(star_type) || SwigType_isrvalue_reference(star_type))) { - if (SwigType_isarray(star_type)) { - SwigType_del_element(star_type); - } else { - SwigType_del_pointer(star_type); - } - ts = SwigType_str(star_type, 0); - if (index == 1) { - Replace(s, "$*type", ts, DOH_REPLACE_ANY); - replace_local_types(locals, "$*type", star_type); - } - sprintf(varname, "$*%d_type", index); - Replace(s, varname, ts, DOH_REPLACE_ANY); - replace_local_types(locals, varname, star_type); - Delete(ts); - } else { - SwigType_del_element(star_type); - } - star_ltype = SwigType_ltype(star_type); - ts = SwigType_str(star_ltype, 0); - if (index == 1) { - Replace(s, "$*ltype", ts, DOH_REPLACE_ANY); - replace_local_types(locals, "$*ltype", star_ltype); - } - sprintf(varname, "$*%d_ltype", index); - Replace(s, varname, ts, DOH_REPLACE_ANY); - replace_local_types(locals, varname, star_ltype); - Delete(ts); - Delete(star_ltype); - - star_mangle = SwigType_manglestr(star_type); - if (index == 1) - Replace(s, "$*mangle", star_mangle, DOH_REPLACE_ANY); - - sprintf(varname, "$*%d_mangle", index); - Replace(s, varname, star_mangle, DOH_REPLACE_ANY); - - star_descriptor = NewStringf("SWIGTYPE%s", star_mangle); - if (index == 1) - if (Replace(s, "$*descriptor", star_descriptor, DOH_REPLACE_ANY)) - SwigType_remember(star_type); - sprintf(varname, "$*%d_descriptor", index); - if (Replace(s, varname, star_descriptor, DOH_REPLACE_ANY)) - SwigType_remember(star_type); - - Delete(star_descriptor); - Delete(star_mangle); - Delete(star_type); - } else { - /* TODO: Signal error if one of the $* substitutions is - requested */ - } - /* One pointer level added */ - amp_type = Copy(type); - SwigType_add_pointer(amp_type); - ts = SwigType_str(amp_type, 0); - if (index == 1) { - Replace(s, "$&type", ts, DOH_REPLACE_ANY); - replace_local_types(locals, "$&type", amp_type); - } - sprintf(varname, "$&%d_type", index); - Replace(s, varname, ts, DOH_REPLACE_ANY); - replace_local_types(locals, varname, amp_type); - Delete(ts); - - amp_ltype = SwigType_ltype(type); - SwigType_add_pointer(amp_ltype); - ts = SwigType_str(amp_ltype, 0); - - if (index == 1) { - Replace(s, "$<ype", ts, DOH_REPLACE_ANY); - replace_local_types(locals, "$<ype", amp_ltype); - } - sprintf(varname, "$&%d_ltype", index); - Replace(s, varname, ts, DOH_REPLACE_ANY); - replace_local_types(locals, varname, amp_ltype); - Delete(ts); - Delete(amp_ltype); - - amp_mangle = SwigType_manglestr(amp_type); - if (index == 1) - Replace(s, "$&mangle", amp_mangle, DOH_REPLACE_ANY); - sprintf(varname, "$&%d_mangle", index); - Replace(s, varname, amp_mangle, DOH_REPLACE_ANY); - - amp_descriptor = NewStringf("SWIGTYPE%s", amp_mangle); - if (index == 1) - if (Replace(s, "$&descriptor", amp_descriptor, DOH_REPLACE_ANY)) - SwigType_remember(amp_type); - sprintf(varname, "$&%d_descriptor", index); - if (Replace(s, varname, amp_descriptor, DOH_REPLACE_ANY)) - SwigType_remember(amp_type); - - Delete(amp_descriptor); - Delete(amp_mangle); - Delete(amp_type); - - /* Base type */ - if (SwigType_isarray(type)) { - base_type = Copy(type); - Delete(SwigType_pop_arrays(base_type)); - } else { - base_type = SwigType_base(type); - } - - base_type_str = SwigType_str(base_type, 0); - base_name = SwigType_namestr(base_type_str); - if (index == 1) { - Replace(s, "$basetype", base_name, DOH_REPLACE_ANY); - replace_local_types(locals, "$basetype", base_name); - } - strcpy(varname, "basetype"); - Replace(s, var, base_type_str, DOH_REPLACE_ANY); - replace_local_types(locals, var, base_name); - - base_mangle = SwigType_manglestr(base_type); - if (index == 1) - Replace(s, "$basemangle", base_mangle, DOH_REPLACE_ANY); - strcpy(varname, "basemangle"); - Replace(s, var, base_mangle, DOH_REPLACE_ANY); - Delete(base_mangle); - Delete(base_name); - Delete(base_type_str); - Delete(base_type); - - lex_type = SwigType_base(rtype); - if (index == 1) - Replace(s, "$lextype", lex_type, DOH_REPLACE_ANY); - strcpy(varname, "lextype"); - Replace(s, var, lex_type, DOH_REPLACE_ANY); - Delete(lex_type); - } - - /* Replace any $n. with (&n)-> */ - { - char temp[64]; - sprintf(var, "$%d.", index); - sprintf(temp, "(&$%d)->", index); - Replace(s, var, temp, DOH_REPLACE_ANY); - } - - /* Replace the bare $n variable */ - sprintf(var, "$%d", index); - bare_substitution_count = Replace(s, var, lname, DOH_REPLACE_NUMBER_END); - Delete(ftype); - return bare_substitution_count; -} - -/* ------------------------------------------------------------------------ - * static typemap_locals() - * - * Takes a string, a parameter list and a wrapper function argument and - * creates the local variables. - * ------------------------------------------------------------------------ */ - -static void typemap_locals(String *s, ParmList *l, Wrapper *f, int argnum) { - Parm *p; - char *new_name; - - p = l; - while (p) { - SwigType *pt = Getattr(p, "type"); - SwigType *at = SwigType_alttype(pt, 1); - String *pn = Getattr(p, "name"); - String *value = Getattr(p, "value"); - if (at) - pt = at; - if (pn) { - if (Len(pn) > 0) { - String *str; - int isglobal = 0; - - str = NewStringEmpty(); - - if (strncmp(Char(pn), "_global_", 8) == 0) { - isglobal = 1; - } - - /* If the user gave us $type as the name of the local variable, we'll use - the passed datatype instead */ - - if ((argnum >= 0) && (!isglobal)) { - Printf(str, "%s%d", pn, argnum); - } else { - Append(str, pn); - } - if (isglobal && Wrapper_check_local(f, str)) { - p = nextSibling(p); - Delete(str); - if (at) - Delete(at); - continue; - } - if (value) { - String *pstr = SwigType_str(pt, str); - new_name = Wrapper_new_localv(f, str, pstr, "=", value, NIL); - Delete(pstr); - } else { - String *pstr = SwigType_str(pt, str); - new_name = Wrapper_new_localv(f, str, pstr, NIL); - Delete(pstr); - } - if (!isglobal) { - /* Substitute */ - Replace(s, pn, new_name, DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE); - } - Delete(str); - } - } - p = nextSibling(p); - if (at) - Delete(at); - } -} - -/* ----------------------------------------------------------------------------- - * typemap_warn() - * - * If any warning message is attached to this parameter's "tmap:<method>:warning" - * attribute, return the warning message (special variables will need expanding - * before displaying the warning). - * ----------------------------------------------------------------------------- */ - -static String *typemap_warn(const_String_or_char_ptr tmap_method, Parm *p) { - String *temp = NewStringf("%s:warning", tmap_method); - String *w = Getattr(p, typemap_method_name(temp)); - Delete(temp); - return w ? Copy(w) : 0; -} - -/* ----------------------------------------------------------------------------- - * typemap_merge_fragment_kwargs() - * - * If multiple 'fragment' attributes are provided to a typemap, combine them by - * concatenating with commas. - * ----------------------------------------------------------------------------- */ - -static void typemap_merge_fragment_kwargs(Parm *kw) { - Parm *reattach_kw = NULL; - Parm *prev_kw = NULL; - Parm *next_kw = NULL; - String *fragment = NULL; - while (kw) { - next_kw = nextSibling(kw); - if (Strcmp(Getattr(kw, "name"), "fragment") == 0) { - String *thisfragment = Getattr(kw, "value"); - String *kwtype = Getattr(kw, "type"); - if (!fragment) { - /* First fragment found; it should remain in the list */ - fragment = thisfragment; - prev_kw = kw; - } else { - /* Concatenate to previously found fragment */ - Printv(fragment, ",", thisfragment, NULL); - reattach_kw = prev_kw; - } - if (kwtype) { - String *mangle = Swig_string_mangle(kwtype); - Append(fragment, mangle); - Delete(mangle); - /* Remove 'type' from kwargs so it's not duplicated later */ - Setattr(kw, "type", NULL); - } - } else { - /* Not a fragment */ - if (reattach_kw) { - /* Update linked list to remove duplicate fragment */ - DohIncref(kw); - set_nextSibling(reattach_kw, kw); - set_previousSibling(kw, reattach_kw); - Delete(reattach_kw); - reattach_kw = NULL; - } - prev_kw = kw; - } - kw = next_kw; - } - if (reattach_kw) { - /* Update linked list to remove duplicate fragment */ - set_nextSibling(reattach_kw, kw); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_typemap_lookup() - * - * Attach one or more typemaps to a node and optionally generate the typemap contents - * into the wrapper. - * - * Looks for a typemap matching the given type and name and attaches the typemap code - * and any typemap attributes to the provided node. - * - * The node should contain the "type" and "name" attributes for the typemap match on. - * input. The typemap code and typemap attribute values are attached onto the node - * prefixed with "tmap:". For example with tmap_method="in", the typemap code can be retrieved - * with a call to Getattr(node, "tmap:in") (this is also the string returned) and the - * "noblock" attribute can be retrieved with a call to Getattr(node, "tmap:in:noblock"). - * - * tmap_method - typemap method, eg "in", "out", "newfree" - * node - the node to attach the typemap and typemap attributes to - * lname - name of variable to substitute $1, $2 etc for - * f - wrapper code to generate into if non null - * actioncode - code to generate into f before the out typemap code, unless - * the optimal attribute is set in the out typemap in which case - * $1 in the out typemap will be replaced by the code in actioncode. - * ----------------------------------------------------------------------------- */ - -static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f, String *actioncode) { - SwigType *type; - SwigType *mtype = 0; - String *pname; - String *qpname = 0; - String *noscope_pname = 0; - Hash *tm = 0; - String *s = 0; - String *sdef = 0; - String *warning = 0; - ParmList *locals; - ParmList *kw; - char temp[256]; - String *symname; - String *cname = 0; - String *clname = 0; - char *cmethod = Char(tmap_method); - int optimal_attribute = 0; - int optimal_substitution = 0; - int delete_optimal_attribute = 0; - int num_substitutions = 0; - SwigType *matchtype = 0; - - type = Getattr(node, "type"); - if (!type) - return sdef; - - /* Special hook (hack!). Check for the 'ref' feature and add code it contains to any 'newfree' typemap code. - * We could choose to put this hook into a number of different typemaps, not necessarily 'newfree'... - * Rather confusingly 'newfree' is used to release memory and the 'ref' feature is used to add in memory references - yuck! */ - if (Cmp(tmap_method, "newfree") == 0) { - String *base = SwigType_base(type); - Node *typenode = Swig_symbol_clookup(base, 0); - if (typenode) - sdef = Swig_ref_call(typenode, lname); - Delete(base); - } - - pname = Getattr(node, "name"); - noscope_pname = Copy(pname); - - if (pname && Getattr(node, "sym:symtab")) { - /* Add on a qualified name search for any symbol in the symbol table, for example: - * struct Foo { - * int *foo(int bar) -> Foo::foo - * }; - * Note that if node is a parameter (Parm *) then there will be no symbol table attached to the Parm *. - */ - String *qsn; - if (Swig_scopename_check(pname)) { - /* sometimes pname is qualified, so we remove all the scope for the lookup */ - Delete(noscope_pname); - noscope_pname = Swig_scopename_last(pname); - /* - Printf(stdout, "Removed scope: %s => %s\n", pname, noscope_pname); - */ - } - qsn = Swig_symbol_qualified(node); - if (qsn && Len(qsn)) { - qpname = NewStringf("%s::%s", qsn, noscope_pname); - Delete(qsn); - } - } - - tm = typemap_search(tmap_method, type, noscope_pname, qpname, &mtype, node); - if (typemap_search_debug) - debug_search_result_display(tm); - if (typemaps_used_debug && tm) { - String *typestr = SwigType_str(type, qpname ? qpname : pname); - Swig_diagnostic(Getfile(node), Getline(node), "Typemap for %s (%s) : %%%s\n", typestr, tmap_method, Getattr(tm, "source")); - assert(Getfile(node) && Len(Getfile(node)) > 0); /* Missing file and line numbering information */ - Delete(typestr); - } - - Delete(qpname); - qpname = 0; - Delete(noscope_pname); - noscope_pname = 0; - - if (!tm) - return sdef; - - s = Getattr(tm, "code"); - if (!s) - return sdef; - - /* Empty typemap. No match */ - if (Cmp(s, "pass") == 0) - return sdef; - - s = Copy(s); /* Make a local copy of the typemap code */ - - /* Look in the "out" typemap for the "optimal" attribute */ - if (Cmp(cmethod, "out") == 0) { - kw = Getattr(tm, "kwargs"); - while (kw) { - if (Cmp(Getattr(kw, "name"), "optimal") == 0) { - optimal_attribute = GetFlag(kw, "value"); - break; - } - kw = nextSibling(kw); - } - } - - if (optimal_attribute) { - /* Note: "out" typemap is the only typemap that will have the "optimal" attribute set. - * If f and actioncode are NULL, then the caller is just looking to attach the "out" attributes - * ie, not use the typemap code, otherwise both f and actioncode must be non null. */ - if (actioncode) { - const String *result_equals = NewStringf("%s = ", Swig_cresult_name()); - /* check that the code in the typemap can be used in this optimal way. - * The code should be in the form "result = ...;\n". We need to extract - * the "..." part. This may not be possible for various reasons, eg - * code added by %exception. This optimal code generation is bit of a - * hack and circumvents the normal requirement for a temporary variable - * to hold the result returned from a wrapped function call. - */ - if (Strncmp(actioncode, result_equals, Len(result_equals)) == 0 && - Strchr(actioncode, ';') == Char(actioncode) + Len(actioncode) - 2 && - Char(actioncode)[Len(actioncode) - 1] == '\n') { - clname = NewStringWithSize(Char(actioncode) + Len(result_equals), - Len(actioncode) - Len(result_equals) - 2); - lname = clname; - actioncode = 0; - optimal_substitution = 1; - } else { - Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute ignored\n", Swig_name_decl(node)); - Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(s), Getline(s), "in the out typemap as the following cannot be used to generate optimal code: %s\n", actioncode); - delete_optimal_attribute = 1; - } - } else { - assert(!f); - } - } - - if (actioncode) { - assert(f); - Append(f->code, actioncode); - } - - /* emit local variables declared in typemap, eg emit declarations for aa and bb in: - * %typemap(in) foo (int aa, int bb) "..." */ - locals = Getattr(tm, "locals"); - if (locals) - locals = CopyParmList(locals); - - if (pname) { - if (SwigType_istemplate(pname)) { - cname = SwigType_namestr(pname); - pname = cname; - } - } - if (SwigType_istemplate((char *) lname)) { - clname = SwigType_namestr((char *) lname); - lname = clname; - } - - matchtype = mtype && SwigType_isarray(mtype) ? mtype : type; - num_substitutions = typemap_replace_vars(s, locals, matchtype, type, pname, (char *) lname, 1); - if (optimal_substitution && num_substitutions > 1) { - Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(node), Getline(node), "Multiple calls to %s might be generated due to\n", Swig_name_decl(node)); - Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(s), Getline(s), "optimal attribute usage in the out typemap.\n"); - } - - if (locals && f) { - typemap_locals(s, locals, f, -1); - } - - { - ParmList *parm_sublist = NewParmWithoutFileLineInfo(type, pname); - Setattr(parm_sublist, "lname", lname); - replace_embedded_typemap(s, parm_sublist, f, tm); - Delete(parm_sublist); - } - - /* Attach kwargs - ie the typemap attributes */ - kw = Getattr(tm, "kwargs"); - typemap_merge_fragment_kwargs(kw); - while (kw) { - String *value = Copy(Getattr(kw, "value")); - String *kwtype = Getattr(kw, "type"); - char *ckwname = Char(Getattr(kw, "name")); - { - /* Expand special variables in typemap attributes. */ - SwigType *ptype = Getattr(node, "type"); - String *pname = Getattr(node, "name"); - SwigType *mtype = Getattr(node, "tmap:match"); - SwigType *matchtype = mtype ? mtype : ptype; - ParmList *parm_sublist; - typemap_replace_vars(value, NULL, matchtype, ptype, pname, (char *)lname, 1); - - /* Expand special variable macros (embedded typemaps) in typemap attributes. */ - parm_sublist = NewParmWithoutFileLineInfo(ptype, pname); - Setattr(parm_sublist, "lname", lname); - replace_embedded_typemap(value, parm_sublist, NULL, tm); - Delete(parm_sublist); - } - if (kwtype) { - String *mangle = Swig_string_mangle(kwtype); - Append(value, mangle); - Delete(mangle); - } - sprintf(temp, "%s:%s", cmethod, ckwname); - Setattr(node, typemap_method_name(temp), value); - Delete(value); - kw = nextSibling(kw); - } - - if (delete_optimal_attribute) - Delattr(node, "tmap:out:optimal"); - - Replace(s, "$name", pname, DOH_REPLACE_ANY); - - symname = Getattr(node, "sym:name"); - if (symname) - Replace(s, "$symname", symname, DOH_REPLACE_ANY); - - Setattr(node, typemap_method_name(tmap_method), s); - if (locals) { - sprintf(temp, "%s:locals", cmethod); - Setattr(node, typemap_method_name(temp), locals); - Delete(locals); - } - - if (Checkattr(tm, "type", "SWIGTYPE")) { - sprintf(temp, "%s:SWIGTYPE", cmethod); - Setattr(node, typemap_method_name(temp), "1"); - } - - /* Print warnings, if any */ - warning = typemap_warn(cmethod, node); - if (warning) { - typemap_replace_vars(warning, 0, matchtype, type, pname, (char *) lname, 1); - Replace(warning, "$name", pname, DOH_REPLACE_ANY); - if (symname) - Replace(warning, "$symname", symname, DOH_REPLACE_ANY); - Swig_warning(0, Getfile(node), Getline(node), "%s\n", warning); - Delete(warning); - } - - /* Look for code fragments */ - { - String *fragment; - sprintf(temp, "%s:fragment", cmethod); - fragment = Getattr(node, typemap_method_name(temp)); - if (fragment) { - String *fname = Copy(fragment); - Setfile(fname, Getfile(node)); - Setline(fname, Getline(node)); - Swig_fragment_emit(fname); - Delete(fname); - } - } - - Delete(cname); - Delete(clname); - Delete(mtype); - if (sdef) { /* put 'ref' and 'newfree' codes together */ - String *p = NewStringf("%s\n%s", sdef, s); - Delete(s); - Delete(sdef); - s = p; - } - Delete(actioncode); - return s; -} - -String *Swig_typemap_lookup_out(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f, String *actioncode) { - assert(actioncode); - assert(Cmp(tmap_method, "out") == 0); - return Swig_typemap_lookup_impl(tmap_method, node, lname, f, actioncode); -} - -String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f) { - return Swig_typemap_lookup_impl(tmap_method, node, lname, f, 0); -} - -/* ----------------------------------------------------------------------------- - * typemap_attach_kwargs() - * - * If this hash (tm) contains a linked list of parameters under its "kwargs" - * attribute, add keys for each of those named keyword arguments to this - * parameter for later use. - * For example, attach the typemap attributes to firstp (first parameter in parameter list): - * %typemap(in, foo="xyz") ... - * A new attribute called "tmap:in:foo" with value "xyz" is attached to firstp. - * Also expands special variables and special variable macros in the typemap attributes. - * ----------------------------------------------------------------------------- */ - -static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method, Parm *firstp, int nmatch) { - String *temp = NewStringEmpty(); - Parm *kw = Getattr(tm, "kwargs"); - typemap_merge_fragment_kwargs(kw); - while (kw) { - String *value = Copy(Getattr(kw, "value")); - String *type = Getattr(kw, "type"); - int i; - Parm *p = firstp; - /* Expand special variables */ - for (i = 0; i < nmatch; i++) { - SwigType *type = Getattr(p, "type"); - String *pname = Getattr(p, "name"); - String *lname = Getattr(p, "lname"); - SwigType *mtype = Getattr(p, "tmap:match"); - SwigType *matchtype = mtype ? mtype : type; - typemap_replace_vars(value, NULL, matchtype, type, pname, lname, i + 1); - p = nextSibling(p); - } - - /* Expand special variable macros (embedded typemaps). - * Special variable are expanded first above as they might be used in the special variable macros. - * For example: $typemap(imtype, $2_type). */ - p = firstp; - for (i = 0; i < nmatch; i++) { - SwigType *type = Getattr(p, "type"); - String *pname = Getattr(p, "name"); - String *lname = Getattr(p, "lname"); - ParmList *parm_sublist = NewParmWithoutFileLineInfo(type, pname); - Setattr(parm_sublist, "lname", lname); - replace_embedded_typemap(value, parm_sublist, NULL, tm); - p = nextSibling(p); - } - if (type) { - Hash *v = NewHash(); - Setattr(v, "type", type); - Setattr(v, "value", value); - Delete(value); - value = v; - } - Clear(temp); - Printf(temp, "%s:%s", tmap_method, Getattr(kw, "name")); - Setattr(firstp, typemap_method_name(temp), value); - Delete(value); - kw = nextSibling(kw); - } - Clear(temp); - Printf(temp, "%s:match_type", tmap_method); - Setattr(firstp, typemap_method_name(temp), Getattr(tm, "type")); - Delete(temp); -} - -static void typemap_emit_code_fragments(const_String_or_char_ptr tmap_method, Parm *p) { - String *temp = NewStringf("%s:fragment", tmap_method); - String *f = Getattr(p, typemap_method_name(temp)); - if (f) { - String *fname = Copy(f); - Setfile(fname, Getfile(p)); - Setline(fname, Getline(p)); - Swig_fragment_emit(fname); - Delete(fname); - } - Delete(temp); -} - -static String *typemap_get_option(Hash *tm, const_String_or_char_ptr name) { - Parm *kw = Getattr(tm, "kwargs"); - while (kw) { - String *kname = Getattr(kw, "name"); - if (Equal(kname, name)) { - return Getattr(kw, "value"); - } - kw = nextSibling(kw); - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * Swig_typemap_attach_parms() - * - * Given a parameter list, this function attaches all of the typemaps and typemap - * attributes to the parameter for each type in the parameter list. - * - * This function basically provides the typemap code and typemap attribute values as - * attributes on each parameter prefixed with "tmap:". For example with tmap_method="in", the typemap - * code can be retrieved for the first parameter with a call to Getattr(parm, "tmap:in") - * and the "numinputs" attribute can be retrieved with a call to Getattr(parm, "tmap:in:numinputs"). - * - * tmap_method - typemap method, eg "in", "out", "newfree" - * parms - parameter list to attach each typemap and all typemap attributes - * f - wrapper code to generate into if non null - * ----------------------------------------------------------------------------- */ - -void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f) { - Parm *p, *firstp; - Hash *tm; - int nmatch = 0; - int i; - String *s; - String *warning = 0; - ParmList *locals; - int argnum = 0; - char temp[256]; - char *cmethod = Char(tmap_method); - String *kwmatch = 0; - p = parms; - -#ifdef SWIG_DEBUG - Printf(stdout, "Swig_typemap_attach_parms: %s\n", tmap_method); -#endif - - while (p) { - argnum++; - nmatch = 0; -#ifdef SWIG_DEBUG - Printf(stdout, "parms: %s %s %s\n", tmap_method, Getattr(p, "name"), Getattr(p, "type")); -#endif - tm = typemap_search_multi(tmap_method, p, &nmatch); -#ifdef SWIG_DEBUG - if (tm) - Printf(stdout, "found: %s\n", tm); -#endif - if (!tm) { - p = nextSibling(p); - continue; - } - /* - Check if the typemap requires to match the type of another - typemap, for example: - - %typemap(in) SWIGTYPE * (int var) {...} - %typemap(freearg,match="in") SWIGTYPE * {if (var$argnum) ...} - - here, the freearg typemap requires the "in" typemap to match, - or the 'var$argnum' variable will not exist. - */ - kwmatch = typemap_get_option(tm, "match"); - if (kwmatch) { - String *tmname = NewStringf("tmap:%s", kwmatch); - String *tmin = Getattr(p, tmname); - Delete(tmname); -#ifdef SWIG_DEBUG - if (tm) - Printf(stdout, "matching: %s\n", kwmatch); -#endif - if (tmin) { - String *tmninp = NewStringf("tmap:%s:numinputs", kwmatch); - String *ninp = Getattr(p, tmninp); - Delete(tmninp); - if (ninp && Equal(ninp, "0")) { - p = nextSibling(p); - continue; - } else { - SwigType *typetm = Getattr(tm, "type"); - String *temp = NewStringf("tmap:%s:match_type", kwmatch); - SwigType *typein = Getattr(p, temp); - Delete(temp); - if (!Equal(typein, typetm)) { - p = nextSibling(p); - continue; - } else { - int nnmatch; - Hash *tmapin = typemap_search_multi(kwmatch, p, &nnmatch); - String *tmname = Getattr(tm, "pname"); - String *tnname = Getattr(tmapin, "pname"); - if (!(tmname && tnname && Equal(tmname, tnname)) && !(!tmname && !tnname)) { - p = nextSibling(p); - continue; - } - } - - } - } else { - p = nextSibling(p); - continue; - } - } - - s = Getattr(tm, "code"); - if (!s) { - p = nextSibling(p); - continue; - } -#ifdef SWIG_DEBUG - if (s) - Printf(stdout, "code: %s\n", s); -#endif - - /* Empty typemap. No match */ - if (Cmp(s, "pass") == 0) { - p = nextSibling(p); - continue; - } - - s = Copy(s); - locals = Getattr(tm, "locals"); - if (locals) - locals = CopyParmList(locals); - firstp = p; -#ifdef SWIG_DEBUG - Printf(stdout, "nmatch: %d\n", nmatch); -#endif - for (i = 0; i < nmatch; i++) { - SwigType *type = Getattr(p, "type"); - String *pname = Getattr(p, "name"); - String *lname = Getattr(p, "lname"); - SwigType *mtype = Getattr(p, "tmap:match"); - SwigType *matchtype = mtype ? mtype : type; - - typemap_replace_vars(s, locals, matchtype, type, pname, lname, i + 1); - if (mtype) - Delattr(p, "tmap:match"); - - if (Checkattr(tm, "type", "SWIGTYPE")) { - sprintf(temp, "%s:SWIGTYPE", cmethod); - Setattr(p, typemap_method_name(temp), "1"); - } - p = nextSibling(p); - } - - if (locals && f) { - typemap_locals(s, locals, f, argnum); - } - - replace_embedded_typemap(s, firstp, f, tm); - - /* Attach attributes to object */ -#ifdef SWIG_DEBUG - Printf(stdout, "attach: %s %s %s\n", Getattr(firstp, "name"), typemap_method_name(tmap_method), s); -#endif - Setattr(firstp, typemap_method_name(tmap_method), s); /* Code object */ - - if (locals) { - sprintf(temp, "%s:locals", cmethod); - Setattr(firstp, typemap_method_name(temp), locals); - Delete(locals); - } - - /* Attach a link to the next parameter. Needed for multimaps */ - sprintf(temp, "%s:next", cmethod); - Setattr(firstp, typemap_method_name(temp), p); - - /* Attach kwargs */ - typemap_attach_kwargs(tm, tmap_method, firstp, nmatch); - - /* Replace the argument number */ - sprintf(temp, "%d", argnum); - Replace(s, "$argnum", temp, DOH_REPLACE_ANY); - - /* Print warnings, if any */ - warning = typemap_warn(tmap_method, firstp); - if (warning) { - SwigType *type = Getattr(firstp, "type"); - String *pname = Getattr(firstp, "name"); - String *lname = Getattr(firstp, "lname"); - SwigType *mtype = Getattr(firstp, "tmap:match"); - SwigType *matchtype = mtype ? mtype : type; - typemap_replace_vars(warning, 0, matchtype, type, pname, lname, 1); - Replace(warning, "$argnum", temp, DOH_REPLACE_ANY); - Swig_warning(0, Getfile(firstp), Getline(firstp), "%s\n", warning); - Delete(warning); - } - - /* Look for code fragments */ - typemap_emit_code_fragments(tmap_method, firstp); - - /* increase argnum to consider numinputs */ - argnum += nmatch - 1; - Delete(s); -#ifdef SWIG_DEBUG - Printf(stdout, "res: %s %s %s\n", Getattr(firstp, "name"), typemap_method_name(tmap_method), Getattr(firstp, typemap_method_name(tmap_method))); -#endif - - } -#ifdef SWIG_DEBUG - Printf(stdout, "Swig_typemap_attach_parms: end\n"); -#endif - -} - -/* Splits the arguments of an embedded typemap */ -static List *split_embedded_typemap(String *s) { - List *args = 0; - char *c, *start; - int level = 0; - int angle_level = 0; - int leading = 1; - - args = NewList(); - c = strchr(Char(s), '('); - assert(c); - c++; - - start = c; - while (*c) { - if (*c == '\"') { - c++; - while (*c) { - if (*c == '\\') { - c++; - } else { - if (*c == '\"') - break; - } - c++; - } - } - if ((level == 0) && angle_level == 0 && ((*c == ',') || (*c == ')'))) { - String *tmp = NewStringWithSize(start, (int)(c - start)); - Append(args, tmp); - Delete(tmp); - start = c + 1; - leading = 1; - if (*c == ')') - break; - c++; - continue; - } - if (*c == '(') - level++; - if (*c == ')') - level--; - if (*c == '<') - angle_level++; - if (*c == '>') - angle_level--; - if (isspace((int) *c) && leading) - start++; - if (!isspace((int) *c)) - leading = 0; - c++; - } - return args; -} - -/* ----------------------------------------------------------------------------- - * Swig_typemap_replace_embedded_typemap() - * - * For special variable macro $typemap(...) expansion outside of typemaps. - * Only limited usage works as most typemap special variables ($1, $input etc) - * are not expanded correctly outside of typemaps. - * ----------------------------------------------------------------------------- */ - -void Swig_typemap_replace_embedded_typemap(String *s, Node *file_line_node) { - Setfile(s, Getfile(file_line_node)); - Setline(s, Getline(file_line_node)); - Replaceall(s, "$typemap", "$TYPEMAP"); - replace_embedded_typemap(s, 0, 0, file_line_node); -} - -/* ----------------------------------------------------------------------------- - * replace_embedded_typemap() - * - * This function replaces the special variable macro $typemap(...) with typemap - * code. The general form of $typemap is as follows: - * - * $typemap(method, typelist, var1=value, var2=value, ...) - * - * where varx parameters are optional and undocumented; they were used in an earlier version of $typemap. - * A search is made using the typemap matching rules of form: - * - * %typemap(method) typelist {...} - * - * and if found will substitute in the typemap contents, making appropriate variable replacements. - * - * For example: - * $typemap(in, int) # simple usage matching %typemap(in) int { ... } - * $typemap(in, int b) # simple usage matching %typemap(in) int b { ... } or above %typemap - * $typemap(in, (Foo<int, bool> a, int b)) # multi-argument typemap matching %typemap(in) (Foo<int, bool> a, int b) {...} - * ----------------------------------------------------------------------------- */ - -static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f, Node *file_line_node) { - char *start = 0; - while ((start = strstr(Char(s), "$TYPEMAP("))) { /* note $typemap capitalisation to $TYPEMAP hack */ - - /* Gather the parameters */ - char *end = 0, *c; - int level = 0; - String *dollar_typemap; - int syntax_error = 1; - c = start; - while (*c) { - if (*c == '(') - level++; - if (*c == ')') { - level--; - if (level == 0) { - end = c + 1; - break; - } - } - c++; - } - if (end) { - dollar_typemap = NewStringWithSize(start, (int)((end - start))); - syntax_error = 0; - } else { - dollar_typemap = NewStringWithSize(start, (int)((c - start))); - } - - if (!syntax_error) { - List *l; - String *tmap_method; - Hash *vars; - syntax_error = 1; - - /* Split apart each parameter in $typemap(...) */ - l = split_embedded_typemap(dollar_typemap); - - if (Len(l) >= 2) { - ParmList *to_match_parms; - tmap_method = Getitem(l, 0); - - /* the second parameter might contain multiple sub-parameters for multi-argument - * typemap matching, so split these parameters apart */ - to_match_parms = Swig_cparse_parms(Getitem(l, 1), file_line_node); - if (to_match_parms) { - Parm *p = to_match_parms; - Parm *sub_p = parm_sublist; - String *empty_string = NewStringEmpty(); - String *lname = empty_string; - while (p) { - if (sub_p) { - lname = Getattr(sub_p, "lname"); - sub_p = nextSibling(sub_p); - } - Setattr(p, "lname", lname); - p = nextSibling(p); - } - Delete(empty_string); - } - - /* process optional extra parameters - the variable replacements (undocumented) */ - vars = NewHash(); - { - int i, ilen; - ilen = Len(l); - for (i = 2; i < ilen; i++) { - String *parm = Getitem(l, i); - char *eq = strchr(Char(parm), '='); - char *c = Char(parm); - if (eq && (eq - c > 0)) { - String *name = NewStringWithSize(c, (int)(eq - c)); - String *value = NewString(eq + 1); - Insert(name, 0, "$"); - Setattr(vars, name, value); - } else { - to_match_parms = 0; /* error - variable replacement parameters must be of form varname=value */ - } - } - } - - /* Perform a typemap search */ - if (to_match_parms) { - static int already_substituting = 0; - String *tm; - String *attr; - int match = 0; -#ifdef SWIG_DEBUG - Printf(stdout, "Swig_typemap_attach_parms: embedded\n"); -#endif - if (already_substituting < 10) { - char* found_colon; - already_substituting++; - if ((in_typemap_search_multi == 0) && typemap_search_debug) { - String *dtypemap = NewString(dollar_typemap); - Replaceall(dtypemap, "$TYPEMAP", "$typemap"); - Printf(stdout, " Containing: %s\n", dtypemap); - Delete(dtypemap); - } - found_colon = Strchr(tmap_method, ':'); - if (found_colon) { - /* Substitute from a keyword argument to a typemap. Avoid emitting local variables from the attached typemap by passing NULL for the file. */ - String *temp_tmap_method = NewStringWithSize(Char(tmap_method), (int)(found_colon - Char(tmap_method))); - Swig_typemap_attach_parms(temp_tmap_method, to_match_parms, NULL); - Delete(temp_tmap_method); - } else { - Swig_typemap_attach_parms(tmap_method, to_match_parms, f); - } - already_substituting--; - - /* Look for the typemap code */ - attr = NewStringf("tmap:%s", tmap_method); - tm = Getattr(to_match_parms, attr); - if (tm) { - Printf(attr, "%s", ":next"); - /* fail if multi-argument lookup requested in $typemap(...) and the lookup failed */ - if (!Getattr(to_match_parms, attr)) { - /* Replace parameter variables */ - Iterator ki; - for (ki = First(vars); ki.key; ki = Next(ki)) { - Replace(tm, ki.key, ki.item, DOH_REPLACE_ANY); - } - /* offer the target language module the chance to make special variable substitutions */ - Language_replace_special_variables(tmap_method, tm, to_match_parms); - /* finish up - do the substitution */ - Replace(s, dollar_typemap, tm, DOH_REPLACE_ANY); - Delete(tm); - match = 1; - } - } - - if (!match) { - String *dtypemap = NewString(dollar_typemap); - Replaceall(dtypemap, "$TYPEMAP", "$typemap"); - Swig_error(Getfile(s), Getline(s), "No typemap found for %s\n", dtypemap); - Delete(dtypemap); - } - Delete(attr); - } else { - /* Simple recursive call check to prevent infinite recursion - this strategy only allows a limited - * number of calls by a embedded typemaps to other embedded typemaps though */ - String *dtypemap = NewString(dollar_typemap); - Replaceall(dtypemap, "$TYPEMAP", "$typemap"); - Swig_error(Getfile(s), Getline(s), "Likely recursive $typemap calls containing %s. Use -debug-tmsearch to debug.\n", dtypemap); - Delete(dtypemap); - } - syntax_error = 0; - } - Delete(vars); - } - Delete(l); - } - - if (syntax_error) { - String *dtypemap = NewString(dollar_typemap); - Replaceall(dtypemap, "$TYPEMAP", "$typemap"); - Swig_error(Getfile(s), Getline(s), "Syntax error in: %s\n", dtypemap); - Delete(dtypemap); - } - Replace(s, dollar_typemap, "<error in embedded typemap>", DOH_REPLACE_ANY); - Delete(dollar_typemap); - } -} - -/* ----------------------------------------------------------------------------- - * Swig_typemap_debug() - * - * Display all typemaps - * ----------------------------------------------------------------------------- */ - -void Swig_typemap_debug(void) { - int nesting_level = 2; - Printf(stdout, "---[ typemaps ]--------------------------------------------------------------\n"); - Swig_print(typemaps, nesting_level); - Printf(stdout, "-----------------------------------------------------------------------------\n"); -} - - -/* ----------------------------------------------------------------------------- - * Swig_typemap_search_debug_set() - * - * Turn on typemap searching debug display - * ----------------------------------------------------------------------------- */ - -void Swig_typemap_search_debug_set(void) { - typemap_search_debug = 1; -} - -/* ----------------------------------------------------------------------------- - * Swig_typemap_used_debug_set() - * - * Turn on typemaps used debug display - * ----------------------------------------------------------------------------- */ - -void Swig_typemap_used_debug_set(void) { - typemaps_used_debug = 1; -} - -/* ----------------------------------------------------------------------------- - * Swig_typemap_register_debug_set() - * - * Turn on typemaps used debug display - * ----------------------------------------------------------------------------- */ - -void Swig_typemap_register_debug_set(void) { - typemap_register_debug = 1; -} - diff --git a/contrib/tools/swig/Source/Swig/typeobj.c b/contrib/tools/swig/Source/Swig/typeobj.c deleted file mode 100644 index 8cd2e28e98d..00000000000 --- a/contrib/tools/swig/Source/Swig/typeobj.c +++ /dev/null @@ -1,1367 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * typeobj.c - * - * This file provides functions for constructing, manipulating, and testing - * type objects. Type objects are merely the raw low-level representation - * of C++ types. They do not incorporate high-level type system features - * like typedef, namespaces, etc. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include <ctype.h> -#include <limits.h> - -/* ----------------------------------------------------------------------------- - * Synopsis - * - * This file provides a collection of low-level functions for constructing and - * manipulating C++ data types. In SWIG, C++ datatypes are encoded as simple - * text strings. This representation is compact, easy to debug, and easy to read. - * - * General idea: - * - * Types are represented by a base type (e.g., "int") and a collection of - * type operators applied to the base (e.g., pointers, arrays, etc...). - * - * Encoding: - * - * Types are encoded as strings of type constructors such as follows: - * - * String Encoding C Example - * --------------- --------- - * p.p.int int ** - * a(300).a(400).int int [300][400] - * p.q(const).char char const * - * - * All type constructors are denoted by a trailing '.': - * - * 'p.' = Pointer (*) - * 'r.' = Reference or ref-qualifier (&) - * 'z.' = Rvalue reference or ref-qualifier (&&) - * 'a(n).' = Array of size n [n] - * 'f(..,..).' = Function with arguments (args) - * 'q(str).' = Qualifier, such as const or volatile (cv-qualifier) - * 'm(cls).' = Pointer to member (cls::*) - * - * The complete type representation for varargs is: - * 'v(...)' - * - * The encoding follows the order that you might describe a type in words. - * For example "p.a(200).int" is "A pointer to array of int's" and - * "p.q(const).char" is "a pointer to a const char". - * - * This representation of types is fairly convenient because ordinary string - * operations can be used for type manipulation. For example, a type could be - * formed by combining two strings such as the following: - * - * "p.p." + "a(400).int" = "p.p.a(400).int" - * - * For C++, typenames may be parameterized using <(...)>. Here are some - * examples: - * - * String Encoding C++ Example - * --------------- ------------ - * p.vector<(int)> vector<int> * - * r.foo<(int,p.double)> foo<int,double *> & - * - * Contents of this file: - * - * Most of this functions in this file pertain to the low-level manipulation - * of type objects. There are constructor functions like this: - * - * SwigType_add_pointer() - * SwigType_add_reference() - * SwigType_add_rvalue_reference() - * SwigType_add_array() - * - * These are used to build new types. There are also functions to undo these - * operations. For example: - * - * SwigType_del_pointer() - * SwigType_del_reference() - * SwigType_del_rvalue_reference() - * SwigType_del_array() - * - * In addition, there are query functions - * - * SwigType_ispointer() - * SwigType_isreference() - * SwigType_isrvalue_reference() - * SwigType_isarray() - * - * Finally, there are some data extraction functions that can be used to - * extract array dimensions, template arguments, and so forth. - * - * It is very important for developers to realize that the functions in this - * module do *NOT* incorporate higher-level type system features like typedef. - * For example, you could have C code like this: - * - * typedef int *intptr; - * - * In this case, a SwigType of type 'intptr' will be treated as a simple type and - * functions like SwigType_ispointer() will evaluate as false. It is strongly - * advised that developers use the TypeSys_* interface to check types in a more - * reliable manner. - * ----------------------------------------------------------------------------- */ - - -/* ----------------------------------------------------------------------------- - * NewSwigType() - * - * Constructs a new type object. Eventually, it would be nice for this function - * to accept an initial value in the form a C/C++ abstract type (currently unimplemented). - * ----------------------------------------------------------------------------- */ - -#ifdef NEW -SwigType *NewSwigType(const_String_or_char_ptr initial) { - return NewString(initial); -} - -#endif - -/* The next few functions are utility functions used in the construction and - management of types */ - -/* ----------------------------------------------------------------------------- - * static element_size() - * - * This utility function finds the size of a single type element in a type string. - * Type elements are always delimited by periods, but may be nested with - * parentheses. A nested element is always handled as a single item. - * - * Returns the integer size of the element (which can be used to extract a - * substring, to chop the element off, or for other purposes). - * ----------------------------------------------------------------------------- */ - -static int element_size(char *c) { - int nparen; - char *s = c; - while (*c) { - if (*c == '.') { - c++; - return (int) (c - s); - } else if (*c == '(') { - nparen = 1; - c++; - while (*c) { - if (*c == '(') - nparen++; - if (*c == ')') { - nparen--; - if (nparen == 0) - break; - } - c++; - } - } - if (*c) - c++; - } - return (int) (c - s); -} - -/* ----------------------------------------------------------------------------- - * SwigType_del_element() - * - * Deletes one type element from the type. - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_del_element(SwigType *t) { - int sz = element_size(Char(t)); - Delslice(t, 0, sz); - return t; -} - -/* ----------------------------------------------------------------------------- - * SwigType_pop() - * - * Pop one type element off the type. - * For example: - * t in: q(const).p.Integer - * t out: p.Integer - * result: q(const). - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_pop(SwigType *t) { - SwigType *result; - char *c; - int sz; - - c = Char(t); - if (!*c) - return 0; - - sz = element_size(c); - result = NewStringWithSize(c, sz); - Delslice(t, 0, sz); - c = Char(t); - if (*c == '.') { - Delitem(t, 0); - } - return result; -} - -/* ----------------------------------------------------------------------------- - * SwigType_last() - * - * Return the last element of the given (partial) type. - * For example: - * t: q(const).p. - * result: p. - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_last(SwigType *t) { - SwigType *result; - char *c; - char *last; - int sz = 0; - - if (!t) - return 0; - - /* Find the last element */ - c = Char(t); - last = 0; - while (*c) { - last = c; - sz = element_size(c); - c = c + sz; - if (*c == '.') { - c++; - sz++; - } - } - - /* Extract the last element */ - if (last) { - result = NewStringWithSize(last, sz); - } else { - result = 0; - } - - return result; -} - -/* ----------------------------------------------------------------------------- - * SwigType_parm() - * - * Returns the parameter of an operator as a string - * ----------------------------------------------------------------------------- */ - -String *SwigType_parm(const SwigType *t) { - char *start, *c; - int nparens = 0; - - c = Char(t); - while (*c && (*c != '(') && (*c != '.')) - c++; - if (!*c || (*c == '.')) - return 0; - c++; - start = c; - while (*c) { - if (*c == ')') { - if (nparens == 0) - break; - nparens--; - } else if (*c == '(') { - nparens++; - } - c++; - } - return NewStringWithSize(start, (int) (c - start)); -} - -/* ----------------------------------------------------------------------------- - * SwigType_split() - * - * Splits a type into its component parts and returns a list of string. - * ----------------------------------------------------------------------------- */ - -List *SwigType_split(const SwigType *t) { - String *item; - List *list; - char *c; - int len; - - c = Char(t); - list = NewList(); - while (*c) { - len = element_size(c); - item = NewStringWithSize(c, len); - Append(list, item); - Delete(item); - c = c + len; - if (*c == '.') - c++; - } - return list; -} - -/* ----------------------------------------------------------------------------- - * SwigType_parmlist() - * - * Splits a comma separated list of parameters into its component parts - * The input is expected to contain the parameter list within () brackets - * Returns 0 if no argument list in the input, ie there are no round brackets () - * Returns an empty List if there are no parameters in the () brackets - * For example: - * - * Foo(std::string,p.f().Bar<(int,double)>) - * - * returns 2 elements in the list: - * std::string - * p.f().Bar<(int,double)> - * ----------------------------------------------------------------------------- */ - -List *SwigType_parmlist(const String *p) { - String *item = 0; - List *list; - char *c; - char *itemstart; - int size; - - assert(p); - c = Char(p); - while (*c && (*c != '(') && (*c != '.')) - c++; - if (!*c) - return 0; - assert(*c != '.'); /* p is expected to contain sub elements of a type */ - c++; - list = NewList(); - itemstart = c; - while (*c) { - if (*c == ',') { - size = (int) (c - itemstart); - item = NewStringWithSize(itemstart, size); - Append(list, item); - Delete(item); - itemstart = c + 1; - } else if (*c == '(') { - int nparens = 1; - c++; - while (*c) { - if (*c == '(') - nparens++; - if (*c == ')') { - nparens--; - if (nparens == 0) - break; - } - c++; - } - } else if (*c == ')') { - break; - } - if (*c) - c++; - } - size = (int) (c - itemstart); - if (size > 0) { - item = NewStringWithSize(itemstart, size); - Append(list, item); - } - Delete(item); - return list; -} - -/* ----------------------------------------------------------------------------- - * Pointers - * - * SwigType_add_pointer() - * SwigType_del_pointer() - * SwigType_ispointer() - * - * Add, remove, and test if a type is a pointer. The deletion and query - * functions take into account qualifiers (if any). - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_add_pointer(SwigType *t) { - Insert(t, 0, "p."); - return t; -} - -SwigType *SwigType_del_pointer(SwigType *t) { - char *c, *s; - c = Char(t); - s = c; - /* Skip qualifiers, if any */ - if (strncmp(c, "q(", 2) == 0) { - c = strchr(c, '.'); - assert(c); - c++; - } - if (strncmp(c, "p.", 2)) { - printf("Fatal error: SwigType_del_pointer applied to non-pointer.\n"); - Exit(EXIT_FAILURE); - } - Delslice(t, 0, (int)((c - s) + 2)); - return t; -} - -int SwigType_ispointer(const SwigType *t) { - char *c; - if (!t) - return 0; - c = Char(t); - /* Skip qualifiers, if any */ - if (strncmp(c, "q(", 2) == 0) { - c = strchr(c, '.'); - if (!c) - return 0; - c++; - } - if (strncmp(c, "p.", 2) == 0) { - return 1; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * References - * - * SwigType_add_reference() - * SwigType_del_reference() - * SwigType_isreference() - * - * Add, remove, and test if a type is a reference. The deletion and query - * functions take into account qualifiers (if any). - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_add_reference(SwigType *t) { - Insert(t, 0, "r."); - return t; -} - -SwigType *SwigType_del_reference(SwigType *t) { - char *c = Char(t); - if (strncmp(c, "r.", 2)) { - printf("Fatal error: SwigType_del_reference applied to non-reference.\n"); - Exit(EXIT_FAILURE); - } - Delslice(t, 0, 2); - return t; -} - -int SwigType_isreference(const SwigType *t) { - char *c; - if (!t) - return 0; - c = Char(t); - if (strncmp(c, "r.", 2) == 0) { - return 1; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * Rvalue References - * - * SwigType_add_rvalue_reference() - * SwigType_del_rvalue_reference() - * SwigType_isrvalue_reference() - * - * Add, remove, and test if a type is a rvalue reference. The deletion and query - * functions take into account qualifiers (if any). - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_add_rvalue_reference(SwigType *t) { - Insert(t, 0, "z."); - return t; -} - -SwigType *SwigType_del_rvalue_reference(SwigType *t) { - char *c = Char(t); - if (strncmp(c, "z.", 2)) { - fprintf(stderr, "Fatal error: SwigType_del_rvalue_reference() applied to non-rvalue-reference.\n"); - Exit(EXIT_FAILURE); - } - Delslice(t, 0, 2); - return t; -} - -int SwigType_isrvalue_reference(const SwigType *t) { - char *c; - if (!t) - return 0; - c = Char(t); - if (strncmp(c, "z.", 2) == 0) { - return 1; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * Qualifiers - * - * SwigType_add_qualifier() - * SwigType_del_qualifier() - * SwigType_is_qualifier() - * - * Adds type qualifiers like "const" and "volatile". When multiple qualifiers - * are added to a type, they are combined together into a single qualifier. - * Repeated qualifications have no effect. Moreover, the order of qualifications - * is alphabetical---meaning that "const volatile" and "volatile const" are - * stored in exactly the same way as "q(const volatile)". - * 'qual' can be a list of multiple qualifiers in any order, separated by spaces. - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual) { - List *qlist; - String *allq, *newq; - int i, sz; - const char *cqprev = 0; - const char *c = Char(t); - const char *cqual = Char(qual); - - /* if 't' has no qualifiers and 'qual' is a single qualifier, simply add it */ - if ((strncmp(c, "q(", 2) != 0) && (strstr(cqual, " ") == 0)) { - String *temp = NewStringf("q(%s).", cqual); - Insert(t, 0, temp); - Delete(temp); - return t; - } - - /* create string of all qualifiers */ - if (strncmp(c, "q(", 2) == 0) { - allq = SwigType_parm(t); - Append(allq, " "); - SwigType_del_element(t); /* delete old qualifier list from 't' */ - } else { - allq = NewStringEmpty(); - } - Append(allq, qual); - - /* create list of all qualifiers from string */ - qlist = Split(allq, ' ', INT_MAX); - Delete(allq); - - /* sort in alphabetical order */ - SortList(qlist, Strcmp); - - /* create new qualifier string from unique elements of list */ - sz = Len(qlist); - newq = NewString("q("); - for (i = 0; i < sz; ++i) { - String *q = Getitem(qlist, i); - const char *cq = Char(q); - if (cqprev == 0 || strcmp(cqprev, cq) != 0) { - if (i > 0) { - Append(newq, " "); - } - Append(newq, q); - cqprev = cq; - } - } - Append(newq, ")."); - Delete(qlist); - - /* replace qualifier string with new one */ - Insert(t, 0, newq); - Delete(newq); - return t; -} - -SwigType *SwigType_del_qualifier(SwigType *t) { - char *c = Char(t); - int check = strncmp(c, "q(", 2); - assert(check == 0); - (void)check; - Delslice(t, 0, element_size(c)); - return t; -} - -int SwigType_isqualifier(const SwigType *t) { - char *c; - if (!t) - return 0; - c = Char(t); - if (strncmp(c, "q(", 2) == 0) { - return 1; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * Function Pointers - * ----------------------------------------------------------------------------- */ - -int SwigType_isfunctionpointer(const SwigType *t) { - char *c; - if (!t) - return 0; - c = Char(t); - if (strncmp(c, "p.f(", 4) == 0) { - return 1; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * SwigType_functionpointer_decompose - * - * Decompose the function pointer into the parameter list and the return type - * t - input and on completion contains the return type - * returns the function's parameters - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_functionpointer_decompose(SwigType *t) { - String *p; - assert(SwigType_isfunctionpointer(t)); - p = SwigType_pop(t); - Delete(p); - p = SwigType_pop(t); - return p; -} - -/* ----------------------------------------------------------------------------- - * Member Pointers - * - * SwigType_add_memberpointer() - * SwigType_del_memberpointer() - * SwigType_ismemberpointer() - * - * Add, remove, and test for C++ pointer to members. - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_add_memberpointer(SwigType *t, const_String_or_char_ptr name) { - String *temp = NewStringf("m(%s).", name); - Insert(t, 0, temp); - Delete(temp); - return t; -} - -SwigType *SwigType_del_memberpointer(SwigType *t) { - char *c = Char(t); - int check = strncmp(c, "m(", 2); - assert(check == 0); - (void)check; - Delslice(t, 0, element_size(c)); - return t; -} - -int SwigType_ismemberpointer(const SwigType *t) { - char *c; - if (!t) - return 0; - c = Char(t); - if (strncmp(c, "m(", 2) == 0) { - return 1; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * Arrays - * - * SwigType_add_array() - * SwigType_del_array() - * SwigType_isarray() - * - * Utility functions: - * - * SwigType_array_ndim() - Calculate number of array dimensions. - * SwigType_array_getdim() - Get array dimension - * SwigType_array_setdim() - Set array dimension - * SwigType_array_type() - Return array type - * SwigType_pop_arrays() - Remove all arrays - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_add_array(SwigType *t, const_String_or_char_ptr size) { - String *temp = NewString("a("); - Append(temp, size); - Append(temp, ")."); - Insert(t, 0, temp); - Delete(temp); - return t; -} - -SwigType *SwigType_del_array(SwigType *t) { - char *c = Char(t); - if (strncmp(c, "a(", 2)) { - fprintf(stderr, "Fatal error: SwigType_del_array() applied to non-array.\n"); - Exit(EXIT_FAILURE); - } - Delslice(t, 0, element_size(c)); - return t; -} - -int SwigType_isarray(const SwigType *t) { - char *c; - if (!t) - return 0; - c = Char(t); - if (strncmp(c, "a(", 2) == 0) { - return 1; - } - return 0; -} -/* - * SwigType_prefix_is_simple_1D_array - * - * Determine if the type is a 1D array type that is treated as a pointer within SWIG - * eg Foo[], Foo[3] return true, but Foo[3][3], Foo*[], Foo*[3], Foo**[] return false - */ -int SwigType_prefix_is_simple_1D_array(const SwigType *t) { - char *c = Char(t); - - if (c && (strncmp(c, "a(", 2) == 0)) { - c = strchr(c, '.'); - if (c) - return (*(++c) == 0); - } - return 0; -} - - -/* Remove all arrays */ -SwigType *SwigType_pop_arrays(SwigType *t) { - String *ta; - assert(SwigType_isarray(t)); - ta = NewStringEmpty(); - while (SwigType_isarray(t)) { - SwigType *td = SwigType_pop(t); - Append(ta, td); - Delete(td); - } - return ta; -} - -/* Return number of array dimensions */ -int SwigType_array_ndim(const SwigType *t) { - int ndim = 0; - char *c = Char(t); - - while (c && (strncmp(c, "a(", 2) == 0)) { - c = strchr(c, '.'); - if (c) { - c++; - ndim++; - } - } - return ndim; -} - -/* Get nth array dimension */ -String *SwigType_array_getdim(const SwigType *t, int n) { - char *c = Char(t); - while (c && (strncmp(c, "a(", 2) == 0) && (n > 0)) { - c = strchr(c, '.'); - if (c) { - c++; - n--; - } - } - if (n == 0) { - String *dim = SwigType_parm(c); - if (SwigType_istemplate(dim)) { - String *ndim = SwigType_namestr(dim); - Delete(dim); - dim = ndim; - } - - return dim; - } - - return 0; -} - -/* Replace nth array dimension */ -void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep) { - String *result = 0; - char temp; - char *start; - char *c = Char(t); - - start = c; - if (strncmp(c, "a(", 2)) { - fprintf(stderr, "Fatal error: SwigType_array_type applied to non-array.\n"); - Exit(EXIT_FAILURE); - } - - while (c && (strncmp(c, "a(", 2) == 0) && (n > 0)) { - c = strchr(c, '.'); - if (c) { - c++; - n--; - } - } - if (n == 0) { - temp = *c; - *c = 0; - result = NewString(start); - Printf(result, "a(%s)", rep); - *c = temp; - c = strchr(c, '.'); - Append(result, c); - } - Clear(t); - Append(t, result); - Delete(result); -} - -/* Return base type of an array */ -SwigType *SwigType_array_type(const SwigType *ty) { - SwigType *t; - t = Copy(ty); - while (SwigType_isarray(t)) { - Delete(SwigType_pop(t)); - } - return t; -} - - -/* ----------------------------------------------------------------------------- - * Functions - * - * SwigType_add_function() - * SwigType_isfunction() - * SwigType_pop_function() - * - * Add, remove, and test for function types. - * ----------------------------------------------------------------------------- */ - -/* Returns the function type, t, constructed from the parameters, parms */ -SwigType *SwigType_add_function(SwigType *t, ParmList *parms) { - String *pstr; - Parm *p; - - Insert(t, 0, ")."); - pstr = NewString("f("); - for (p = parms; p; p = nextSibling(p)) { - if (p != parms) - Putc(',', pstr); - Append(pstr, Getattr(p, "type")); - } - Insert(t, 0, pstr); - Delete(pstr); - return t; -} - -/* ----------------------------------------------------------------------------- - * SwigType_pop_function() - * - * Pop and return the function from the input type leaving the function's return - * type, if any. - * For example: - * t in: q(const).f().p. - * t out: p. - * result: q(const).f(). - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_pop_function(SwigType *t) { - SwigType *f = 0; - SwigType *g = 0; - char *c = Char(t); - if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) { - /* Remove ref-qualifier */ - f = SwigType_pop(t); - c = Char(t); - } - if (strncmp(c, "q(", 2) == 0) { - /* Remove cv-qualifier */ - String *qual = SwigType_pop(t); - if (f) { - SwigType_push(qual, f); - Delete(f); - } - f = qual; - c = Char(t); - } - if (strncmp(c, "f(", 2)) { - fprintf(stderr, "Fatal error. SwigType_pop_function applied to non-function.\n"); - Exit(EXIT_FAILURE); - } - g = SwigType_pop(t); - if (f) - SwigType_push(g, f); - Delete(f); - return g; -} - -/* ----------------------------------------------------------------------------- - * SwigType_pop_function_qualifiers() - * - * Pop and return the function qualifiers from the input type leaving the rest of - * function declaration. Returns NULL if no qualifiers. - * For example: - * t in: r.q(const).f().p. - * t out: f().p. - * result: r.q(const) - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_pop_function_qualifiers(SwigType *t) { - SwigType *qualifiers = 0; - char *c = Char(t); - if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) { - /* Remove ref-qualifier */ - String *qual = SwigType_pop(t); - qualifiers = qual; - c = Char(t); - } - if (strncmp(c, "q(", 2) == 0) { - /* Remove cv-qualifier */ - String *qual = SwigType_pop(t); - if (qualifiers) { - SwigType_push(qual, qualifiers); - Delete(qualifiers); - } - qualifiers = qual; - } - assert(Strncmp(t, "f(", 2) == 0); - - return qualifiers; -} - -int SwigType_isfunction(const SwigType *t) { - char *c; - if (!t) { - return 0; - } - c = Char(t); - if (strncmp(c, "r.", 2) == 0 || strncmp(c, "z.", 2) == 0) { - /* Might be a function with a ref-qualifier, skip over */ - c += 2; - if (!*c) - return 0; - } - if (strncmp(c, "q(", 2) == 0) { - /* Might be a function with a cv-qualifier, skip over */ - c = strchr(c, '.'); - if (c) - c++; - else - return 0; - } - if (strncmp(c, "f(", 2) == 0) { - return 1; - } - return 0; -} - -/* Create a list of parameters from the type t, using the file_line_node Node for - * file and line numbering for the parameters */ -ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node) { - List *l = SwigType_parmlist(t); - Hash *p, *pp = 0, *firstp = 0; - Iterator o; - - for (o = First(l); o.item; o = Next(o)) { - p = file_line_node ? NewParm(o.item, 0, file_line_node) : NewParmWithoutFileLineInfo(o.item, 0); - if (!firstp) - firstp = p; - if (pp) { - set_nextSibling(pp, p); - Delete(p); - } - pp = p; - } - Delete(l); - return firstp; -} - -int SwigType_isvarargs(const SwigType *t) { - if (Strcmp(t, "v(...)") == 0) - return 1; - return 0; -} - -/* ----------------------------------------------------------------------------- - * Templates - * - * SwigType_add_template() - * - * Template handling. - * ----------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------------- - * SwigType_add_template() - * - * Adds a template to a type. This template is encoded in the SWIG type - * mechanism and produces a string like this: - * - * vector<int *> ----> "vector<(p.int)>" - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_add_template(SwigType *t, ParmList *parms) { - Parm *p; - - Append(t, "<("); - for (p = parms; p; p = nextSibling(p)) { - String *v; - if (Getattr(p, "default")) - continue; - if (p != parms) - Append(t, ","); - v = Getattr(p, "value"); - if (v) { - Append(t, v); - } else { - Append(t, Getattr(p, "type")); - } - } - Append(t, ")>"); - return t; -} - - -/* ----------------------------------------------------------------------------- - * SwigType_templateprefix() - * - * Returns the prefix before the first template definition. - * Returns the type unmodified if not a template. - * For example: - * - * Foo<(p.int)>::bar => Foo - * r.q(const).Foo<(p.int)>::bar => r.q(const).Foo - * Foo => Foo - * ----------------------------------------------------------------------------- */ - -String *SwigType_templateprefix(const SwigType *t) { - const char *s = Char(t); - const char *c = strstr(s, "<("); - return c ? NewStringWithSize(s, (int)(c - s)) : NewString(s); -} - -/* ----------------------------------------------------------------------------- - * SwigType_templatesuffix() - * - * Returns text after a template substitution. Used to handle scope names - * for example: - * - * Foo<(p.int)>::bar - * - * returns "::bar" - * ----------------------------------------------------------------------------- */ - -String *SwigType_templatesuffix(const SwigType *t) { - const char *c; - c = Char(t); - while (*c) { - if ((*c == '<') && (*(c + 1) == '(')) { - int nest = 1; - c++; - while (*c && nest) { - if (*c == '<') - nest++; - if (*c == '>') - nest--; - c++; - } - return NewString(c); - } - c++; - } - return NewStringEmpty(); -} - -/* ----------------------------------------------------------------------------- - * SwigType_istemplate_templateprefix() - * - * Combines SwigType_istemplate and SwigType_templateprefix efficiently into one function. - * Returns the prefix before the first template definition. - * Returns NULL if not a template. - * For example: - * - * Foo<(p.int)>::bar => Foo - * r.q(const).Foo<(p.int)>::bar => r.q(const).Foo - * Foo => NULL - * ----------------------------------------------------------------------------- */ - -String *SwigType_istemplate_templateprefix(const SwigType *t) { - const char *s = Char(t); - const char *c = strstr(s, "<("); - return c ? NewStringWithSize(s, (int)(c - s)) : 0; -} - -/* ----------------------------------------------------------------------------- - * SwigType_istemplate_only_templateprefix() - * - * Similar to SwigType_istemplate_templateprefix() but only returns the template - * prefix if the type is just the template and not a subtype/symbol within the template. - * Returns NULL if not a template or is a template with a symbol within the template. - * For example: - * - * Foo<(p.int)> => Foo - * Foo<(p.int)>::bar => NULL - * r.q(const).Foo<(p.int)> => r.q(const).Foo - * r.q(const).Foo<(p.int)>::bar => NULL - * Foo => NULL - * ----------------------------------------------------------------------------- */ - -String *SwigType_istemplate_only_templateprefix(const SwigType *t) { - int len = Len(t); - const char *s = Char(t); - if (len >= 4 && strcmp(s + len - 2, ")>") == 0) { - const char *c = strstr(s, "<("); - return c ? NewStringWithSize(s, (int)(c - s)) : 0; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * SwigType_templateargs() - * - * Returns the template arguments - * For example: - * - * Foo<(p.int)>::bar - * - * returns "<(p.int)>" - * ----------------------------------------------------------------------------- */ - -String *SwigType_templateargs(const SwigType *t) { - const char *c; - const char *start; - c = Char(t); - while (*c) { - if ((*c == '<') && (*(c + 1) == '(')) { - int nest = 1; - start = c; - c++; - while (*c && nest) { - if (*c == '<') - nest++; - if (*c == '>') - nest--; - c++; - } - return NewStringWithSize(start, (int)(c - start)); - } - c++; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * SwigType_istemplate() - * - * Tests a type to see if it includes template parameters - * ----------------------------------------------------------------------------- */ - -int SwigType_istemplate(const SwigType *t) { - char *ct = Char(t); - ct = strstr(ct, "<("); - if (ct && (strstr(ct + 2, ")>"))) - return 1; - return 0; -} - -/* ----------------------------------------------------------------------------- - * SwigType_base() - * - * This function returns the base of a type. For example, if you have a - * type "p.p.int", the function would return "int". - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_base(const SwigType *t) { - char *c; - char *lastop = 0; - c = Char(t); - - lastop = c; - - /* Search for the last type constructor separator '.' */ - while (*c) { - if (*c == '.') { - if (*(c + 1)) { - lastop = c + 1; - } - c++; - continue; - } - if (*c == '<') { - /* Skip over template---it's part of the base name */ - int ntemp = 1; - c++; - while ((*c) && (ntemp > 0)) { - if (*c == '>') - ntemp--; - else if (*c == '<') - ntemp++; - c++; - } - if (ntemp) - break; - continue; - } - if (*c == '(') { - /* Skip over params */ - int nparen = 1; - c++; - while ((*c) && (nparen > 0)) { - if (*c == '(') - nparen++; - else if (*c == ')') - nparen--; - c++; - } - if (nparen) - break; - continue; - } - c++; - } - return NewString(lastop); -} - -/* ----------------------------------------------------------------------------- - * SwigType_prefix() - * - * Returns the prefix of a datatype. For example, the prefix of the - * type "p.p.int" is "p.p.". - * ----------------------------------------------------------------------------- */ - -String *SwigType_prefix(const SwigType *t) { - char *c, *d; - String *r = 0; - - c = Char(t); - d = c + strlen(c); - - /* Check for a type constructor */ - if ((d > c) && (*(d - 1) == '.')) - d--; - - while (d > c) { - d--; - if (*d == '>') { - int nest = 1; - d--; - while ((d > c) && (nest)) { - if (*d == '>') - nest++; - if (*d == '<') - nest--; - d--; - } - } - if (*d == ')') { - /* Skip over params */ - int nparen = 1; - d--; - while ((d > c) && (nparen)) { - if (*d == ')') - nparen++; - if (*d == '(') - nparen--; - d--; - } - } - - if (*d == '.') { - char t = *(d + 1); - *(d + 1) = 0; - r = NewString(c); - *(d + 1) = t; - return r; - } - } - return NewStringEmpty(); -} - -/* ----------------------------------------------------------------------------- - * SwigType_strip_qualifiers() - * - * Strip all qualifiers from a type and return a new type - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_strip_qualifiers(const SwigType *t) { - static Hash *memoize_stripped = 0; - SwigType *r; - List *l; - Iterator ei; - - if (!memoize_stripped) - memoize_stripped = NewHash(); - r = Getattr(memoize_stripped, t); - if (r) - return Copy(r); - - l = SwigType_split(t); - r = NewStringEmpty(); - - for (ei = First(l); ei.item; ei = Next(ei)) { - if (SwigType_isqualifier(ei.item)) - continue; - Append(r, ei.item); - } - Delete(l); - { - String *key, *value; - key = Copy(t); - value = Copy(r); - Setattr(memoize_stripped, key, value); - Delete(key); - Delete(value); - } - return r; -} - -/* ----------------------------------------------------------------------------- - * SwigType_strip_single_qualifier() - * - * If the type contains a qualifier, strip one qualifier and return a new type. - * The left most qualifier is stripped first (when viewed as C source code) but - * this is the equivalent to the right most qualifier using SwigType notation. - * Example: - * r.q(const).p.q(const).int => r.q(const).p.int - * r.q(const).p.int => r.p.int - * r.p.int => r.p.int - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_strip_single_qualifier(const SwigType *t) { - static Hash *memoize_stripped = 0; - SwigType *r = 0; - List *l; - int numitems; - - if (!memoize_stripped) - memoize_stripped = NewHash(); - r = Getattr(memoize_stripped, t); - if (r) - return Copy(r); - - l = SwigType_split(t); - - numitems = Len(l); - if (numitems >= 2) { - int item; - /* iterate backwards from last but one item */ - for (item = numitems - 2; item >= 0; --item) { - String *subtype = Getitem(l, item); - if (SwigType_isqualifier(subtype)) { - Iterator it; - Delitem(l, item); - r = NewStringEmpty(); - for (it = First(l); it.item; it = Next(it)) { - Append(r, it.item); - } - break; - } - } - } - if (!r) - r = Copy(t); - - Delete(l); - { - String *key, *value; - key = Copy(t); - value = Copy(r); - Setattr(memoize_stripped, key, value); - Delete(key); - Delete(value); - } - return r; -} - diff --git a/contrib/tools/swig/Source/Swig/typesys.c b/contrib/tools/swig/Source/Swig/typesys.c deleted file mode 100644 index 4a11790c72d..00000000000 --- a/contrib/tools/swig/Source/Swig/typesys.c +++ /dev/null @@ -1,2309 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * typesys.c - * - * SWIG type system management. These functions are used to manage - * the C++ type system including typenames, typedef, type scopes, - * inheritance, and namespaces. Generation of support code for the - * run-time type checker is also handled here. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include "cparse.h" - -/* ----------------------------------------------------------------------------- - * Synopsis - * - * The purpose of this module is to manage type names and scoping issues related - * to the C++ type system. The primary use is tracking typenames through typedef - * and inheritance. - * - * New typenames are introduced by typedef, class, and enum declarations. - * Each type is declared in a scope. This is either the global scope, a - * class, or a namespace. For example: - * - * typedef int A; // Typename A, in global scope - * namespace Foo { - * typedef int A; // Typename A, in scope Foo:: - * } - * class Bar { // Typename Bar, in global scope - * typedef int A; // Typename A, in scope Bar:: - * } - * - * To manage scopes, the type system is constructed as a tree of hash tables. Each - * hash table contains the following attributes: - * - * "name" - Scope name - * "qname" - Fully qualified typename - * "typetab" - Type table containing typenames and typedef information - * For a given key in the typetab table, the value is a fully - * qualified name if not pointing to itself. - * "symtab" - Hash table of symbols defined in a scope - * "inherit" - List of inherited scopes - * "parent" - Parent scope - * - * The contents of these tables can be viewed for debugging using the -debug-typedef - * option which calls SwigType_print_scope(). - * - * Typedef information is stored in the "typetab" hash table. For example, - * if you have these declarations: - * - * typedef int A; - * typedef A B; - * typedef B *C; - * - * typetab in scope '' contains: - * "A" : "int" - * "B" : "A" - * "C" : "p.B" - * - * To resolve a type back to its root type, one repeatedly expands on the type base. - * For example: - * - * C *[40] ---> a(40).p.C (string type representation, see stype.c) - * ---> a(40).p.p.B (C --> p.B) - * ---> a(40).p.p.A (B --> A) - * ---> a(40).p.p.int (A --> int) - * - * - * Using declarations are stored in the "typetab" hash table. For example, - * - * namespace NN { - * struct SS {}; - * } - * namespace N { - * struct S {}; - * using NN::SS; - * } - * using N::S; - * - * typetab in scope '' contains: - * "S" : "N::S" - * - * and typetab in scope 'N' contains: - * "SS" : "NN::SS" - * "S" : "S" - * - * - * For inheritance, SWIG tries to resolve types back to the base class. For instance, if - * you have this: - * - * class Foo { - * public: - * typedef int Integer; - * }; - * struct Bar : public Foo { - * void blah(Integer x); - * }; - * - * In this case typetab in scope '' contains: - * "Foo" : "Foo" - * "Bar" : "Bar" - * and scope 'Foo' contains: - * "Integer" : "int" - * and scope 'Bar' inherits from 'Foo' but is empty (observe that blah is not a scope or typedef) - * - * The argument type of Bar::blah will be set to Foo::Integer. - * - * - * The scope-inheritance mechanism is used to manage C++ using directives. - * - * namespace XX { - * class CC {}; - * } - * namespace X { - * class C {}; - * using namespace XX; - * } - * using namespace X; - * - * typetab in scope '' inherits from 'X' - * typetab in scope 'X' inherits from 'XX' and contains: - * "C" : "C" - * typetab in scope 'XX' contains: - * "CC" : "CC" - * - * - * The scope-inheritance mechanism is used to manage C++ namespace aliases. - * For example, if you have this: - * - * namespace Foo { - * typedef int Integer; - * } - * - * namespace F = Foo; - * - * In this case, F is defined as a scope that "inherits" from Foo. Internally, - * F will merely be an empty scope that points to Foo. SWIG will never - * place new type information into a namespace alias---attempts to do so - * will generate a warning message (in the parser) and will place information into - * Foo instead. - * - *----------------------------------------------------------------------------- */ - -static Typetab *current_scope = 0; /* Current type scope */ -static Hash *current_typetab = 0; /* Current type table */ -static Hash *current_symtab = 0; /* Current symbol table */ -static Typetab *global_scope = 0; /* The global scope */ -static Hash *scopes = 0; /* Hash table containing fully qualified scopes */ - -/* Performance optimization */ -#define SWIG_TYPEDEF_RESOLVE_CACHE -static Hash *typedef_resolve_cache = 0; -static Hash *typedef_all_cache = 0; -static Hash *typedef_qualified_cache = 0; - -static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix); - -/* common attribute keys, to avoid calling find_key all the times */ - -/* - Enable this one if your language fully support SwigValueWrapper<T>. - - Leaving at '0' keeps the old swig behavior, which is not - always safe, but is well known. - - Setting at '1' activates the new scheme, which is always safe but - it requires all the typemaps to be ready for that. - -*/ -static int value_wrapper_mode = 0; -int Swig_value_wrapper_mode(int mode) { - value_wrapper_mode = mode; - return mode; -} - - -static void flush_cache(void) { - typedef_resolve_cache = 0; - typedef_all_cache = 0; - typedef_qualified_cache = 0; -} - -/* Initialize the scoping system */ - -void SwigType_typesystem_init(void) { - if (global_scope) - Delete(global_scope); - if (scopes) - Delete(scopes); - - current_scope = NewHash(); - global_scope = current_scope; - - Setattr(current_scope, "name", ""); /* No name for global scope */ - current_typetab = NewHash(); - Setattr(current_scope, "typetab", current_typetab); - - current_symtab = 0; - scopes = NewHash(); - Setattr(scopes, "", current_scope); -} - - -/* ----------------------------------------------------------------------------- - * SwigType_typedef() - * - * Defines a new typedef in the current scope. Returns -1 if the type name is - * already defined. - * ----------------------------------------------------------------------------- */ - -int SwigType_typedef(const SwigType *type, const_String_or_char_ptr name) { - /* Printf(stdout, "typedef %s %s\n", type, name); */ - if (Getattr(current_typetab, name)) - return -1; /* Already defined */ - if (Strcmp(type, name) == 0) { /* Can't typedef a name to itself */ - return 0; - } - - /* Check if 'type' is already a scope. If so, we create an alias in the type - system for it. This is needed to make strange nested scoping problems work - correctly. */ - { - Typetab *t = SwigType_find_scope(current_scope, type); - if (t) { - SwigType_new_scope(name); - SwigType_inherit_scope(t); - SwigType_pop_scope(); - } - } - Setattr(current_typetab, name, type); - flush_cache(); - return 0; -} - - -/* ----------------------------------------------------------------------------- - * SwigType_typedef_class() - * - * Defines a class in the current scope. - * ----------------------------------------------------------------------------- */ - -int SwigType_typedef_class(const_String_or_char_ptr name) { - String *cname; - /* Printf(stdout,"class : '%s'\n", name); */ - if (Getattr(current_typetab, name)) - return -1; /* Already defined */ - cname = NewString(name); - Setmeta(cname, "class", "1"); - Setattr(current_typetab, cname, cname); - Delete(cname); - flush_cache(); - return 0; -} - -/* ----------------------------------------------------------------------------- - * SwigType_scope_name() - * - * Returns the qualified scope name of a type table - * ----------------------------------------------------------------------------- */ - -String *SwigType_scope_name(Typetab *ttab) { - String *qname = NewString(Getattr(ttab, "name")); - ttab = Getattr(ttab, "parent"); - while (ttab) { - String *pname = Getattr(ttab, "name"); - if (Len(pname)) { - Insert(qname, 0, "::"); - Insert(qname, 0, pname); - } - ttab = Getattr(ttab, "parent"); - } - return qname; -} - -/* ----------------------------------------------------------------------------- - * SwigType_new_scope() - * - * Creates a new scope - * ----------------------------------------------------------------------------- */ - -void SwigType_new_scope(const_String_or_char_ptr name) { - Typetab *s; - Hash *ttab; - String *qname; - - if (!name) { - name = "<unnamed>"; - } - s = NewHash(); - Setattr(s, "name", name); - Setattr(s, "parent", current_scope); - ttab = NewHash(); - Setattr(s, "typetab", ttab); - - /* Build fully qualified name */ - qname = SwigType_scope_name(s); -#if 1 - { - /* TODO: only do with templates? What happens with non-templates with code below? */ - String *stripped_qname; - stripped_qname = SwigType_remove_global_scope_prefix(qname); - /* Use fully qualified name for hash key without unary scope prefix, qname may contain unary scope */ - Setattr(scopes, stripped_qname, s); - Setattr(s, "qname", qname); - /* - Printf(stdout, "SwigType_new_scope stripped %s %s\n", qname, stripped_qname); - */ - Delete(stripped_qname); - } -#else - Printf(stdout, "SwigType_new_scope %s\n", qname); - Setattr(scopes, qname, s); - Setattr(s, "qname", qname); -#endif - Delete(qname); - - current_scope = s; - current_typetab = ttab; - current_symtab = 0; - flush_cache(); -} - -/* ----------------------------------------------------------------------------- - * SwigType_inherit_scope() - * - * Makes the current scope inherit from another scope. This is used for both - * C++ class inheritance, namespaces, and namespace aliases. - * ----------------------------------------------------------------------------- */ - -void SwigType_inherit_scope(Typetab *scope) { - List *inherits; - int i, len; - inherits = Getattr(current_scope, "inherit"); - if (!inherits) { - inherits = NewList(); - Setattr(current_scope, "inherit", inherits); - Delete(inherits); - } - assert(scope != current_scope); - - len = Len(inherits); - for (i = 0; i < len; i++) { - Node *n = Getitem(inherits, i); - if (n == scope) - return; - } - Append(inherits, scope); -} - -/* ----------------------------------------------------------------------------- - * SwigType_scope_alias() - * - * Creates a scope-alias. - * ----------------------------------------------------------------------------- */ - -void SwigType_scope_alias(String *aliasname, Typetab *ttab) { - String *q; - /* Printf(stdout,"alias: '%s' '%p'\n", aliasname, ttab); */ - q = SwigType_scope_name(current_scope); - if (Len(q)) { - Append(q, "::"); - } - Append(q, aliasname); - Setattr(scopes, q, ttab); - flush_cache(); -} - -/* ----------------------------------------------------------------------------- - * SwigType_using_scope() - * - * Import another scope into this scope. - * ----------------------------------------------------------------------------- */ - -void SwigType_using_scope(Typetab *scope) { - SwigType_inherit_scope(scope); - { - List *ulist; - int i, len; - ulist = Getattr(current_scope, "using"); - if (!ulist) { - ulist = NewList(); - Setattr(current_scope, "using", ulist); - Delete(ulist); - } - assert(scope != current_scope); - len = Len(ulist); - for (i = 0; i < len; i++) { - Typetab *n = Getitem(ulist, i); - if (n == scope) - return; - } - Append(ulist, scope); - } - flush_cache(); -} - -/* ----------------------------------------------------------------------------- - * SwigType_pop_scope() - * - * Pop off the last scope and perform a merge operation. Returns the hash - * table for the scope that was popped off. - * ----------------------------------------------------------------------------- */ - -Typetab *SwigType_pop_scope(void) { - Typetab *t, *old = current_scope; - t = Getattr(current_scope, "parent"); - if (!t) - t = global_scope; - current_scope = t; - current_typetab = Getattr(t, "typetab"); - current_symtab = Getattr(t, "symtab"); - flush_cache(); - return old; -} - -/* ----------------------------------------------------------------------------- - * SwigType_set_scope() - * - * Set the scope. Returns the old scope. - * ----------------------------------------------------------------------------- */ - -Typetab *SwigType_set_scope(Typetab *t) { - Typetab *old = current_scope; - if (!t) - t = global_scope; - current_scope = t; - current_typetab = Getattr(t, "typetab"); - current_symtab = Getattr(t, "symtab"); - flush_cache(); - return old; -} - -/* ----------------------------------------------------------------------------- - * SwigType_attach_symtab() - * - * Attaches a symbol table to a type scope - * ----------------------------------------------------------------------------- */ - -void SwigType_attach_symtab(Symtab *sym) { - Setattr(current_scope, "symtab", sym); - current_symtab = sym; -} - -/* ----------------------------------------------------------------------------- - * SwigType_print_scope() - * - * Debugging function for printing out current scope - * ----------------------------------------------------------------------------- */ - -void SwigType_print_scope(void) { - Hash *ttab; - Iterator i, j; - - Printf(stdout, "SCOPES start =======================================\n"); - for (i = First(scopes); i.key; i = Next(i)) { - Printf(stdout, "-------------------------------------------------------------\n"); - ttab = Getattr(i.item, "typetab"); - - Printf(stdout, "Type scope '%s' (%p)\n", i.key, i.item); - { - List *inherit = Getattr(i.item, "inherit"); - if (inherit) { - Iterator j; - for (j = First(inherit); j.item; j = Next(j)) { - Printf(stdout, " Inherits from '%s' (%p)\n", Getattr(j.item, "qname"), j.item); - } - } - } - for (j = First(ttab); j.key; j = Next(j)) { - Printf(stdout, "%40s -> %s\n", j.key, j.item); - } - } - Printf(stdout, "SCOPES finish =======================================\n"); -} - -static Typetab *SwigType_find_scope(Typetab *s, const SwigType *nameprefix) { - Typetab *ss; - Typetab *s_orig = s; - String *nnameprefix = 0; - static int check_parent = 1; - int is_template = 0; - - if (Getmark(s)) - return 0; - Setmark(s, 1); - - is_template = SwigType_istemplate(nameprefix); - if (is_template) { - nnameprefix = SwigType_typedef_resolve_all(nameprefix); - nameprefix = nnameprefix; - } - - ss = s; - while (ss) { - String *full; - String *qname = Getattr(ss, "qname"); - if (qname) { - full = NewStringf("%s::%s", qname, nameprefix); - } else { - full = NewString(nameprefix); - } - s = Getattr(scopes, full); - if (!s && is_template) { - /* try look up scope with all the unary scope operators within the template parameter list removed */ - SwigType *full_stripped = SwigType_remove_global_scope_prefix(full); - s = Getattr(scopes, full_stripped); - Delete(full_stripped); - } - Delete(full); - if (s) { - if (nnameprefix) - Delete(nnameprefix); - Setmark(s_orig, 0); - return s; - } - if (!s) { - /* Check inheritance */ - List *inherit; - inherit = Getattr(ss, "using"); - if (inherit) { - Typetab *ttab; - int i, len; - len = Len(inherit); - for (i = 0; i < len; i++) { - int oldcp = check_parent; - ttab = Getitem(inherit, i); - check_parent = 0; - s = SwigType_find_scope(ttab, nameprefix); - check_parent = oldcp; - if (s) { - if (nnameprefix) - Delete(nnameprefix); - Setmark(s_orig, 0); - return s; - } - } - } - } - if (!check_parent) - break; - ss = Getattr(ss, "parent"); - } - if (nnameprefix) - Delete(nnameprefix); - Setmark(s_orig, 0); - return 0; -} - -/* ----------------------------------------------------------------------------- - * typedef_resolve() - * - * Resolves a typedef and returns a new type string. Returns 0 if there is no - * typedef mapping. base is a name without qualification. - * Internal function. - * ----------------------------------------------------------------------------- */ - -static Typetab *resolved_scope = 0; - -/* Internal function */ - -static SwigType *_typedef_resolve(Typetab *s, String *base, int look_parent) { - Hash *ttab; - SwigType *type = 0; - List *inherit; - Typetab *parent; - - /* if (!s) return 0; *//* now is checked below */ - /* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base); */ - - if (!Getmark(s)) { - Setmark(s, 1); - - ttab = Getattr(s, "typetab"); - type = Getattr(ttab, base); - if (type) { - resolved_scope = s; - Setmark(s, 0); - } else { - /* Hmmm. Not found in my scope. It could be in an inherited scope */ - inherit = Getattr(s, "inherit"); - if (inherit) { - int i, len; - len = Len(inherit); - for (i = 0; i < len; i++) { - type = _typedef_resolve(Getitem(inherit, i), base, 0); - if (type) { - Setmark(s, 0); - break; - } - } - } - if (!type) { - /* Hmmm. Not found in my scope. check parent */ - if (look_parent) { - parent = Getattr(s, "parent"); - type = parent ? _typedef_resolve(parent, base, 1) : 0; - } - } - Setmark(s, 0); - } - } - return type; -} - -/* ----------------------------------------------------------------------------- - * template_parameters_resolve() - * - * For use with templates only. Attempts to resolve one template parameter. - * - * If one of the template parameters can be resolved, the type is returned with - * just the one parameter resolved and the remaining parameters left as is. - * If none of the template parameters can be resolved, zero is returned. - * ----------------------------------------------------------------------------- */ - -static String *template_parameters_resolve(const String *base) { - List *tparms; - String *suffix; - String *type; - int i, sz; - int rep = 0; - type = SwigType_templateprefix(base); - suffix = SwigType_templatesuffix(base); - Append(type, "<("); - tparms = SwigType_parmlist(base); - sz = Len(tparms); - for (i = 0; i < sz; i++) { - SwigType *tpr; - SwigType *tp = Getitem(tparms, i); - if (!rep) { - tpr = SwigType_typedef_resolve(tp); - } else { - tpr = 0; - } - if (tpr) { - Append(type, tpr); - Delete(tpr); - rep = 1; - } else { - Append(type, tp); - } - if ((i + 1) < sz) - Append(type, ","); - } - if (rep) { - Append(type, ")>"); - Append(type, suffix); - } else { - Delete(type); - type = 0; - } - Delete(suffix); - Delete(tparms); - return type; -} - -static SwigType *typedef_resolve(Typetab *s, String *base) { - return _typedef_resolve(s, base, 1); -} - - -/* ----------------------------------------------------------------------------- - * SwigType_typedef_resolve() - * - * Given a type declaration, this function looks to reduce/resolve the type via a - * typedef (including via C++ using declarations). - * - * If it is able to find a typedef, the resolved type is returned. If no typedef - * is found NULL is returned. The type name is resolved in the current scope. - * The type returned is not always fully qualified for the global scope, it is - * valid for use in the current scope. If the current scope is global scope, a - * fully qualified type should be returned. - * - * Some additional notes are in Doc/Manual/Extending.html. - * ----------------------------------------------------------------------------- */ - -/* #define SWIG_DEBUG */ -SwigType *SwigType_typedef_resolve(const SwigType *t) { - String *base; - String *type = 0; - String *r = 0; - Typetab *s; - Hash *ttab; - String *namebase = 0; - String *nameprefix = 0, *rnameprefix = 0; - int newtype = 0; - - resolved_scope = 0; - -#ifdef SWIG_TYPEDEF_RESOLVE_CACHE - if (!typedef_resolve_cache) { - typedef_resolve_cache = NewHash(); - } - r = Getattr(typedef_resolve_cache, t); - if (r) { - resolved_scope = Getmeta(r, "scope"); - return Copy(r); - } -#endif - - base = SwigType_base(t); - -#ifdef SWIG_DEBUG - Printf(stdout, "base = '%s' t='%s'\n", base, t); -#endif - - if (SwigType_issimple(base)) { - s = current_scope; - ttab = current_typetab; - if (strncmp(Char(base), "::", 2) == 0) { - s = global_scope; - ttab = Getattr(s, "typetab"); - Delitem(base, 0); - Delitem(base, 0); - } - /* Do a quick check in the local scope */ - type = Getattr(ttab, base); - if (type) { - resolved_scope = s; - } - if (!type) { - /* Didn't find in this scope. We need to do a little more searching */ - if (Swig_scopename_check(base)) { - /* A qualified name. */ - Swig_scopename_split(base, &nameprefix, &namebase); -#ifdef SWIG_DEBUG - Printf(stdout, "nameprefix = '%s'\n", nameprefix); -#endif - if (nameprefix) { - rnameprefix = SwigType_typedef_resolve(nameprefix); - if(rnameprefix != NULL) { -#ifdef SWIG_DEBUG - Printf(stdout, "nameprefix '%s' is a typedef to '%s'\n", nameprefix, rnameprefix); -#endif - type = Copy(namebase); - Insert(type, 0, "::"); - Insert(type, 0, rnameprefix); - if (strncmp(Char(type), "::", 2) == 0) { - Delitem(type, 0); - Delitem(type, 0); - } - newtype = 1; - } else { - /* Name had a prefix on it. See if we can locate the proper scope for it */ - String *rnameprefix = template_parameters_resolve(nameprefix); - nameprefix = rnameprefix ? Copy(rnameprefix) : nameprefix; - Delete(rnameprefix); - s = SwigType_find_scope(s, nameprefix); - - /* Couldn't locate a scope for the type. */ - if (!s) { - Delete(base); - Delete(namebase); - Delete(nameprefix); - r = 0; - goto return_result; - } - /* Try to locate the name starting in the scope */ -#ifdef SWIG_DEBUG - Printf(stdout, "namebase = '%s'\n", namebase); -#endif - type = typedef_resolve(s, namebase); - if (type && resolved_scope) { - /* we need to look for the resolved type, this will also - fix the resolved_scope if 'type' and 'namebase' are - declared in different scopes */ - String *rtype = 0; - rtype = typedef_resolve(resolved_scope, type); - if (rtype) - type = rtype; - } -#ifdef SWIG_DEBUG - Printf(stdout, "%s type = '%s'\n", Getattr(s, "name"), type); -#endif - if ((type) && (!Swig_scopename_check(type)) && resolved_scope) { - Typetab *rtab = resolved_scope; - String *qname = Getattr(resolved_scope, "qname"); - /* If qualified *and* the typename is defined from the resolved scope, we qualify */ - if ((qname) && typedef_resolve(resolved_scope, type)) { - type = Copy(type); - Insert(type, 0, "::"); - Insert(type, 0, qname); -#ifdef SWIG_DEBUG - Printf(stdout, "qual %s \n", type); -#endif - newtype = 1; - } - resolved_scope = rtab; - } - } - } else { - /* Name is unqualified. */ - type = typedef_resolve(s, base); - } - } else { - /* Name is unqualified. */ - type = typedef_resolve(s, base); - } - } - - if (!type && SwigType_istemplate(base)) { - String *tprefix = SwigType_templateprefix(base); - String *rtprefix = SwigType_typedef_resolve(tprefix); - /* We're looking for a using declaration on the template prefix to resolve the template prefix - * in another scope. Using declaration do not have template parameters. */ - if (rtprefix && !SwigType_istemplate(rtprefix)) { - String *tsuffix = SwigType_templatesuffix(base); - String *targs = SwigType_templateargs(base); - type = NewString(rtprefix); - newtype = 1; - Append(type, targs); - Append(type, tsuffix); - Delete(targs); - Delete(tsuffix); - Delete(rtprefix); - } - Delete(tprefix); - } - - if (type && (Equal(base, type))) { - if (newtype) - Delete(type); - Delete(base); - Delete(namebase); - Delete(nameprefix); - r = 0; - goto return_result; - } - - /* If the type is a template, and no typedef was found, we need to check the - template arguments one by one to see if they can be resolved. */ - - if (!type && SwigType_istemplate(base)) { - newtype = 1; - type = template_parameters_resolve(base); - } - Delete(namebase); - Delete(nameprefix); - } else { - if (SwigType_isfunction(base)) { - List *parms; - int i, sz; - int rep = 0; - type = NewString("f("); - newtype = 1; - parms = SwigType_parmlist(base); - sz = Len(parms); - for (i = 0; i < sz; i++) { - SwigType *tpr; - SwigType *tp = Getitem(parms, i); - if (!rep) { - tpr = SwigType_typedef_resolve(tp); - } else { - tpr = 0; - } - if (tpr) { - Append(type, tpr); - Delete(tpr); - rep = 1; - } else { - Append(type, tp); - } - if ((i + 1) < sz) - Append(type, ","); - } - Append(type, ")."); - Delete(parms); - if (!rep) { - Delete(type); - type = 0; - } - } else if (SwigType_ismemberpointer(base)) { - String *rt; - String *mtype = SwigType_parm(base); - rt = SwigType_typedef_resolve(mtype); - if (rt) { - type = NewStringf("m(%s).", rt); - newtype = 1; - Delete(rt); - } - Delete(mtype); - } else { - type = 0; - } - } - r = SwigType_prefix(t); - if (!type) { - if (r && Len(r)) { - char *cr = Char(r); - if ((strstr(cr, "f(") || (strstr(cr, "m(")))) { - SwigType *rt = SwigType_typedef_resolve(r); - if (rt) { - Delete(r); - Append(rt, base); - Delete(base); - r = rt; - goto return_result; - } - } - } - Delete(r); - Delete(base); - r = 0; - goto return_result; - } - Delete(base); - - /* If 'type' is an array, then the right-most qualifier in 'r' should - be added to 'type' after the array qualifier, so that given - a(7).q(volatile).double myarray // typedef volatile double[7] myarray; - the type - q(const).myarray // const myarray - becomes - a(7).q(const volatile).double // const volatile double[7] - and NOT - q(const).a(7).q(volatile).double // non-sensical type - */ - if (r && Len(r) && SwigType_isarray(type)) { - List *r_elem; - String *r_qual; - int r_sz; - r_elem = SwigType_split(r); - r_sz = Len(r_elem); - r_qual = Getitem(r_elem, r_sz-1); - if (SwigType_isqualifier(r_qual)) { - String *new_r; - String *new_type; - List *type_elem; - String *type_qual; - String *r_qual_arg; - int i, type_sz; - - type_elem = SwigType_split(type); - type_sz = Len(type_elem); - - for (i = 0; i < type_sz; ++i) { - String *e = Getitem(type_elem, i); - if (!SwigType_isarray(e)) - break; - } - type_qual = Copy(Getitem(type_elem, i)); - r_qual_arg = SwigType_parm(r_qual); - SwigType_add_qualifier(type_qual, r_qual_arg); - Delete(r_qual_arg); - Setitem(type_elem, i, type_qual); - - new_r = NewStringEmpty(); - for (i = 0; i < r_sz-1; ++i) { - Append(new_r, Getitem(r_elem, i)); - } - new_type = NewStringEmpty(); - for (i = 0; i < type_sz; ++i) { - Append(new_type, Getitem(type_elem, i)); - } -#ifdef SWIG_DEBUG - Printf(stdout, "r+type='%s%s' new_r+new_type='%s%s'\n", r, type, new_r, new_type); -#endif - - Delete(r); - r = new_r; - newtype = 1; - type = new_type; - Delete(type_elem); - } - Delete(r_elem); - } - - Append(r, type); - if (newtype) { - Delete(type); - } - -return_result: -#ifdef SWIG_TYPEDEF_RESOLVE_CACHE - { - String *key = NewString(t); - if (r) { - SwigType *r1; - Setattr(typedef_resolve_cache, key, r); - Setmeta(r, "scope", resolved_scope); - r1 = Copy(r); - Delete(r); - r = r1; - } - Delete(key); - } -#endif - return r; -} - -/* ----------------------------------------------------------------------------- - * SwigType_typedef_resolve_all() - * - * Fully resolve a type down to its most basic datatype - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_typedef_resolve_all(const SwigType *t) { - SwigType *n; - SwigType *r; - int count = 0; - - /* Check to see if the typedef resolve has been done before by checking the cache */ - if (!typedef_all_cache) { - typedef_all_cache = NewHash(); - } - r = Getattr(typedef_all_cache, t); - if (r) { - return Copy(r); - } - -#ifdef SWIG_DEBUG - Printf(stdout, "SwigType_typedef_resolve_all start ... %s\n", t); -#endif - /* Recursively resolve the typedef */ - r = NewString(t); - while ((n = SwigType_typedef_resolve(r))) { - Delete(r); - r = n; - if (++count >= 512) { - Swig_error(Getfile(t), Getline(t), "Recursive typedef detected resolving '%s' to '%s' to '%s' and so on...\n", SwigType_str(t, 0), SwigType_str(SwigType_typedef_resolve(t), 0), SwigType_str(SwigType_typedef_resolve(SwigType_typedef_resolve(t)), 0)); - break; - } - } - - /* Add the typedef to the cache for next time it is looked up */ - { - String *key; - SwigType *rr = Copy(r); - key = NewString(t); - Setattr(typedef_all_cache, key, rr); - Delete(key); - Delete(rr); - } -#ifdef SWIG_DEBUG - Printf(stdout, "SwigType_typedef_resolve_all end === %s => %s\n", t, r); -#endif - return r; -} - - -/* ----------------------------------------------------------------------------- - * SwigType_typedef_qualified() - * - * Given a type declaration, this function tries to fully qualify it so that the - * resulting type can be used in the global scope. The type name is resolved in - * the current scope. - * - * It provides a fully qualified name, not necessarily a fully expanded name. - * When a using declaration or using directive is found the type may not be fully - * expanded, but it will be resolved and fully qualified for use in the global scope. - * - * This function is for looking up scopes to qualify a type. It does not resolve - * C typedefs, it just qualifies them. See SwigType_typedef_resolve for resolving. - * - * If the unary scope operator (::) is used as a prefix to the type to denote global - * scope, it is left in place. - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_typedef_qualified(const SwigType *t) { - List *elements; - String *result; - int i, len; - - if (!typedef_qualified_cache) - typedef_qualified_cache = NewHash(); - result = Getattr(typedef_qualified_cache, t); - if (result) { - String *rc = Copy(result); - return rc; - } - - result = NewStringEmpty(); - elements = SwigType_split(t); - len = Len(elements); - for (i = 0; i < len; i++) { - String *ty = 0; - String *e = Getitem(elements, i); - if (SwigType_issimple(e)) { - if (!SwigType_istemplate(e)) { - String *isenum = 0; - if (SwigType_isenum(e)) { - isenum = NewString("enum "); - ty = NewString(Char(e) + 5); - e = ty; - } - resolved_scope = 0; - if (typedef_resolve(current_scope, e) && resolved_scope) { - /* resolved_scope contains the scope that actually resolved the symbol */ - String *qname = Getattr(resolved_scope, "qname"); - if (qname) { - Insert(e, 0, "::"); - Insert(e, 0, qname); - } - } else { - if (Swig_scopename_check(e)) { - String *qlast; - String *qname; - Swig_scopename_split(e, &qname, &qlast); - if (qname) { - String *tqname = SwigType_typedef_qualified(qname); - Clear(e); - Printf(e, "%s::%s", tqname, qlast); - Delete(qname); - Delete(tqname); - } - Delete(qlast); - - /* Automatic template instantiation might go here??? */ - } else { - /* It's a bare name. It's entirely possible, that the - name is part of a namespace. We'll check this by unrolling - out of the current scope */ - - Typetab *cs = current_scope; - if (cs) { - Typetab *found_scope = SwigType_find_scope(cs, e); - if (found_scope) { - String *qs = SwigType_scope_name(found_scope); - Clear(e); - Append(e, qs); - Delete(qs); - } - } - } - } - if (isenum) { - Insert(e, 0, isenum); - Delete(isenum); - } - } else { - /* Template. We need to qualify template parameters as well as the template itself */ - String *tprefix, *qprefix; - String *tsuffix; - Iterator pi; - Parm *p; - List *parms; - ty = Swig_symbol_template_deftype(e, current_symtab); - e = ty; - parms = SwigType_parmlist(e); - tprefix = SwigType_templateprefix(e); - tsuffix = SwigType_templatesuffix(e); - qprefix = SwigType_typedef_qualified(tprefix); - Append(qprefix, "<("); - pi = First(parms); - while ((p = pi.item)) { - /* TODO: the logic here should be synchronised with that in symbol_template_qualify() in symbol.c */ - String *qt = SwigType_typedef_qualified(p); - if (Equal(qt, p)) { /* && (!Swig_scopename_check(qt))) */ - /* No change in value. It is entirely possible that the parameter is an integer value. - If there is a symbol table associated with this scope, we're going to check for this */ - - if (current_symtab) { - Node *lastnode = 0; - String *value = Copy(p); - while (1) { - Node *n = Swig_symbol_clookup(value, current_symtab); - if (n == lastnode) - break; - lastnode = n; - if (n) { - char *ntype = Char(nodeType(n)); - if (strcmp(ntype, "enumitem") == 0) { - /* An enum item. Generate a fully qualified name */ - String *qn = Swig_symbol_qualified(n); - if (Len(qn)) { - Append(qn, "::"); - Append(qn, Getattr(n, "name")); - Delete(value); - value = qn; - continue; - } else { - Delete(qn); - break; - } - } else if ((strcmp(ntype, "cdecl") == 0) && (Getattr(n, "value"))) { - Delete(value); - value = Copy(Getattr(n, "value")); - continue; - } - } - break; - } - Append(qprefix, value); - Delete(value); - } else { - Append(qprefix, p); - } - } else { - Append(qprefix, qt); - } - Delete(qt); - pi = Next(pi); - if (pi.item) { - Append(qprefix, ","); - } - } - Append(qprefix, ")>"); - Append(qprefix, tsuffix); - Delete(tsuffix); - Clear(e); - Append(e, qprefix); - Delete(tprefix); - Delete(qprefix); - Delete(parms); - } - Append(result, e); - Delete(ty); - } else if (SwigType_isfunction(e)) { - List *parms = SwigType_parmlist(e); - String *s = NewString("f("); - Iterator pi; - pi = First(parms); - while (pi.item) { - String *pq = SwigType_typedef_qualified(pi.item); - Append(s, pq); - Delete(pq); - pi = Next(pi); - if (pi.item) { - Append(s, ","); - } - } - Append(s, ")."); - Append(result, s); - Delete(s); - Delete(parms); - } else if (SwigType_isarray(e)) { - String *ndim; - String *dim = SwigType_parm(e); - ndim = Swig_symbol_string_qualify(dim, 0); - Printf(result, "a(%s).", ndim); - Delete(dim); - Delete(ndim); - } else { - Append(result, e); - } - } - Delete(elements); - { - String *key, *cresult; - key = NewString(t); - cresult = NewString(result); - Setattr(typedef_qualified_cache, key, cresult); - Delete(key); - Delete(cresult); - } - return result; -} - -/* ----------------------------------------------------------------------------- - * SwigType_istypedef() - * - * Checks a typename to see if it is a typedef. - * ----------------------------------------------------------------------------- */ - -int SwigType_istypedef(const SwigType *t) { - String *type; - - type = SwigType_typedef_resolve(t); - if (type) { - Delete(type); - return 1; - } else { - return 0; - } -} - - -/* ----------------------------------------------------------------------------- - * SwigType_typedef_using() - * - * Processes a 'using' declaration to import types from one scope into another. - * Name is a qualified name like A::B. - * ----------------------------------------------------------------------------- */ - -int SwigType_typedef_using(const_String_or_char_ptr name) { - String *base; - String *td; - String *prefix; - Typetab *s; - Typetab *tt = 0; - - String *defined_name = 0; - - /* Printf(stdout, "using %s\n", name); */ - - if (!Swig_scopename_check(name)) - return -1; /* Not properly qualified */ - base = Swig_scopename_last(name); - - /* See if the base is already defined in this scope */ - if (Getattr(current_typetab, base)) { - Delete(base); - return -1; - } - - /* See if the using name is a scope */ - /* tt = SwigType_find_scope(current_scope,name); - Printf(stdout,"tt = %p, name = '%s'\n", tt, name); */ - - /* We set up a typedef B --> A::B */ - Setattr(current_typetab, base, name); - - /* Find the scope name where the symbol is defined */ - td = SwigType_typedef_resolve(name); - /* Printf(stdout,"td = '%s' %p\n", td, resolved_scope); */ - if (resolved_scope) { - defined_name = Getattr(resolved_scope, "qname"); - if (defined_name) { - defined_name = Copy(defined_name); - Append(defined_name, "::"); - Append(defined_name, base); - /* Printf(stdout,"defined_name = '%s'\n", defined_name); */ - tt = SwigType_find_scope(current_scope, defined_name); - } - } - if (td) - Delete(td); - - - /* Figure out the scope the using directive refers to */ - { - prefix = Swig_scopename_prefix(name); - if (prefix) { - s = SwigType_find_scope(current_scope, prefix); - if (s) { - Hash *ttab = Getattr(s, "typetab"); - if (!Getattr(ttab, base) && defined_name) { - Setattr(ttab, base, defined_name); - } - } - } - } - - if (tt) { - /* Using directive had its own scope. We need to create a new scope for it */ - SwigType_new_scope(base); - SwigType_inherit_scope(tt); - SwigType_pop_scope(); - } - - if (defined_name) - Delete(defined_name); - Delete(prefix); - Delete(base); - return 0; -} - -/* ----------------------------------------------------------------------------- - * SwigType_isclass() - * - * Determines if a type defines a class or not. A class is defined by - * its type-table entry maps to itself. Note: a pointer to a class is not - * a class. - * ----------------------------------------------------------------------------- */ - -int SwigType_isclass(const SwigType *t) { - SwigType *qty, *qtys; - int isclass = 0; - - qty = SwigType_typedef_resolve_all(t); - qtys = SwigType_strip_qualifiers(qty); - if (SwigType_issimple(qtys)) { - String *td = SwigType_typedef_resolve(qtys); - if (td) { - Delete(td); - } - if (resolved_scope) { - isclass = 1; - } - /* Hmmm. Not a class. If a template, it might be uninstantiated */ - if (!isclass) { - String *tp = SwigType_istemplate_templateprefix(qtys); - if (tp && Strcmp(tp, t) != 0) { - isclass = SwigType_isclass(tp); - } - Delete(tp); - } - } - Delete(qty); - Delete(qtys); - return isclass; -} - -/* ----------------------------------------------------------------------------- - * SwigType_type() - * - * Returns an integer code describing the datatype. This is only used for - * compatibility with SWIG1.1 language modules and is likely to go away once - * everything is based on typemaps. - * ----------------------------------------------------------------------------- */ - -int SwigType_type(const SwigType *t) { - char *c; - /* Check for the obvious stuff */ - c = Char(t); - - if (strncmp(c, "p.", 2) == 0) { - if (SwigType_type(c + 2) == T_CHAR) - return T_STRING; - else if (SwigType_type(c + 2) == T_WCHAR) - return T_WSTRING; - else - return T_POINTER; - } - if (strncmp(c, "a(", 2) == 0) - return T_ARRAY; - if (strncmp(c, "r.", 2) == 0) - return T_REFERENCE; - if (strncmp(c, "z.", 2) == 0) - return T_RVALUE_REFERENCE; - if (strncmp(c, "m(", 2) == 0) - return T_MPOINTER; - if (strncmp(c, "q(", 2) == 0) { - while (*c && (*c != '.')) - c++; - if (*c) - return SwigType_type(c + 1); - return T_ERROR; - } - if (strncmp(c, "f(", 2) == 0) - return T_FUNCTION; - - /* Look for basic types */ - if (strcmp(c, "int") == 0) - return T_INT; - if (strcmp(c, "long") == 0) - return T_LONG; - if (strcmp(c, "short") == 0) - return T_SHORT; - if (strcmp(c, "unsigned") == 0) - return T_UINT; - if (strcmp(c, "unsigned short") == 0) - return T_USHORT; - if (strcmp(c, "unsigned long") == 0) - return T_ULONG; - if (strcmp(c, "unsigned int") == 0) - return T_UINT; - if (strcmp(c, "char") == 0) - return T_CHAR; - if (strcmp(c, "signed char") == 0) - return T_SCHAR; - if (strcmp(c, "unsigned char") == 0) - return T_UCHAR; - if (strcmp(c, "wchar_t") == 0) - return T_WCHAR; - if (strcmp(c, "float") == 0) - return T_FLOAT; - if (strcmp(c, "double") == 0) - return T_DOUBLE; - if (strcmp(c, "long double") == 0) - return T_LONGDOUBLE; - if (!cparse_cplusplus && (strcmp(c, "float _Complex") == 0)) - return T_FLTCPLX; - if (!cparse_cplusplus && (strcmp(c, "double _Complex") == 0)) - return T_DBLCPLX; - if (!cparse_cplusplus && (strcmp(c, "_Complex") == 0)) - return T_COMPLEX; - if (strcmp(c, "void") == 0) - return T_VOID; - if (strcmp(c, "bool") == 0) - return T_BOOL; - if (strcmp(c, "long long") == 0) - return T_LONGLONG; - if (strcmp(c, "unsigned long long") == 0) - return T_ULONGLONG; - if (strncmp(c, "enum ", 5) == 0) - return T_INT; - if (strcmp(c, "auto") == 0) - return T_AUTO; - - if (strcmp(c, "v(...)") == 0) - return T_VARARGS; - /* Hmmm. Unknown type */ - if (SwigType_istypedef(t)) { - int r; - SwigType *nt = SwigType_typedef_resolve(t); - r = SwigType_type(nt); - Delete(nt); - return r; - } - return T_USER; -} - -/* ----------------------------------------------------------------------------- - * SwigType_alttype() - * - * Returns the alternative value type needed in C++ for class value - * types. When swig is not sure about using a plain $ltype value, - * since the class doesn't have a default constructor, or it can't be - * assigned, you will get back 'SwigValueWrapper<type >'. - * - * This is the default behavior unless: - * - * 1.- swig detects a default_constructor and 'setallocate:default_constructor' - * attribute. - * - * 2.- swig doesn't mark 'type' as non-assignable. - * - * 3.- the user specifies that the value wrapper is not needed by using - * %feature("novaluewrapper") like so: - * - * %feature("novaluewrapper") MyOpaqueClass; - * class MyOpaqueClass; - * - * The user can also force the use of the value wrapper with - * %feature("valuewrapper"). - * ----------------------------------------------------------------------------- */ - -SwigType *SwigType_alttype(const SwigType *t, int local_tmap) { - Node *n; - SwigType *w = 0; - int use_wrapper = 0; - SwigType *td = 0; - - if (!cparse_cplusplus) - return 0; - - if (value_wrapper_mode == 0) { - /* old partial use of SwigValueTypes, it can fail for opaque types */ - if (local_tmap) - return 0; - if (SwigType_isclass(t)) { - SwigType *ftd = SwigType_typedef_resolve_all(t); - td = SwigType_strip_qualifiers(ftd); - Delete(ftd); - n = Swig_symbol_clookup(td, 0); - if (n) { - if (GetFlag(n, "feature:valuewrapper")) { - use_wrapper = 1; - } else { - if (Checkattr(n, "nodeType", "class") - && (!Getattr(n, "allocate:default_constructor") - || (Getattr(n, "allocate:noassign")))) { - use_wrapper = !GetFlag(n, "feature:novaluewrapper") || GetFlag(n, "feature:nodefault"); - } - } - } else { - if (SwigType_issimple(td) && SwigType_istemplate(td)) { - use_wrapper = 1; - } - } - } - } else { - /* safe use of SwigValueTypes, it can fail with some typemaps */ - SwigType *ftd = SwigType_typedef_resolve_all(t); - td = SwigType_strip_qualifiers(ftd); - Delete(ftd); - if (SwigType_type(td) == T_USER) { - use_wrapper = 1; - n = Swig_symbol_clookup(td, 0); - if (n) { - if ((Checkattr(n, "nodeType", "class") - && !Getattr(n, "allocate:noassign") - && (Getattr(n, "allocate:default_constructor"))) - || (GetFlag(n, "feature:novaluewrapper"))) { - use_wrapper = GetFlag(n, "feature:valuewrapper"); - } - } - } - } - - if (use_wrapper) { - /* Need a space before the type in case it starts "::" (since the <: - * token is a digraph for [ in C++. Also need a space after the - * type in case it ends with ">" since then we form the token ">>". - */ - w = NewStringf("SwigValueWrapper< %s >", td); - } - Delete(td); - return w; -} - -/* ---------------------------------------------------------------------------- - * * * * WARNING * * * *** - * *** - * Don't even think about modifying anything below this line unless you *** - * are completely on top of *EVERY* subtle aspect of the C++ type system *** - * and you are prepared to suffer endless hours of agony trying to *** - * debug the SWIG run-time type checker after you break it. *** - * ------------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------------- - * SwigType_remember() - * - * This function "remembers" a datatype that was used during wrapper code generation - * so that a type-checking table can be generated later on. It is up to the language - * modules to actually call this function--it is not done automatically. - * - * Type tracking is managed through two separate hash tables. The hash 'r_mangled' - * is mapping between mangled type names (used in the target language) and - * fully-resolved C datatypes used in the source input. The second hash 'r_resolved' - * is the inverse mapping that maps fully-resolved C datatypes to all of the mangled - * names in the scripting languages. For example, consider the following set of - * typedef declarations: - * - * typedef double Real; - * typedef double Float; - * typedef double Point[3]; - * - * Now, suppose that the types 'double *', 'Real *', 'Float *', 'double[3]', and - * 'Point' were used in an interface file and "remembered" using this function. - * The hash tables would look like this: - * - * r_mangled { - * _p_double : [ p.double, a(3).double ] - * _p_Real : [ p.double ] - * _p_Float : [ p.double ] - * _Point : [ a(3).double ] - * - * r_resolved { - * p.double : [ _p_double, _p_Real, _p_Float ] - * a(3).double : [ _p_double, _Point ] - * } - * - * Together these two hash tables can be used to determine type-equivalency between - * mangled typenames. To do this, we view the two hash tables as a large graph and - * compute the transitive closure. - * ----------------------------------------------------------------------------- */ - -static Hash *r_mangled = 0; /* Hash mapping mangled types to fully resolved types */ -static Hash *r_resolved = 0; /* Hash mapping resolved types to mangled types */ -static Hash *r_ltype = 0; /* Hash mapping mangled names to their local c type */ -static Hash *r_clientdata = 0; /* Hash mapping resolved types to client data */ -static Hash *r_mangleddata = 0; /* Hash mapping mangled types to client data */ -static Hash *r_remembered = 0; /* Hash of types we remembered already */ - -static void (*r_tracefunc) (const SwigType *t, String *mangled, String *clientdata) = 0; - -void SwigType_remember_mangleddata(String *mangled, const_String_or_char_ptr clientdata) { - if (!r_mangleddata) { - r_mangleddata = NewHash(); - } - Setattr(r_mangleddata, mangled, clientdata); -} - - -void SwigType_remember_clientdata(const SwigType *t, const_String_or_char_ptr clientdata) { - String *mt; - SwigType *lt; - Hash *h; - SwigType *fr; - SwigType *qr; - String *tkey; - String *cd; - Hash *lthash; - - if (!r_mangled) { - r_mangled = NewHash(); - r_resolved = NewHash(); - r_ltype = NewHash(); - r_clientdata = NewHash(); - r_remembered = NewHash(); - } - - { - String *last; - last = Getattr(r_remembered, t); - if (last && (Cmp(last, clientdata) == 0)) - return; - } - - tkey = Copy(t); - cd = clientdata ? NewString(clientdata) : NewStringEmpty(); - Setattr(r_remembered, tkey, cd); - Delete(tkey); - Delete(cd); - - mt = SwigType_manglestr(t); /* Create mangled string */ - - if (r_tracefunc) { - (*r_tracefunc) (t, mt, (String *) clientdata); - } - - if (SwigType_istypedef(t)) { - lt = Copy(t); - } else { - lt = SwigType_ltype(t); - } - - lthash = Getattr(r_ltype, mt); - if (!lthash) { - lthash = NewHash(); - Setattr(r_ltype, mt, lthash); - } - Setattr(lthash, lt, "1"); - Delete(lt); - - fr = SwigType_typedef_resolve_all(t); /* Create fully resolved type */ - qr = SwigType_typedef_qualified(fr); - Delete(fr); - - /* Added to deal with possible table bug */ - fr = SwigType_strip_qualifiers(qr); - Delete(qr); - - /*Printf(stdout,"t = '%s'\n", t); - Printf(stdout,"fr= '%s'\n\n", fr); */ - - if (t) { - char *ct = Char(t); - const char *lt = strchr(ct, '<'); - /* Allow for `<<` operator in constant expression for array size. */ - if (lt && lt[1] != '(' && lt[1] != '<') { - Printf(stdout, "Bad template type passed to SwigType_remember: %s\n", t); - assert(0); - } - } - - h = Getattr(r_mangled, mt); - if (!h) { - h = NewHash(); - Setattr(r_mangled, mt, h); - Delete(h); - } - Setattr(h, fr, mt); - - h = Getattr(r_resolved, fr); - if (!h) { - h = NewHash(); - Setattr(r_resolved, fr, h); - Delete(h); - } - Setattr(h, mt, fr); - - if (clientdata) { - String *cd = Getattr(r_clientdata, fr); - if (cd) { - if (Strcmp(clientdata, cd) != 0) { - Printf(stderr, "*** Internal error. Inconsistent clientdata for type '%s'\n", SwigType_str(fr, 0)); - Printf(stderr, "*** '%s' != '%s'\n", clientdata, cd); - assert(0); - } - } else { - String *cstr = NewString(clientdata); - Setattr(r_clientdata, fr, cstr); - Delete(cstr); - } - } - - /* If the remembered type is a reference, we also remember the pointer version. - This is to prevent odd problems with mixing pointers and references--especially - when different functions are using different typenames (via typedef). */ - - if (SwigType_isreference(t)) { - SwigType *tt = Copy(t); - SwigType_del_reference(tt); - SwigType_add_pointer(tt); - SwigType_remember_clientdata(tt, clientdata); - } else if (SwigType_isrvalue_reference(t)) { - SwigType *tt = Copy(t); - SwigType_del_rvalue_reference(tt); - SwigType_add_pointer(tt); - SwigType_remember_clientdata(tt, clientdata); - } -} - -void SwigType_remember(const SwigType *ty) { - SwigType_remember_clientdata(ty, 0); -} - -void (*SwigType_remember_trace(void (*tf) (const SwigType *, String *, String *))) (const SwigType *, String *, String *) { - void (*o) (const SwigType *, String *, String *) = r_tracefunc; - r_tracefunc = tf; - return o; -} - -/* ----------------------------------------------------------------------------- - * SwigType_equivalent_mangle() - * - * Return a list of all of the mangled typenames that are equivalent to another - * mangled name. This works as follows: For each fully qualified C datatype - * in the r_mangled hash entry, we collect all of the mangled names from the - * r_resolved hash and combine them together in a list (removing duplicate entries). - * ----------------------------------------------------------------------------- */ - -List *SwigType_equivalent_mangle(String *ms, Hash *checked, Hash *found) { - List *l; - Hash *h; - Hash *ch; - Hash *mh; - - if (found) { - h = found; - } else { - h = NewHash(); - } - if (checked) { - ch = checked; - } else { - ch = NewHash(); - } - if (Getattr(ch, ms)) - goto check_exit; /* Already checked this type */ - Setattr(h, ms, "1"); - Setattr(ch, ms, "1"); - mh = Getattr(r_mangled, ms); - if (mh) { - Iterator ki; - ki = First(mh); - while (ki.key) { - Hash *rh; - if (Getattr(ch, ki.key)) { - ki = Next(ki); - continue; - } - Setattr(ch, ki.key, "1"); - rh = Getattr(r_resolved, ki.key); - if (rh) { - Iterator rk; - rk = First(rh); - while (rk.key) { - Setattr(h, rk.key, "1"); - SwigType_equivalent_mangle(rk.key, ch, h); - rk = Next(rk); - } - } - ki = Next(ki); - } - } -check_exit: - if (!found) { - l = Keys(h); - Delete(h); - Delete(ch); - return l; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * SwigType_clientdata_collect() - * - * Returns the clientdata field for a mangled type-string. - * ----------------------------------------------------------------------------- */ - -static -String *SwigType_clientdata_collect(String *ms) { - Hash *mh; - String *clientdata = 0; - - if (r_mangleddata) { - clientdata = Getattr(r_mangleddata, ms); - if (clientdata) - return clientdata; - } - - mh = Getattr(r_mangled, ms); - if (mh) { - Iterator ki; - ki = First(mh); - while (ki.key) { - clientdata = Getattr(r_clientdata, ki.key); - if (clientdata) - break; - ki = Next(ki); - } - } - return clientdata; -} - - - - -/* ----------------------------------------------------------------------------- - * SwigType_inherit() - * - * Record information about inheritance. We keep a hash table that keeps - * a mapping between base classes and all of the classes that are derived - * from them. - * - * subclass is a hash that maps base-classes to all of the classes derived from them. - * - * derived - name of derived class - * base - name of base class - * cast - additional casting code when casting from derived to base - * conversioncode - if set, overrides the default code in the function when casting - * from derived to base - * ----------------------------------------------------------------------------- */ - -static Hash *subclass = 0; -static Hash *conversions = 0; - -void SwigType_inherit(String *derived, String *base, String *cast, String *conversioncode) { - Hash *h; - String *dd = 0; - String *bb = 0; - if (!subclass) - subclass = NewHash(); - - /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */ - - if (SwigType_istemplate(derived)) { - String *ty = SwigType_typedef_resolve_all(derived); - dd = SwigType_typedef_qualified(ty); - derived = dd; - Delete(ty); - } - if (SwigType_istemplate(base)) { - String *ty = SwigType_typedef_resolve_all(base); - bb = SwigType_typedef_qualified(ty); - base = bb; - Delete(ty); - } - - /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */ - - h = Getattr(subclass, base); - if (!h) { - h = NewHash(); - Setattr(subclass, base, h); - Delete(h); - } - if (!Getattr(h, derived)) { - Hash *c = NewHash(); - if (cast) - Setattr(c, "cast", cast); - if (conversioncode) - Setattr(c, "convcode", conversioncode); - Setattr(h, derived, c); - Delete(c); - } - - Delete(dd); - Delete(bb); -} - -/* ----------------------------------------------------------------------------- - * SwigType_issubtype() - * - * Determines if a t1 is a subtype of t2, ie, is t1 derived from t2 - * ----------------------------------------------------------------------------- */ - -int SwigType_issubtype(const SwigType *t1, const SwigType *t2) { - SwigType *ft1, *ft2; - String *b1, *b2; - Hash *h; - int r = 0; - - if (!subclass) - return 0; - - ft1 = SwigType_typedef_resolve_all(t1); - ft2 = SwigType_typedef_resolve_all(t2); - b1 = SwigType_base(ft1); - b2 = SwigType_base(ft2); - - h = Getattr(subclass, b2); - if (h) { - if (Getattr(h, b1)) { - r = 1; - } - } - Delete(ft1); - Delete(ft2); - Delete(b1); - Delete(b2); - /* Printf(stdout, "issubtype(%s,%s) --> %d\n", t1, t2, r); */ - return r; -} - -/* ----------------------------------------------------------------------------- - * SwigType_inherit_equiv() - * - * Modify the type table to handle C++ inheritance - * ----------------------------------------------------------------------------- */ - -void SwigType_inherit_equiv(File *out) { - String *ckey; - String *prefix, *base; - String *mprefix, *mkey; - Hash *sub; - Hash *rh; - List *rlist; - List *r_resolved_sorted_keys; - Iterator rk, bk, ck; - - if (!conversions) - conversions = NewHash(); - if (!subclass) - subclass = NewHash(); - - r_resolved_sorted_keys = SortedKeys(r_resolved, Strcmp); - rk = First(r_resolved_sorted_keys); - while (rk.item) { - List *sub_sorted_keys; - /* rkey is a fully qualified type. We strip all of the type constructors off of it just to get the base */ - base = SwigType_base(rk.item); - /* Check to see whether the base is recorded in the subclass table */ - sub = Getattr(subclass, base); - Delete(base); - if (!sub) { - rk = Next(rk); - continue; - } - - /* This type has subclasses. We now need to walk through these subtypes and generate pointer conversion functions */ - - rh = Getattr(r_resolved, rk.item); - rlist = NewList(); - for (ck = First(rh); ck.key; ck = Next(ck)) { - Append(rlist, ck.key); - } - /* Printf(stdout,"rk.item = '%s'\n", rk.item); - Printf(stdout,"rh = %p '%s'\n", rh,rh); */ - - sub_sorted_keys = SortedKeys(sub, Strcmp); - bk = First(sub_sorted_keys); - while (bk.item) { - prefix = SwigType_prefix(rk.item); - Append(prefix, bk.item); - /* Printf(stdout,"set %p = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */ - mprefix = SwigType_manglestr(prefix); - Setattr(rh, mprefix, prefix); - mkey = SwigType_manglestr(rk.item); - ckey = NewStringf("%s+%s", mprefix, mkey); - if (!Getattr(conversions, ckey)) { - String *convname = NewStringf("%sTo%s", mprefix, mkey); - String *lkey = SwigType_lstr(rk.item, 0); - String *lprefix = SwigType_lstr(prefix, 0); - Hash *subhash = Getattr(sub, bk.item); - String *convcode = Getattr(subhash, "convcode"); - if (convcode) { - char *newmemoryused = Strstr(convcode, "newmemory"); /* see if newmemory parameter is used in order to avoid unused parameter warnings */ - String *fn = Copy(convcode); - Replaceall(fn, "$from", "x"); - Printf(out, "static void *%s(void *x, int *%s) {", convname, newmemoryused ? "newmemory" : "SWIGUNUSEDPARM(newmemory)"); - Printf(out, "%s", fn); - } else { - String *cast = Getattr(subhash, "cast"); - Printf(out, "static void *%s(void *x, int *SWIGUNUSEDPARM(newmemory)) {", convname); - Printf(out, "\n return (void *)((%s) ", lkey); - if (cast) - Printf(out, "%s", cast); - Printf(out, " ((%s) x));\n", lprefix); - } - Printf(out, "}\n"); - Setattr(conversions, ckey, convname); - Delete(ckey); - Delete(lkey); - Delete(lprefix); - - /* This inserts conversions for typedefs */ - { - Hash *r = Getattr(r_resolved, prefix); - if (r) { - Iterator rrk; - rrk = First(r); - while (rrk.key) { - Iterator rlk; - String *rkeymangle; - - /* Make sure this name equivalence is not due to inheritance */ - if (Cmp(prefix, Getattr(r, rrk.key)) == 0) { - rkeymangle = Copy(mkey); - ckey = NewStringf("%s+%s", rrk.key, rkeymangle); - if (!Getattr(conversions, ckey)) { - Setattr(conversions, ckey, convname); - } - Delete(ckey); - for (rlk = First(rlist); rlk.item; rlk = Next(rlk)) { - ckey = NewStringf("%s+%s", rrk.key, rlk.item); - Setattr(conversions, ckey, convname); - Delete(ckey); - } - Delete(rkeymangle); - /* This is needed to pick up other alternative names for the same type. - Needed to make templates work */ - Setattr(rh, rrk.key, rrk.item); - } - rrk = Next(rrk); - } - } - } - Delete(convname); - } - Delete(prefix); - Delete(mprefix); - Delete(mkey); - bk = Next(bk); - } - Delete(sub_sorted_keys); - rk = Next(rk); - Delete(rlist); - } - Delete(r_resolved_sorted_keys); -} - -/* ----------------------------------------------------------------------------- - * SwigType_type_table() - * - * Generate the type-table for the type-checker. - * ----------------------------------------------------------------------------- */ - -void SwigType_emit_type_table(File *f_forward, File *f_table) { - Iterator ki; - String *types, *table, *cast, *cast_init, *cast_temp; - Hash *imported_types; - List *mangled_list; - List *table_list = NewList(); - int i = 0; - - if (!r_mangled) { - r_mangled = NewHash(); - r_resolved = NewHash(); - } - - Printf(f_table, "\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */\n\n"); - - SwigType_inherit_equiv(f_table); - - /*#define DEBUG 1*/ -#ifdef DEBUG - Printf(stdout, "---r_mangled---\n"); - Swig_print(r_mangled, 2); - - Printf(stdout, "---r_resolved---\n"); - Swig_print(r_resolved, 2); - - Printf(stdout, "---r_ltype---\n"); - Swig_print(r_ltype, 2); - - Printf(stdout, "---subclass---\n"); - Swig_print(subclass, 2); - - Printf(stdout, "---conversions---\n"); - Swig_print(conversions, 2); - - Printf(stdout, "---r_clientdata---\n"); - Swig_print(r_clientdata, 2); - -#endif - table = NewStringEmpty(); - types = NewStringEmpty(); - cast = NewStringEmpty(); - cast_init = NewStringEmpty(); - imported_types = NewHash(); - - Printf(table, "static swig_type_info *swig_type_initial[] = {\n"); - Printf(cast_init, "static swig_cast_info *swig_cast_initial[] = {\n"); - - Printf(f_forward, "\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n"); - - mangled_list = SortedKeys(r_mangled, Strcmp); - for (ki = First(mangled_list); ki.item; ki = Next(ki)) { - List *el; - Iterator ei; - String *nt; - String *ln; - String *rn; - const String *cd; - Hash *lthash; - Iterator ltiter; - Hash *nthash; - String *cast_temp_conv; - String *resolved_lstr = 0; - List *ntlist; - - cast_temp = NewStringEmpty(); - cast_temp_conv = NewStringEmpty(); - - Printv(types, "static swig_type_info _swigt_", ki.item, " = {", NIL); - Append(table_list, ki.item); - Printf(cast_temp, "static swig_cast_info _swigc_%s[] = {", ki.item); - i++; - - cd = SwigType_clientdata_collect(ki.item); - if (!cd) - cd = "0"; - - lthash = Getattr(r_ltype, ki.item); - nt = 0; - nthash = NewHash(); - ltiter = First(lthash); - while (ltiter.key) { - SwigType *lt = ltiter.key; - SwigType *rt = SwigType_typedef_resolve_all(lt); - /* we save the original type and the fully resolved version */ - ln = SwigType_lstr(lt, 0); - rn = SwigType_lstr(rt, 0); - if (Equal(ln, rn)) { - Setattr(nthash, ln, "1"); - } else { - Setattr(nthash, rn, "1"); - Setattr(nthash, ln, "1"); - } - if (!resolved_lstr) { - resolved_lstr = Copy(rn); - } else if (Len(rn) < Len(resolved_lstr)) { - Delete(resolved_lstr); - resolved_lstr = Copy(rn); - } - if (SwigType_istemplate(rt)) { - String *dt = Swig_symbol_template_deftype(rt, 0); - String *dn = SwigType_lstr(dt, 0); - if (!Equal(dn, rn) && !Equal(dn, ln)) { - Setattr(nthash, dn, "1"); - } - Delete(dt); - Delete(dn); - } - Delete(rt); - Delete(rn); - Delete(ln); - - ltiter = Next(ltiter); - } - - /* now build nt */ - ntlist = SortedKeys(nthash, Strcmp); - ltiter = First(ntlist); - nt = 0; - while (ltiter.item) { - if (!Equal(resolved_lstr, ltiter.item)) { - if (nt) { - Printf(nt, "|%s", ltiter.item); - } else { - nt = NewString(ltiter.item); - } - } - ltiter = Next(ltiter); - } - /* Last in list is a resolved type used by SWIG_TypePrettyName. - * There can be more than one resolved type and the chosen one is simply the - * shortest in length, arguably the most user friendly/readable. */ - if (nt) { - Printf(nt, "|%s", resolved_lstr); - } else { - nt = NewString(resolved_lstr); - } - Delete(ntlist); - Delete(nthash); - Delete(resolved_lstr); - - Printf(types, "\"%s\", \"%s\", 0, 0, (void*)%s, 0};\n", ki.item, nt, cd); - - el = SwigType_equivalent_mangle(ki.item, 0, 0); - SortList(el, Strcmp); - for (ei = First(el); ei.item; ei = Next(ei)) { - String *ckey; - String *conv; - ckey = NewStringf("%s+%s", ei.item, ki.item); - conv = Getattr(conversions, ckey); - if (conv) { - Printf(cast_temp_conv, " {&_swigt_%s, %s, 0, 0},", ei.item, conv); - } else { - Printf(cast_temp, " {&_swigt_%s, 0, 0, 0},", ei.item); - } - Delete(ckey); - - if (!Getattr(r_mangled, ei.item) && !Getattr(imported_types, ei.item)) { - Printf(types, "static swig_type_info _swigt_%s = {\"%s\", 0, 0, 0, 0, 0};\n", ei.item, ei.item); - Append(table_list, ei.item); - - Printf(cast, "static swig_cast_info _swigc_%s[] = {{&_swigt_%s, 0, 0, 0},{0, 0, 0, 0}};\n", ei.item, ei.item); - i++; - - Setattr(imported_types, ei.item, "1"); - } - } - Delete(el); - Printf(cast, "%s%s{0, 0, 0, 0}};\n", cast_temp, cast_temp_conv); - Delete(cast_temp_conv); - Delete(cast_temp); - Delete(nt); - } - /* print the tables in the proper order */ - SortList(table_list, Strcmp); - i = 0; - for (ki = First(table_list); ki.item; ki = Next(ki)) { - Printf(f_forward, "#define SWIGTYPE%s swig_types[%d]\n", ki.item, i++); - Printf(table, " &_swigt_%s,\n", ki.item); - Printf(cast_init, " _swigc_%s,\n", ki.item); - } - if (i == 0) { - /* empty arrays are not allowed by ISO C */ - Printf(table, " NULL\n"); - Printf(cast_init, " NULL\n"); - } - - Delete(table_list); - - Delete(mangled_list); - - Printf(table, "};\n"); - Printf(cast_init, "};\n"); - Printf(f_table, "%s\n", types); - Printf(f_table, "%s\n", table); - Printf(f_table, "%s\n", cast); - Printf(f_table, "%s\n", cast_init); - Printf(f_table, "\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */\n\n"); - - Printf(f_forward, "static swig_type_info *swig_types[%d];\n", i + 1); - Printf(f_forward, "static swig_module_info swig_module = {swig_types, %d, 0, 0, 0, 0};\n", i); - Printf(f_forward, "#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)\n"); - Printf(f_forward, "#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)\n"); - Printf(f_forward, "\n/* -------- TYPES TABLE (END) -------- */\n\n"); - - Delete(types); - Delete(table); - Delete(cast); - Delete(cast_init); - Delete(imported_types); -} diff --git a/contrib/tools/swig/Source/Swig/wrapfunc.c b/contrib/tools/swig/Source/Swig/wrapfunc.c deleted file mode 100644 index 6d823724538..00000000000 --- a/contrib/tools/swig/Source/Swig/wrapfunc.c +++ /dev/null @@ -1,520 +0,0 @@ -/* ----------------------------------------------------------------------------- - * This file is part of SWIG, which is licensed as a whole under version 3 - * (or any later version) of the GNU General Public License. Some additional - * terms also apply to certain portions of SWIG. The full details of the SWIG - * license and copyrights can be found in the LICENSE and COPYRIGHT files - * included with the SWIG source code as distributed by the SWIG developers - * and at https://www.swig.org/legal.html. - * - * wrapfunc.c - * - * This file defines a object for creating wrapper functions. Primarily - * this is used for convenience since it allows pieces of a wrapper function - * to be created in a piecemeal manner. - * ----------------------------------------------------------------------------- */ - -#include "swig.h" -#include <ctype.h> - -static int Compact_mode = 0; /* set to 0 on default */ -static int Max_line_size = 128; - -/* ----------------------------------------------------------------------------- - * NewWrapper() - * - * Create a new wrapper function object. - * ----------------------------------------------------------------------------- */ - -Wrapper *NewWrapper(void) { - Wrapper *w; - w = (Wrapper *) Malloc(sizeof(Wrapper)); - w->localh = NewHash(); - w->locals = NewStringEmpty(); - w->code = NewStringEmpty(); - w->def = NewStringEmpty(); - return w; -} - -/* ----------------------------------------------------------------------------- - * DelWrapper() - * - * Delete a wrapper function object. - * ----------------------------------------------------------------------------- */ - -void DelWrapper(Wrapper *w) { - Delete(w->localh); - Delete(w->locals); - Delete(w->code); - Delete(w->def); - Free(w); -} - -/* ----------------------------------------------------------------------------- - * Wrapper_compact_print_mode_set() - * - * Set compact_mode. - * ----------------------------------------------------------------------------- */ - -void Wrapper_compact_print_mode_set(int flag) { - Compact_mode = flag; -} - -/* ----------------------------------------------------------------------------- - * Wrapper_pretty_print() - * - * Formats a wrapper function and fixes up the indentation. - * ----------------------------------------------------------------------------- */ - -void Wrapper_pretty_print(String *str, File *f) { - String *ts; - int level = 0; - int c, i; - int empty = 1; - int indent = 2; - int plevel = 0; - int label = 0; - - ts = NewStringEmpty(); - Seek(str, 0, SEEK_SET); - while ((c = Getc(str)) != EOF) { - if (c == '\"') { - Putc(c, ts); - while ((c = Getc(str)) != EOF) { - if (c == '\\') { - Putc(c, ts); - c = Getc(str); - } - Putc(c, ts); - if (c == '\"') - break; - } - empty = 0; - } else if (c == '\'') { - Putc(c, ts); - while ((c = Getc(str)) != EOF) { - if (c == '\\') { - Putc(c, ts); - c = Getc(str); - } - Putc(c, ts); - if (c == '\'') - break; - } - empty = 0; - } else if (c == ':') { - Putc(c, ts); - if ((c = Getc(str)) == '\n') { - if (!empty && !strchr(Char(ts), '?')) - label = 1; - } - Ungetc(c, str); - } else if (c == '(') { - Putc(c, ts); - plevel += indent; - empty = 0; - } else if (c == ')') { - Putc(c, ts); - plevel -= indent; - empty = 0; - } else if (c == '{') { - Putc(c, ts); - Putc('\n', ts); - for (i = 0; i < level; i++) - Putc(' ', f); - Printf(f, "%s", ts); - Clear(ts); - level += indent; - while ((c = Getc(str)) != EOF) { - if (!isspace(c)) { - Ungetc(c, str); - break; - } - } - empty = 0; - } else if (c == '}') { - if (!empty) { - Putc('\n', ts); - for (i = 0; i < level; i++) - Putc(' ', f); - Printf(f, "%s", ts); - Clear(ts); - } - level -= indent; - Putc(c, ts); - empty = 0; - } else if (c == '\n') { - Putc(c, ts); - empty = 0; - if (!empty) { - int slevel = level; - if (label && (slevel >= indent)) - slevel -= indent; - if ((Char(ts))[0] != '#') { - for (i = 0; i < slevel; i++) - Putc(' ', f); - } - Printf(f, "%s", ts); - for (i = 0; i < plevel; i++) - Putc(' ', f); - } - Clear(ts); - label = 0; - empty = 1; - } else if (c == '/') { - empty = 0; - Putc(c, ts); - c = Getc(str); - if (c != EOF) { - Putc(c, ts); - if (c == '/') { /* C++ comment */ - while ((c = Getc(str)) != EOF) { - if (c == '\n') { - Ungetc(c, str); - break; - } - Putc(c, ts); - } - } else if (c == '*') { /* C comment */ - int endstar = 0; - while ((c = Getc(str)) != EOF) { - if (endstar && c == '/') { /* end of C comment */ - Putc(c, ts); - break; - } - endstar = (c == '*'); - Putc(c, ts); - if (c == '\n') { /* multi-line C comment. Could be improved slightly. */ - for (i = 0; i < level; i++) - Putc(' ', ts); - } - } - } - } - } else { - if (!empty || !isspace(c)) { - Putc(c, ts); - empty = 0; - } - } - } - if (!empty) - Printf(f, "%s", ts); - Delete(ts); - Printf(f, "\n"); -} - -/* ----------------------------------------------------------------------------- - * Wrapper_compact_print() - * - * Formats a wrapper function and fixes up the indentation. - * Print out in compact format, with Compact enabled. - * ----------------------------------------------------------------------------- */ - -void Wrapper_compact_print(String *str, File *f) { - String *ts, *tf; /*temp string & temp file */ - int level = 0; - int c, i; - int empty = 1; - int indent = 2; - - ts = NewStringEmpty(); - tf = NewStringEmpty(); - Seek(str, 0, SEEK_SET); - - while ((c = Getc(str)) != EOF) { - if (c == '\"') { /* string 1 */ - empty = 0; - Putc(c, ts); - while ((c = Getc(str)) != EOF) { - if (c == '\\') { - Putc(c, ts); - c = Getc(str); - } - Putc(c, ts); - if (c == '\"') - break; - } - } else if (c == '\'') { /* string 2 */ - empty = 0; - Putc(c, ts); - while ((c = Getc(str)) != EOF) { - if (c == '\\') { - Putc(c, ts); - c = Getc(str); - } - Putc(c, ts); - if (c == '\'') - break; - } - } else if (c == '{') { /* start of {...} */ - empty = 0; - Putc(c, ts); - if (Len(tf) == 0) { - for (i = 0; i < level; i++) - Putc(' ', tf); - } else if ((Len(tf) + Len(ts)) < Max_line_size) { - Putc(' ', tf); - } else { - Putc('\n', tf); - Printf(f, "%s", tf); - Clear(tf); - for (i = 0; i < level; i++) - Putc(' ', tf); - } - Append(tf, ts); - Clear(ts); - level += indent; - while ((c = Getc(str)) != EOF) { - if (!isspace(c)) { - Ungetc(c, str); - break; - } - } - } else if (c == '}') { /* end of {...} */ - empty = 0; - if (Len(tf) == 0) { - for (i = 0; i < level; i++) - Putc(' ', tf); - } else if ((Len(tf) + Len(ts)) < Max_line_size) { - Putc(' ', tf); - } else { - Putc('\n', tf); - Printf(f, "%s", tf); - Clear(tf); - for (i = 0; i < level; i++) - Putc(' ', tf); - } - Append(tf, ts); - Putc(c, tf); - Clear(ts); - level -= indent; - } else if (c == '\n') { /* line end */ - while ((c = Getc(str)) != EOF) { - if (!isspace(c)) - break; - } - if (c == '#') { - Putc('\n', ts); - } else if (c == '}') { - Putc(' ', ts); - } else if ((c != EOF) || (Len(ts) != 0)) { - if (Len(tf) == 0) { - for (i = 0; i < level; i++) - Putc(' ', tf); - } else if ((Len(tf) + Len(ts)) < Max_line_size) { - Putc(' ', tf); - } else { - Putc('\n', tf); - Printf(f, "%s", tf); - Clear(tf); - for (i = 0; i < level; i++) - Putc(' ', tf); - } - Append(tf, ts); - Clear(ts); - } - Ungetc(c, str); - - empty = 1; - } else if (c == '/') { /* comment */ - empty = 0; - c = Getc(str); - if (c != EOF) { - if (c == '/') { /* C++ comment */ - while ((c = Getc(str)) != EOF) { - if (c == '\n') { - Ungetc(c, str); - break; - } - } - } else if (c == '*') { /* C comment */ - int endstar = 0; - while ((c = Getc(str)) != EOF) { - if (endstar && c == '/') { /* end of C comment */ - break; - } - endstar = (c == '*'); - } - } else { - Putc('/', ts); - Putc(c, ts); - } - } - } else if (c == '#') { /* Preprocessor line */ - Putc('#', ts); - while ((c = Getc(str)) != EOF) { - Putc(c, ts); - if (c == '\\') { /* Continued line of the same PP */ - c = Getc(str); - if (c == '\n') - Putc(c, ts); - else - Ungetc(c, str); - } else if (c == '\n') - break; - } - if (!empty) { - Append(tf, "\n"); - } - Append(tf, ts); - Printf(f, "%s", tf); - Clear(tf); - Clear(ts); - for (i = 0; i < level; i++) - Putc(' ', tf); - empty = 1; - } else { - if (!empty || !isspace(c)) { - Putc(c, ts); - empty = 0; - } - } - } - if (!empty) { - Append(tf, ts); - } - if (Len(tf) != 0) - Printf(f, "%s", tf); - Delete(ts); - Delete(tf); - Printf(f, "\n"); -} - -/* ----------------------------------------------------------------------------- - * Wrapper_print() - * - * Print out a wrapper function. Does pretty or compact printing as well. - * ----------------------------------------------------------------------------- */ - -void Wrapper_print(Wrapper *w, File *f) { - String *str; - - str = NewStringEmpty(); - Printf(str, "%s\n", w->def); - Printf(str, "%s\n", w->locals); - Printf(str, "%s\n", w->code); - if (Compact_mode == 1) - Wrapper_compact_print(str, f); - else - Wrapper_pretty_print(str, f); - - Delete(str); -} - -/* ----------------------------------------------------------------------------- - * Wrapper_add_local() - * - * Adds a new local variable declaration to a function. Returns -1 if already - * present (which may or may not be okay to the caller). - * ----------------------------------------------------------------------------- */ - -int Wrapper_add_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl) { - /* See if the local has already been declared */ - if (Getattr(w->localh, name)) { - return -1; - } - Setattr(w->localh, name, decl); - Printf(w->locals, "%s;\n", decl); - return 0; -} - -/* ----------------------------------------------------------------------------- - * Wrapper_add_localv() - * - * Same as add_local(), but allows a NULL terminated list of strings to be - * used as a replacement for decl. This saves the caller the trouble of having - * to manually construct the 'decl' string before calling. - * ----------------------------------------------------------------------------- */ - -int Wrapper_add_localv(Wrapper *w, const_String_or_char_ptr name, ...) { - va_list ap; - int ret; - String *decl; - DOH *obj; - decl = NewStringEmpty(); - va_start(ap, name); - - obj = va_arg(ap, void *); - while (obj) { - Append(decl, obj); - Putc(' ', decl); - obj = va_arg(ap, void *); - } - va_end(ap); - - ret = Wrapper_add_local(w, name, decl); - Delete(decl); - return ret; -} - -/* ----------------------------------------------------------------------------- - * Wrapper_check_local() - * - * Check to see if a local name has already been declared - * ----------------------------------------------------------------------------- */ - -int Wrapper_check_local(Wrapper *w, const_String_or_char_ptr name) { - if (Getattr(w->localh, name)) { - return 1; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * Wrapper_new_local() - * - * Adds a new local variable with a guarantee that a unique local name will be - * used. Returns the name that was actually selected. - * ----------------------------------------------------------------------------- */ - -char *Wrapper_new_local(Wrapper *w, const_String_or_char_ptr name, const_String_or_char_ptr decl) { - int i; - String *nname = NewString(name); - String *ndecl = NewString(decl); - char *ret; - - i = 0; - - while (Wrapper_check_local(w, nname)) { - Clear(nname); - Printf(nname, "%s%d", name, i); - i++; - } - Replace(ndecl, name, nname, DOH_REPLACE_ID); - Setattr(w->localh, nname, ndecl); - Printf(w->locals, "%s;\n", ndecl); - ret = Char(nname); - Delete(nname); - Delete(ndecl); - return ret; /* Note: nname should still exists in the w->localh hash */ -} - - -/* ----------------------------------------------------------------------------- - * Wrapper_new_localv() - * - * Same as add_local(), but allows a NULL terminated list of strings to be - * used as a replacement for decl. This saves the caller the trouble of having - * to manually construct the 'decl' string before calling. - * ----------------------------------------------------------------------------- */ - -char *Wrapper_new_localv(Wrapper *w, const_String_or_char_ptr name, ...) { - va_list ap; - char *ret; - String *decl; - DOH *obj; - decl = NewStringEmpty(); - va_start(ap, name); - - obj = va_arg(ap, void *); - while (obj) { - Append(decl, obj); - Putc(' ', decl); - obj = va_arg(ap, void *); - } - va_end(ap); - - ret = Wrapper_new_local(w, name, decl); - Delete(decl); - return ret; -} diff --git a/contrib/tools/swig/swig_lib.cpp b/contrib/tools/swig/swig_lib.cpp deleted file mode 100644 index 75b98501e88..00000000000 --- a/contrib/tools/swig/swig_lib.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define _STR(a) #a -#define STR(a) _STR(a) - -static const char* ArcadiaRoot() { - const char* root = getenv("ARCADIA_ROOT_DISTBUILD"); - return root ? root : STR(ARCADIA_ROOT); -} - -#ifdef _MSC_VER -static int setenv(const char* name, const char* value, int overwrite) { - return (overwrite || !getenv(name)) ? _putenv_s(name, value) : 0; -} -#endif - -static void InitSwigLib() { - const char* root = ArcadiaRoot(); - const char* lib = STR(SWIG_LIB_ARCPATH); - char* s = new char[strlen(root) + 1 + strlen(lib) + 1]; - sprintf(s, "%s/%s", root, lib); - setenv("SWIG_LIB", s, false); - delete[] s; -} - -static int initSwigLib = (InitSwigLib(), 0); diff --git a/contrib/tools/swig/ya.make b/contrib/tools/swig/ya.make deleted file mode 100644 index d1d4b407c8c..00000000000 --- a/contrib/tools/swig/ya.make +++ /dev/null @@ -1,120 +0,0 @@ -# Generated by devtools/yamaker from nixpkgs 22.11. - -PROGRAM(swig) - -LICENSE( - Custom-swig AND - GPL-3.0-only -) - -LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - -VERSION(4.1.1) - -ORIGINAL_SOURCE(https://github.com/swig/swig/archive/v4.1.1.tar.gz) - -PEERDIR( - contrib/libs/pcre2 -) - -ADDINCL( - contrib/libs/pcre2 - contrib/tools/swig/Source/CParse - contrib/tools/swig/Source/DOH - contrib/tools/swig/Source/Doxygen - contrib/tools/swig/Source/Include - contrib/tools/swig/Source/Modules - contrib/tools/swig/Source/Preprocessor - contrib/tools/swig/Source/Swig -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DSWIG_LIB_ARCPATH=contrib/tools/swig/Lib - -DHAVE_CONFIG_H -) - -BISON_GEN_C() - -SRCS( - Source/CParse/cscanner.c - Source/CParse/parser.y - Source/CParse/templ.c - Source/CParse/util.c - Source/DOH/base.c - Source/DOH/file.c - Source/DOH/fio.c - Source/DOH/hash.c - Source/DOH/list.c - Source/DOH/memory.c - Source/DOH/string.c - Source/DOH/void.c - Source/Doxygen/doxyentity.cxx - Source/Doxygen/doxyparser.cxx - Source/Doxygen/doxytranslator.cxx - Source/Doxygen/javadoc.cxx - Source/Doxygen/pydoc.cxx - Source/Modules/allocate.cxx - Source/Modules/contract.cxx - Source/Modules/csharp.cxx - Source/Modules/d.cxx - Source/Modules/directors.cxx - Source/Modules/emit.cxx - Source/Modules/go.cxx - Source/Modules/guile.cxx - Source/Modules/interface.cxx - Source/Modules/java.cxx - Source/Modules/javascript.cxx - Source/Modules/lang.cxx - Source/Modules/lua.cxx - Source/Modules/main.cxx - Source/Modules/mzscheme.cxx - Source/Modules/nested.cxx - Source/Modules/ocaml.cxx - Source/Modules/octave.cxx - Source/Modules/overload.cxx - Source/Modules/perl5.cxx - Source/Modules/php.cxx - Source/Modules/python.cxx - Source/Modules/r.cxx - Source/Modules/ruby.cxx - Source/Modules/scilab.cxx - Source/Modules/swigmain.cxx - Source/Modules/tcl8.cxx - Source/Modules/typepass.cxx - Source/Modules/utils.cxx - Source/Modules/xml.cxx - Source/Preprocessor/cpp.c - Source/Preprocessor/expr.c - Source/Swig/cwrap.c - Source/Swig/deprecate.c - Source/Swig/error.c - Source/Swig/extend.c - Source/Swig/fragment.c - Source/Swig/getopt.c - Source/Swig/include.c - Source/Swig/misc.c - Source/Swig/naming.c - Source/Swig/parms.c - Source/Swig/scanner.c - Source/Swig/stype.c - Source/Swig/symbol.c - Source/Swig/tree.c - Source/Swig/typemap.c - Source/Swig/typeobj.c - Source/Swig/typesys.c - Source/Swig/wrapfunc.c - swig_lib.cpp -) - -END() - -RECURSE( - Lib/go - Lib/java - Lib/perl5 - Lib/python -) |