diff --git a/ANNOUNCE b/ANNOUNCE index 2595f7a55..ad3e8f8d6 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,14 +1,11 @@ -*** ANNOUNCE: SWIG 2.0.0 (in progress) *** +*** ANNOUNCE: SWIG 2.0.1 (in progress) *** http://www.swig.org - -We're pleased to announce SWIG-2.0.0, the latest installment in the -SWIG development effort. SWIG-2.0.0 includes a number of bug fixes -and enhancements. +We're pleased to announce SWIG-2.0.1, the latest SWIG release. What is SWIG? -------------- +============= SWIG is a software development tool that reads C/C++ header files and generates the wrapper code needed to make C and C++ code accessible @@ -20,17 +17,17 @@ SWIG include generation of scripting language extension modules, rapid prototyping, testing, and user interface development for large C/C++ systems. -Availability: -------------- +Availability +============ The release is available for download on Sourceforge at - http://prdownloads.sourceforge.net/swig/swig-2.0.0.tar.gz + http://prdownloads.sourceforge.net/swig/swig-2.0.1.tar.gz A Windows version is also available at - http://prdownloads.sourceforge.net/swig/swigwin-2.0.0.zip + http://prdownloads.sourceforge.net/swig/swigwin-2.0.1.zip -Please report problems with this release to the swig-dev mailing list, +Please report problems with this release to the swig-devel mailing list, details at http://www.swig.org/mail.html. --- The SWIG Developers diff --git a/CCache/Makefile.in b/CCache/Makefile.in index ef20f48a0..d8f9042fe 100644 --- a/CCache/Makefile.in +++ b/CCache/Makefile.in @@ -40,8 +40,11 @@ web/ccache-man.html: ccache.yo yodl2html -o web/ccache-man.html ccache.yo install: $(PACKAGE_NAME)$(EXEEXT) $(PACKAGE_NAME).1 + @echo "Installing $(PACKAGE_NAME)" + @echo "Installing $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT)" ${INSTALLCMD} -d $(DESTDIR)${bindir} ${INSTALLCMD} -m 755 $(PACKAGE_NAME)$(EXEEXT) $(DESTDIR)${bindir}/`echo $(PACKAGE_NAME) | sed '$(transform)'`$(EXEEXT) + @echo "Installing $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1" ${INSTALLCMD} -d $(DESTDIR)${mandir}/man1 ${INSTALLCMD} -m 644 ${srcdir}/$(PACKAGE_NAME).1 $(DESTDIR)${mandir}/man1/`echo $(PACKAGE_NAME) | sed '$(transform)'`.1 @@ -52,9 +55,6 @@ uninstall: $(PACKAGE_NAME)$(EXEEXT) $(PACKAGE_NAME).1 clean: /bin/rm -f $(OBJS) *~ $(PACKAGE_NAME)$(EXEEXT) -distclean-docs: - rm -f $(PACKAGE_NAME).1 web/ccache-man.html - check : test test: test.sh @@ -62,11 +62,13 @@ test: test.sh check: test -distclean: clean distclean-docs - /bin/rm -f Makefile config.h config.sub config.log build-stamp config.status config.h.in ccache_swig_config.h +distclean: clean + /bin/rm -f Makefile config.h config.sub config.log build-stamp config.status ccache_swig_config.h + /bin/rm -rf autom4te.cache maintainer-clean: distclean - /bin/rm -f configure + /bin/rm -f $(PACKAGE_NAME).1 web/ccache-man.html + # FIXME: To fix this, test.sh needs to be able to take ccache from the # installed prefix, not from the source dir. diff --git a/CHANGES b/CHANGES index 509484e2f..f243ff7c6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,668 @@ SWIG (Simplified Wrapper and Interface Generator) -See CHANGES.current for current version. +See the CHANGES.current file for changes in the current version. +See the RELEASENOTES file for a summary of changes in each release. + +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 + + 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 http://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 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 compileable 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 compileable 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 uncompileable 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. Uncompileable 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 uncompileable + 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 struct X { void a() {}; }; + template <> struct X { 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. 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 class X {}; + template class X {}; + %template(X1) X; // Chooses T * specialization + + and more complex cases with multiple parameters and a mix of template argument + deduction and explicitly specialised parameters, eg: + template struct TwoParm { void a() {} }; + template struct TwoParm { void e() {} }; + %template(E) TwoParm; + + 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) =============================== @@ -956,7 +1618,7 @@ Version 1.3.35 (7 April 2008) 03/17/2008: olly Fix memory leak in SWIG's parser (based on patch from Russell - Bryant in SF#1914023).` + Bryant in SF#1914023). 03/12/2008: wsfulton Fix bug #1878285 - unnecessary cast for C struct creation wrappers. @@ -8256,7 +8918,7 @@ Version 1.3.22 (September 4, 2004) When needed, use %inlcude std_string.i // 'char' strings - %inlcude std_wstring.i // 'wchar_t; strings + %inlcude std_wstring.i // 'wchar_t' strings 04/10/2004: mmatus (Marcelo Matus) diff --git a/CHANGES.current b/CHANGES.current index 902308847..63af7206d 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,371 +1,27 @@ -Version 1.3.41 (in progress) -============================ +This file contains 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. -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. +Version 2.0.1 (in progress) +=========================== -2010-02-13: wsfulton - [Ruby] A few fixes for compiling under ruby-1.9.x including patch from 'Nibble'. +2010-07-16: wsfulton + Fix wrapping of function pointers and member function pointers when the function + returns by reference. -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-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-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: +2010-06-10: wsfulton + [Lua] Fix SWIG_lua_isnilstring multiply defined when using multiple + modules and wrapping strings. Patch from 'Number Cruncher'. - 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 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 compileable 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 compileable 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 uncompileable 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. Uncompileable 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 uncompileable - 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 struct X { void a() {}; }; - template <> struct X { 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. 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 class X {}; - template class X {}; - %template(X1) X; // Chooses T * specialization - - and more complex cases with multiple parameters and a mix of template argument - deduction and explicitly specialised parameters, eg: - template struct TwoParm { void a() {} }; - template struct TwoParm { void e() {} }; - %template(E) TwoParm; - - 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 +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 uncompileable code when %rename results in two enum items + with the same name. Reported by Vadim Zeitlin. diff --git a/COPYRIGHT b/COPYRIGHT index 45f9d6b45..40d09a1d6 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -29,7 +29,7 @@ Past SWIG developers and major contributors include: Charlie Savage (cfis@interserv.com) (Ruby) Thien-Thi Nguyen (ttn@glug.org) (build/test/misc) Richard Palmer (richard@magicality.org) (PHP) - Sam Liddicott - Anonova Ltd (saml@liddicott.com) (PHP) + Sam Liddicott - Ananova Ltd (saml@liddicott.com) (PHP) Tim Hockin - Sun Microsystems (thockin@sun.com) (PHP) Kevin Ruland (PHP) Shibukawa Yoshiki (Japanese Translation) @@ -58,6 +58,42 @@ Past SWIG developers and major contributors include: 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 - (See CHANGES and CHANGES.current for a more complete list). + 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 + (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/Doc/Devel/cmdopt.html b/Doc/Devel/cmdopt.html index c5f207c03..5e90d2aba 100644 --- a/Doc/Devel/cmdopt.html +++ b/Doc/Devel/cmdopt.html @@ -36,7 +36,7 @@ functions to mark whether or not a particular command line option was used. Thi

Argument Marking

-As command line options are are processed by language modules, the following functions are used +As command line options are processed by language modules, the following functions are used to mark the arguments as used:

diff --git a/Doc/Devel/engineering.html b/Doc/Devel/engineering.html index 5ccfb7858..7dfef2ad3 100644 --- a/Doc/Devel/engineering.html +++ b/Doc/Devel/engineering.html @@ -119,22 +119,25 @@ are case-insensitive on Windows so this convention will prevent you from inadver creating two files that differ in case-only.

-Each file should include a short abstract, author information, copyright information, and +Each file should include a short abstract, license information and a SVN revision tag like this:

 /* -----------------------------------------------------------------------------
- * See the LICENSE file for information on copyright, usage and redistribution
- * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ * This file is part of SWIG, which is licensed as a whole under version 3 
+ * (or any later version) of the GNU General Public License. Some additional
+ * terms also apply to certain portions of SWIG. The full details of the SWIG
+ * license and copyrights can be found in the LICENSE and COPYRIGHT files
+ * included with the SWIG source code as distributed by the SWIG developers
+ * and at http://www.swig.org/legal.html.
  *
- * cwrap.c
+ * xxx.c
  *
- * This file defines a variety of wrapping rules for C/C++ handling including
- * the naming of local variables, calling conventions, and so forth.
+ * This file defines ...
  * ----------------------------------------------------------------------------- */
 
-char cvsroot_cwrap_c[] = "$Id$";
+static char cvs[] = "$Id$ xxx.c";
 
 #include "swig.h"
 
diff --git a/Doc/Devel/internals.html b/Doc/Devel/internals.html
index 63a8626ff..6ac3947f7 100644
--- a/Doc/Devel/internals.html
+++ b/Doc/Devel/internals.html
@@ -42,11 +42,9 @@ David M. Beazley 
  • 3. Types and Typemaps
  • 4. Parsing -
  • 5. Difference Between SWIG 1.1 and SWIG 1.3 -
  • 6. Plans for SWIG 2.0 -
  • 7. C/C++ Wrapper Support Functions -
  • 8. Symbol Naming Guidelines for Generated C/C++ Code -
  • 9. Debugging SWIG +
  • 5. C/C++ Wrapper Support Functions +
  • 6. Symbol Naming Guidelines for Generated C/C++ Code +
  • 7. Debugging SWIG @@ -76,9 +74,8 @@ to code). Examples This subdir tree contains examples of using SWIG w/ different scripting languages, including makefiles. Typically, there are the -"simple" and "matrix" examples, w/ some languages offering additional -examples. The GIFPlot example has its own set of per-language -subdirectories. See the README more index.html file in each directory +"simple" and "class" examples, w/ some languages offering additional +examples. See the README more index.html file in each directory for more info. [FIXME: Ref SWIG user manual.] @@ -97,55 +94,35 @@ info. Source -SWIG source code is in this subdir tree. Directories marked w/ "(*)" -are used in building the swig executable. +The C and C++ source code for the swig executable is in this +subdir tree. - + + containers. - - - - - + - - + + - - - - + language has a .cxx and a .h file). - - + + - - - - - - - - - - + @@ -154,7 +131,7 @@ are used in building the swig executable. - + @@ -173,14 +150,14 @@ to look for code: - -
    DOH (*)
    DOH C library providing memory allocation, file access and generic - containers. Result: libdoh.a
    Experiment[TODO]
    Include (*)
    Include Configuration .h files
    LParseParser (lex / yacc) files and support [why not (*)?!]
    CParseParser (lex / yacc) files and support
    Modules[TODO]
    Modules1.1 (*) Language-specific callbacks that does actual code generation (each - language has a .cxx and a .h file). Result: libmodules11.a
    Preprocessor (*)SWIG-specialized C/C++ preprocessor. Result: libcpp.a
    PreprocessorSWIG-specialized C/C++ preprocessor.
    SWIG1.1 (*)Parts of SWIG that are not language-specific, including option - processing and the type-mapping system. Result: libswig11.a. - Note: This directory is currently being phased out.
    SWIG1.3[TODO] [funny, nothing here is presently used for swig-1.3]. - This directory might turn into a compatibility interface between - SWIG1.3 and the SWIG1.1 modules.
    Swig (*)This directory contains the new ANSI C core of the system +
    SwigThis directory contains the ANSI C core of the system and contains generic functions related to types, file handling, scanning, and so forth.
    ToolsLibtool support and the mkdist.py script.The mkdist.py script and other tools.
    Win
    usagetransform
    "skip" tag(none)
    Examples/ subdir name(none)
    Examples/GIFPlot/ subdir namecapitalize (upcase first letter)
    Examples/test-suite/ subdir name(none)
    @@ -3159,8 +3157,8 @@ skip-qux = $(skip-qux99)

    Lastly, you need to modify each of check-aliveness, -check-examples, check-test-suite, -check-gifplot (all targets) and lib-languages (var). +check-examples, check-test-suite +and lib-languages (var). Use the nickname for these, not the alias. Note that you can do this even before you have any tests or examples set up; the Makefile rules do some sanity checking and skip around @@ -3175,10 +3173,6 @@ and look to the existing languages for examples.

    Do cp ../python/check.list . and modify to taste. One subdir per line. -
    Examples/GIFPlot/Qux99/check.list -
    Do cp ../Python/check.list . and modify to taste. -One subdir per line. -
    Lib/qux99/extra-install.list
    If you add your language to the top-level Makefile.in var lib-languages, then make install will install @@ -3199,7 +3193,7 @@ politely displays the ignoring language message. -

    35.10.9 Runtime support

    +

    36.10.9 Runtime support

    @@ -3208,7 +3202,7 @@ Discuss the kinds of functions typically needed for SWIG runtime support (e.g. the SWIG files that implement those functions.

    -

    35.10.10 Standard library files

    +

    36.10.10 Standard library files

    @@ -3227,7 +3221,7 @@ The following are the minimum that are usually supported: Please copy these and modify for any new language.

    -

    35.10.11 User examples

    +

    36.10.11 User examples

    @@ -3252,11 +3246,11 @@ These can be found, for example for Python, in

    By default, all of the examples are built and run when the user types make check. To ensure that your examples are automatically run -during this process, see the section on configuration +during this process, see the section on configuration files.

    -

    35.10.12 Test driven development and the test-suite

    +

    36.10.12 Test driven development and the test-suite

    @@ -3315,7 +3309,7 @@ It is therefore essential that the runtime tests are written in a manner that di but error/exception out with an error message on stderr on failure.

    -

    35.10.12.1 Running the test-suite

    +

    36.10.12.1 Running the test-suite

    @@ -3475,7 +3469,15 @@ SWIG can be analyzed for bad memory accesses using: make ret_by_value.ctest SWIGTOOL="valgrind --tool=memcheck --trace-children=yes"

  • -

    35.10.13 Documentation

    +

    +A debugger can also be invoked easily on an individual test, for example gdb: +

    + +
    +make ret_by_value.ctest RUNTOOL="gdb --args"
    +
    + +

    36.10.13 Documentation

    @@ -3507,7 +3509,7 @@ Some topics that you'll want to be sure to address include: if available. -

    35.10.14 Prerequisites for adding a new language module to the SWIG distribution

    +

    36.10.14 Prerequisites for adding a new language module to the SWIG distribution

    @@ -3564,7 +3566,7 @@ should be added should there be an area not already covered by the existing tests.

    -

    35.10.15 Coding style guidelines

    +

    36.10.15 Coding style guidelines

    @@ -3588,7 +3590,7 @@ The generated C/C++ code should also follow this style as close as possible. How should be avoided as unlike the SWIG developers, users will never have consistent tab settings.

    -

    35.11 Debugging Options

    +

    36.11 Debugging Options

    @@ -3613,7 +3615,7 @@ There are various command line options which can aid debugging a SWIG interface The complete list of command line options for SWIG are available by running swig -help.

    -

    35.12 Guide to parse tree nodes

    +

    36.12 Guide to parse tree nodes

    @@ -4021,7 +4023,7 @@ extern "X" { ... } declaration. -

    35.13 Further Development Information

    +

    36.13 Further Development Information

    diff --git a/Doc/Manual/Go.html b/Doc/Manual/Go.html new file mode 100644 index 000000000..5e99a5156 --- /dev/null +++ b/Doc/Manual/Go.html @@ -0,0 +1,454 @@ + + + +SWIG and Go + + + +

    20 SWIG and Go

    + + + + + + +

    +This chapter describes SWIG's support of Go. For more information on +the Go programming language +see golang.org. +

    + +

    20.1 Overview

    + + +

    +Go is a compiled language, not a scripting language. However, it does +not support direct calling of functions written in C/C++. The cgo +program may be used to generate wrappers to call C code from Go, but +there is no convenient way to call C++ code. SWIG fills this gap. +

    + +

    +There are (at least) two different Go compilers. One is the gc +compiler, normally invoked under the names 6g, 8g, or 5g. The other +is the gccgo compiler, which is a frontend to the gcc compiler suite. +The interface to C/C++ code is completely different for the two Go +compilers. SWIG supports both, selected by a command line option. +

    + +

    +Because Go is a type-safe compiled language, SWIG's runtime type +checking and runtime library are not used with Go. This should be +borne in mind when reading the rest of the SWIG documentation. +

    + +

    20.2 Running SWIG with Go

    + + +

    +To generate Go code, use the -go option with SWIG. By +default SWIG will generate code for the gc compilers. To generate +code for gccgo, you should also use the -gccgo option. +

    + +

    20.2.1 Additional Commandline Options

    + + +

    +These are the command line options for SWIG's GO module. They can +also be seen by using: +

    + +
    +swig -go -help
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Go specific options
    -gccgoGenerate code for gccgo. The default is to generate code for + 6g/8g/6g.
    -package <name>Set the name of the Go package to <name>. The default + package name is the SWIG module name.
    -go-prefix <prefix>When generating code for gccgo, set the prefix to use. This + corresponds to the -fgo-prefix option to gccgo.
    -long-type-size <s>Set the size for the C/C++ type long. This controls + whether long is converted to the Go type int32 + or int64. The <s> argument should be 32 or 64.
    + +

    20.2.2 Go Output Files

    + + +

    When generating Go code, SWIG will generate the following + files:

    + +
      +
    • +MODULE.go will contain the Go functions that your Go code will call. +These functions will be wrappers for the C++ functions defined by your +module. This file should, of course, be compiled with the Go +compiler. +
    • +MODULE_wrap.c or MODULE_wrap.cxx will contain C/C++ functions will be +invoked by the Go wrapper code. This file should be compiled with the +usual C or C++ compiler and linked into a shared library. +
    • +MODULE_wrap.h will be generated if you use the directors feature. It +provides a definition of the generated C++ director classes. It is +generally not necessary to use this file, but in some special cases it +may be helpful to include it in your code, compiled with the usual C +or C++ compiler. +
    • +If using the gc compiler, MODULE_gc.c will contain C code which should +be compiled with the C compiler distributed as part of the gc compiler: 6c, 8c, +or 5c. It should then be combined with the compiled MODULE.go using +gopack. This file will not be generated when using gccgo. +
    + +

    +A typical command sequence would look like this: +

    + +
    +% swig -go example.i
    +% gcc -c -fpic example.c
    +% gcc -c -fpic example_wrap.c
    +% gcc -shared example.o example_wrap.o -o example.so
    +% 6g example.go
    +% 6c example_gc.c
    +% gopack grc example.a example.6 example_gc.6
    +% 6g main.go  # your code, not generated by SWIG
    +% 6l main.6
    +
    + +

    20.3 A tour of basic C/C++ wrapping

    + + +

    +By default, SWIG attempts to build a natural Go interface to your +C/C++ code. However, the languages are somewhat different, so some +modifications have to occur. This section briefly covers the +essential aspects of this wrapping. +

    + +

    20.3.1 Go Package Name

    + + +

    +All Go source code lives in a package. The name of this package will +default to the name of the module from SWIG's %module +directive. You may override this by using SWIG's -package +command line option. +

    + +

    20.3.2 Go Names

    + + +

    +In Go, a function is only visible outside the current package if the +first letter of the name is uppercase. This is quite different from +C/C++. Because of this, C/C++ names are modified when generating the +Go interface: the first letter is forced to be uppercase if it is not +already. This affects the names of functions, methods, variables, +constants, enums, and classes. +

    + +

    +C/C++ variables are wrapped with setter and getter functions in Go. +First the first letter of the variable name will be forced to +uppercase, and then Get or Set will be prepended. +For example, if the C/C++ variable is called var, then SWIG +will define the functions GetVar and SetVar. If a +variable is declared as const, or if +SWIG's +%immutable directive is used for the variable, then only +the getter will be defined. +

    + +

    +C++ classes will be discussed further below. Here we'll note that the +first letter of the class name will be forced to uppercase to give the +name of a type in Go. A constructor will be named New +followed by that name, and the destructor will be +named Delete followed by that name. +

    + +

    20.3.3 Go Constants

    + + +

    +C/C++ constants created via #define or the %constant +directive become Go constants, declared with a const +declaration. + +

    20.3.4 Go Enumerations

    + + +

    +C/C++ enumeration types will cause SWIG to define an integer type with +the name of the enumeration (with first letter forced to uppercase as +usual). The values of the enumeration will become variables in Go; +code should avoid modifying those variables. +

    + +

    20.3.5 Go Classes

    + + +

    +Go has interfaces, methods and inheritance, but it does not have +classes in the same sense as C++. This sections describes how SWIG +represents C++ classes represented in Go. +

    + +

    +For a C++ class ClassName, SWIG will define two types in Go: +an underlying type, which will just hold a pointer to the C++ type, +and an interface type. The interface type will be +named ClassName. SWIG will define a +function NewClassName which will take any constructor +arguments and return a value of the interface +type ClassName. SWIG will also define a +destructor DeleteClassName. +

    + +

    +SWIG will represent any methods of the C++ class as methods on the +underlying type, and also as methods of the interface type. Thus C++ +methods may be invoked directly using the +usual val.MethodName syntax. Public members of the C++ class +will be given getter and setter functions defined as methods of the +class. +

    + +

    +SWIG will represent static methods of C++ classes as ordinary Go +functions. SWIG will use names like ClassName_MethodName. +SWIG will give static members getter and setter functions with names +like GetClassName_VarName. +

    + +

    +Given a value of the interface type, Go code can retrieve the pointer +to the C++ type by calling the Swigcptr method. This will +return a value of type SwigcptrClassName, which is just a +name for uintptr. A Go type conversion can be used to +convert this value to a different C++ type, but note that this +conversion will not be type checked and is essentially equivalent +to reinterpret_cast. This should only be used for very +special cases, such as where C++ would use a dynamic_cast. +

    + +

    20.3.5.1 Go Class Inheritance

    + + +

    +C++ class inheritance is automatically represented in Go due to its +use of interfaces. The interface for a child class will be a superset +of the interface of its parent class. Thus a value of the child class +type in Go may be passed to a function which expects the parent class. +Doing the reverse will require an explicit type assertion, which will +be checked dynamically. +

    + +

    20.3.6 Go Templates

    + + +

    +In order to use C++ templates in Go, you must tell SWIG to create +wrappers for a particular template instantation. To do this, use +the %template directive. + +

    20.3.7 Go Director Classes

    + + +

    +SWIG's director feature permits a Go type to act as the subclass of a +C++ class with virtual methods. This is complicated by the fact that +C++ and Go define inheritance differently. In Go, structs can inherit +methods via anonymous field embedding. However, when a method is +called for an embedded struct, if that method calls any other methods, +they are called for the embedded struct, not for the original type. +Therefore, SWIG must use Go interfaces to represent C++ inheritance. +

    + +

    +In order to use the director feature in Go, you must define a type in +your Go code. You must then add methods for the type. Define a +method in Go for each C++ virtual function that you want to override. +You must then create a value of your new type, and pass a pointer to +it to the function NewDirectorClassName, +where ClassName is the name of the C++ class. That will +return a value of type ClassName. +

    + +

    +For example: +

    + +
    +
    +type GoClass struct { }
    +func (p *GoClass) VirtualFunction() { }
    +func MakeClass() ClassName {
    +	return NewDirectorClassName(&GoClass{})
    +}
    +
    +
    + +

    +Any call in C++ code to the virtual function will wind up calling the +method defined in Go. The Go code may of course call other methods on +itself, and those methods may be defined either in Go or in C++. +

    + +

    20.3.8 Default Go primitive type mappings

    + + +

    +The following table lists the default type mapping from C/C++ to Go. +This table will tell you which Go type to expect for a function which +uses a given C/C++ type. +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    C/C++ typeGo type
    boolbool
    charbyte
    signed charint8
    unsigned charbyte
    shortint16
    unsigned shortuint16
    intint
    unsigned intuint
    longint32 or int64, depending on -long-type-size
    unsigned longuint32 or uint64, depending on -long-type-size
    long longint64
    unsigned long longuint64
    floatfloat32
    doublefloat64
    char *
    char []
    string
    + +

    +Note that SWIG wraps the C char type as a character. Pointers +and arrays of this type are wrapped as strings. The signed +char type can be used if you want to treat char as a +signed number rather than a character. Also note that all const +references to primitive types are treated as if they are passed by +value. +

    + +

    +These type mappings are defined by the "gotype" typemap. You may change +that typemap, or add new values, to control how C/C++ types are mapped +into Go types. +

    + + + diff --git a/Doc/Manual/Guile.html b/Doc/Manual/Guile.html index 61b5ba7d6..75c3d3473 100644 --- a/Doc/Manual/Guile.html +++ b/Doc/Manual/Guile.html @@ -8,7 +8,7 @@ -

    20 SWIG and Guile

    +

    21 SWIG and Guile

      @@ -47,7 +47,7 @@

      This section details guile-specific support in SWIG. -

      20.1 Meaning of "Module"

      +

      21.1 Meaning of "Module"

      @@ -55,7 +55,7 @@ There are three different concepts of "module" involved, defined separately for SWIG, Guile, and Libtool. To avoid horrible confusion, we explicitly prefix the context, e.g., "guile-module". -

      20.2 Using the SCM or GH Guile API

      +

      21.2 Using the SCM or GH Guile API

      The guile module can currently export wrapper files that use the guile GH interface or the @@ -69,7 +69,7 @@ SCM interface is the default. The SCM and GH interface differ greatly in how th pointers and have completely different run-time code. See below for more info.

      The GH interface to guile is deprecated. Read more about why in the -Guile manual. +Guile manual. The idea of the GH interface was to provide a high level API that other languages and projects could adopt. This was a good idea, but didn't pan out well for general development. But for the specific, minimal uses that the SWIG typemaps put the GH interface to use is ideal for @@ -103,7 +103,7 @@ for the specific API. Currently only the guile language module has created a ma but there is no reason other languages (like mzscheme or chicken) couldn't also use this. If that happens, there is A LOT less code duplication in the standard typemaps.

      -

      20.3 Linkage

      +

      21.3 Linkage

      @@ -111,7 +111,7 @@ Guile support is complicated by a lack of user community cohesiveness, which manifests in multiple shared-library usage conventions. A set of policies implementing a usage convention is called a linkage. -

      20.3.1 Simple Linkage

      +

      21.3.1 Simple Linkage

      @@ -206,7 +206,7 @@ placed between the define-module form and the SWIG_init via a preprocessor define to avoid symbol clashes. For this case, however, passive linkage is available. -

      20.3.2 Passive Linkage

      +

      21.3.2 Passive Linkage

      Passive linkage is just like simple linkage, but it generates an @@ -216,7 +216,7 @@ package name (see below).

      You should use passive linkage rather than simple linkage when you are using multiple modules. -

      20.3.3 Native Guile Module Linkage

      +

      21.3.3 Native Guile Module Linkage

      SWIG can also generate wrapper code that does all the Guile module @@ -257,7 +257,7 @@ Newer Guile versions have a shorthand procedure for this:

    -

    20.3.4 Old Auto-Loading Guile Module Linkage

    +

    21.3.4 Old Auto-Loading Guile Module Linkage

    Guile used to support an autoloading facility for object-code @@ -283,7 +283,7 @@ option, SWIG generates an exported module initialization function with an appropriate name. -

    20.3.5 Hobbit4D Linkage

    +

    21.3.5 Hobbit4D Linkage

    @@ -308,7 +308,7 @@ my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very experimental; the (hobbit4d link) conventions are not well understood.

    -

    20.4 Underscore Folding

    +

    21.4 Underscore Folding

    @@ -320,7 +320,7 @@ complained so far. %rename to specify the Guile name of the wrapped functions and variables (see CHANGES). -

    20.5 Typemaps

    +

    21.5 Typemaps

    @@ -409,10 +409,10 @@ See also the "multivalue" example. %feature("constasvar") can be applied to any constant, immutable variable, or enum. Instead of exporting the constant as a function that must be called, the constant will appear as a scheme variable. See -Features and the %feature directive +Features and the %feature directive for info on how to apply the %feature.

    -

    20.6 Representation of pointers as smobs

    +

    21.6 Representation of pointers as smobs

    @@ -433,7 +433,7 @@ representing the expected pointer type. See also If the Scheme object passed was not a SWIG smob representing a compatible pointer, a wrong-type-arg exception is raised. -

    20.6.1 GH Smobs

    +

    21.6.1 GH Smobs

    @@ -462,7 +462,7 @@ that created them, so the first module we check will most likely be correct. Once we have a swig_type_info structure, we loop through the linked list of casts, using pointer comparisons.

    -

    20.6.2 SCM Smobs

    +

    21.6.2 SCM Smobs

    The SCM interface (using the "-scm" argument to swig) uses swigrun.swg. @@ -477,7 +477,7 @@ in the smob tag. If a generated GOOPS module has been loaded, smobs will be wra GOOPS class.

    -

    20.6.3 Garbage Collection

    +

    21.6.3 Garbage Collection

    Garbage collection is a feature of the new SCM interface, and it is automatically included @@ -487,11 +487,11 @@ to the destructor for this type. The destructor is the generated wrapper around So swig still exports a wrapper for the destructor, it just does not call scm_c_define_gsubr() for the wrapped delete function. So the only way to delete an object is from the garbage collector, since the delete function is not available to scripts. How swig determines if a type should be garbage collected -is exactly like described in +is exactly like described in Object ownership and %newobject in the SWIG manual. All typemaps use an $owner var, and the guile module replaces $owner with 0 or 1 depending on feature:new.

    -

    20.7 Exception Handling

    +

    21.7 Exception Handling

    @@ -517,7 +517,7 @@ mapping: The default when not specified here is to use "swig-error". See Lib/exception.i for details. -

    20.8 Procedure documentation

    +

    21.8 Procedure documentation

    If invoked with the command-line option -procdoc @@ -553,7 +553,7 @@ like this: typemap argument doc. See Lib/guile/typemaps.i for details. -

    20.9 Procedures with setters

    +

    21.9 Procedures with setters

    For global variables, SWIG creates a single wrapper procedure @@ -581,7 +581,7 @@ struct members, the procedures (struct-member-get pointer) and (struct-member-set pointer value) are not generated. -

    20.10 GOOPS Proxy Classes

    +

    21.10 GOOPS Proxy Classes

    SWIG can also generate classes and generic functions for use with @@ -730,7 +730,7 @@ Notice that <Foo> is used before it is defined. The fix is to just put th %import "foo.h" before the %inline block.

    -

    20.10.1 Naming Issues

    +

    21.10.1 Naming Issues

    As you can see in the example above, there are potential naming conflicts. The default exported @@ -767,9 +767,7 @@ guile-modules. For example,

    (use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:))) -

    TODO: Renaming class name prefixes?

    - -

    20.10.2 Linking

    +

    21.10.2 Linking

    The guile-modules generated above all need to be linked together. GOOPS support requires diff --git a/Doc/Manual/Introduction.html b/Doc/Manual/Introduction.html index df8d03fdf..3bac9484e 100644 --- a/Doc/Manual/Introduction.html +++ b/Doc/Manual/Introduction.html @@ -37,7 +37,7 @@

    SWIG is a software development tool that simplifies the task of interfacing different languages to C and C++ programs. In a -nutshell, SWIG is a compiler that takes C declarations and creates +nutshell, SWIG is a compiler that takes C/C++ declarations and creates the wrappers needed to access those declarations from other languages including including Perl, Python, Tcl, Ruby, Guile, and Java. SWIG normally requires no modifications to existing code and can often be used to @@ -68,7 +68,8 @@ a dedicated IDL compiler). Although this style of development isn't appropriate for every project, it is particularly well suited to software development in the small; especially the research and development work that is commonly found -in scientific and engineering projects. +in scientific and engineering projects. However, nowadays SWIG is known to be used in many +large open source and commercial projects.

    2.2 Why use SWIG?

    @@ -365,7 +366,7 @@ possible to support different types of interfaces depending on the application.

    SWIG is a command line tool and as such can be incorporated into any build system that supports invoking external tools/compilers. -SWIG is most commonly invoked from within a Makefile, but is also known to be invoked from from popular IDEs such as +SWIG is most commonly invoked from within a Makefile, but is also known to be invoked from popular IDEs such as Microsoft Visual Studio.

    @@ -375,10 +376,10 @@ If you are using the GNU Autotools Automake/ Libtool) to configure SWIG use in your project, the SWIG Autoconf macros can be used. -The primary macro is ac_pkg_swig, see -http://www.gnu.org/software/ac-archive/htmldoc/ac_pkg_swig.html. -The ac_python_devel macro is also helpful for generating Python extensions. See the -Autoconf Macro Archive +The primary macro is ax_pkg_swig, see +http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig. +The ax_python_devel macro is also helpful for generating Python extensions. See the +Autoconf Archive for further information on this and other Autoconf macros.

    diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html index 7869c5269..f572ffa32 100644 --- a/Doc/Manual/Java.html +++ b/Doc/Manual/Java.html @@ -5,143 +5,143 @@ -

    21 SWIG and Java

    +

    22 SWIG and Java

    @@ -154,7 +154,7 @@ It covers most SWIG features, but certain low-level details are covered in less

    -

    21.1 Overview

    +

    22.1 Overview

    @@ -181,7 +181,7 @@ However, the "SWIG Basics" chapter will be a useful

    This chapter starts with a few practicalities on running SWIG and compiling the generated code. If you are looking for the minimum amount to read, have a look at the sections up to and including the -tour of basic C/C++ wrapping section which explains how to call the various C/C++ code constructs from Java. +tour of basic C/C++ wrapping section which explains how to call the various C/C++ code constructs from Java. Following this section are details of the C/C++ code and Java classes that SWIG generates. Due to the complexities of C and C++ there are different ways in which C/C++ code could be wrapped and called from Java. SWIG is a powerful tool and the rest of the chapter details how the default code wrapping can be tailored. @@ -189,7 +189,7 @@ Various customisation tips and techniques using SWIG directives are covered. The latter sections cover the advanced techniques of using typemaps for complete control of the wrapping process.

    -

    21.2 Preliminaries

    +

    22.2 Preliminaries

    @@ -205,7 +205,7 @@ Run make -k check from the SWIG root directory after installing SWIG on The Java module requires your system to support shared libraries and dynamic loading. This is the commonly used method to load JNI code so your system will more than likely support this.

    -

    21.2.1 Running SWIG

    +

    22.2.1 Running SWIG

    @@ -250,11 +250,11 @@ rest of your C/C++ application. The name of the wrapper file is derived from the name of the input file. For example, if the input file is example.i, the name of the wrapper file is example_wrap.c. To change this, you can use the -o option. -It is also possible to change the output directory that the Java files are generated into using -outdir. +It is also possible to change the output directory that the Java files are generated into using -outdir.

    -The module name, specified with %module, determines the name of various generated classes as discussed later. +The module name, specified with %module, determines the name of various generated classes as discussed later. Note that the module name does not define a Java package and by default, the generated Java classes do not have a Java package. The -package option described below can specify a Java package name to use.

    @@ -264,7 +264,7 @@ The following sections have further practical examples and details on how you mi compiling and using the generated files.

    -

    21.2.2 Additional Commandline Options

    +

    22.2.2 Additional Commandline Options

    @@ -301,7 +301,7 @@ swig -java -help Their use will become clearer by the time you have finished reading this section on SWIG and Java.

    -

    21.2.3 Getting the right header files

    +

    22.2.3 Getting the right header files

    @@ -316,7 +316,7 @@ They are usually in directories like this:

    The exact location may vary on your machine, but the above locations are typical.

    -

    21.2.4 Compiling a dynamic module

    +

    22.2.4 Compiling a dynamic module

    @@ -344,15 +344,15 @@ is a useful reference for compiling on different platforms.

    Important
    If you are going to use optimisations turned on with gcc (for example -O2), ensure you also compile with -fno-strict-aliasing. The GCC optimisations have become -more aggressive from gcc-4.0 onwards and will result in code that fails with strict aliasing optimisations turned on. See the C/C++ to Java typemaps section for more details. +more aggressive from gcc-4.0 onwards and will result in code that fails with strict aliasing optimisations turned on. See the C/C++ to Java typemaps section for more details.

    The name of the shared library output file is important. -If the name of your SWIG module is "example", the name of the corresponding shared library file should be "libexample.so" (or equivalent depending on your machine, see Dynamic linking problems for more information). +If the name of your SWIG module is "example", the name of the corresponding shared library file should be "libexample.so" (or equivalent depending on your machine, see Dynamic linking problems for more information). The name of the module is specified using the %module directive or -module command line option.

    -

    21.2.5 Using your module

    +

    22.2.5 Using your module

    @@ -387,7 +387,7 @@ $ If it doesn't work have a look at the following section which discusses problems loading the shared library.

    -

    21.2.6 Dynamic linking problems

    +

    22.2.6 Dynamic linking problems

    @@ -474,7 +474,7 @@ The following section also contains some C++ specific linking problems and solut

    -

    21.2.7 Compilation problems and compiling with C++

    +

    22.2.7 Compilation problems and compiling with C++

    @@ -527,7 +527,7 @@ Finally make sure the version of JDK header files matches the version of Java th

    -

    21.2.8 Building on Windows

    +

    22.2.8 Building on Windows

    @@ -536,7 +536,7 @@ You will want to produce a DLL that can be loaded by the Java Virtual Machine. This section covers the process of using SWIG with Microsoft Visual C++ 6 although the procedure may be similar with other compilers. In order for everything to work, you will need to have a JDK installed on your machine in order to read the JNI header files.

    -

    21.2.8.1 Running SWIG from Visual Studio

    +

    22.2.8.1 Running SWIG from Visual Studio

    @@ -572,10 +572,10 @@ When doing a build, any changes made to the interface file will result in SWIG b

    The Java classes that SWIG output should also be compiled into .class files. To run the native code in the DLL (example.dll), make sure that it is in your path then run your Java program which uses it, as described in the previous section. -If the library fails to load have a look at Dynamic linking problems. +If the library fails to load have a look at Dynamic linking problems.

    -

    21.2.8.2 Using NMAKE

    +

    22.2.8.2 Using NMAKE

    @@ -634,7 +634,7 @@ Of course you may want to make changes for it to work for C++ by adding in the -

    -

    21.3 A tour of basic C/C++ wrapping

    +

    22.3 A tour of basic C/C++ wrapping

    @@ -644,7 +644,7 @@ variables are wrapped with JavaBean type getters and setters and so forth. This section briefly covers the essential aspects of this wrapping.

    -

    21.3.1 Modules, packages and generated Java classes

    +

    22.3.1 Modules, packages and generated Java classes

    @@ -680,7 +680,7 @@ swig -java -package com.bloggs.swig -outdir com/bloggs/swig example.i SWIG won't create the directory, so make sure it exists beforehand.

    -

    21.3.2 Functions

    +

    22.3.2 Functions

    @@ -714,7 +714,7 @@ System.out.println(example.fact(4)); -

    21.3.3 Global variables

    +

    22.3.3 Global variables

    @@ -801,7 +801,7 @@ extern char *path; // Read-only (due to %immutable) -

    21.3.4 Constants

    +

    22.3.4 Constants

    @@ -837,7 +837,7 @@ public interface exampleConstants { Note that SWIG has inferred the C type and used an appropriate Java type that will fit the range of all possible values for the C type. By default SWIG generates runtime constants. They are not compiler constants that can, for example, be used in a switch statement. This can be changed by using the %javaconst(flag) directive. It works like all -the other %feature directives. The default is %javaconst(0). +the other %feature directives. The default is %javaconst(0). It is possible to initialize all wrapped constants from pure Java code by placing a %javaconst(1) before SWIG parses the constants. Putting it at the top of your interface file would ensure this. Here is an example: @@ -941,7 +941,7 @@ Or if you decide this practice isn't so bad and your own class implements ex

    -

    21.3.5 Enumerations

    +

    22.3.5 Enumerations

    @@ -955,7 +955,7 @@ The final two approaches use simple integers for each enum item. Before looking at the various approaches for wrapping named C/C++ enums, anonymous enums are considered.

    -

    21.3.5.1 Anonymous enums

    +

    22.3.5.1 Anonymous enums

    @@ -1018,7 +1018,7 @@ As in the case of constants, you can access them through either the module class

    -

    21.3.5.2 Typesafe enums

    +

    22.3.5.2 Typesafe enums

    @@ -1053,7 +1053,7 @@ public final class Beverage {

    -See Typesafe enum classes to see the omitted support methods. +See Typesafe enum classes to see the omitted support methods. Note that the enum item with an initializer (LAGER) is initialized with the enum value obtained via a JNI call. However, as with anonymous enums and constants, use of the %javaconst directive is strongly recommended to change this behaviour:

    @@ -1094,10 +1094,11 @@ C++ enums defined within a C++ class are generated into a static final inner Jav

    -Typesafe enums have their advantages over using plain integers in that they they can be used in a typesafe manner. +Typesafe enums have their advantages over using plain integers in that they can be used in a typesafe manner. However, there are limitations. For example, they cannot be used in switch statements and serialization is an issue. Please look at the following references for further information: + http://java.sun.com/developer/Books/shiftintojava/page1.html#replaceenums Replace Enums with Classes in Effective Java Programming on the Sun website, Create enumerated constants in Java JavaWorld article, Java Tip 133: More on typesafe enums and @@ -1111,7 +1112,7 @@ When upgrading to JDK 1.5 or later, proper Java enums could be used instead, wit The following section details proper Java enum generation.

    -

    21.3.5.3 Proper Java enums

    +

    22.3.5.3 Proper Java enums

    @@ -1152,19 +1153,19 @@ public enum Beverage {

    -See Proper Java enum classes to see the omitted support methods. +See Proper Java enum classes to see the omitted support methods. The generated Java enum has numerous additional methods to support enums with initializers, such as LAGER above. Note that as with the typesafe enum pattern, enum items with initializers are by default initialized with the enum value obtained via a JNI call. However, this is not the case above as we have used the recommended %javaconst(1) to avoid the JNI call. -The %javaconstvalue(value) directive covered in the Constants section can also be used for proper Java enums. +The %javaconstvalue(value) directive covered in the Constants section can also be used for proper Java enums.

    The additional support methods need not be generated if none of the enum items have initializers and this is covered later in the -Simpler Java enums for enums without initializers section. +Simpler Java enums for enums without initializers section.

    -

    21.3.5.4 Type unsafe enums

    +

    22.3.5.4 Type unsafe enums

    @@ -1202,7 +1203,7 @@ public final class Beverage {

    As is the case previously, the default is %javaconst(0) as not all C/C++ values will compile as Java code. However, again it is recommended to add in a %javaconst(1) directive. -and the %javaconstvalue(value) directive covered in the Constants section can also be used for type unsafe enums. +and the %javaconstvalue(value) directive covered in the Constants section can also be used for type unsafe enums. Note that global enums are generated into a Java class within whatever package you are using. C++ enums defined within a C++ class are generated into a static final inner Java class within the Java proxy class.

    @@ -1212,7 +1213,7 @@ Note that unlike typesafe enums, this approach requires users to mostly use diff Thus the upgrade path to proper enums provided in JDK 1.5 is more painful.

    -

    21.3.5.5 Simple enums

    +

    22.3.5.5 Simple enums

    @@ -1221,7 +1222,7 @@ Each enum item is also wrapped as a static final integer. However, these integers are not generated into a class named after the C/C++ enum. Instead, global enums are generated into the constants interface. Also, enums defined in a C++ class have their enum items generated directly into the Java proxy class rather than an inner class within the Java proxy class. -In fact, this approach is effectively wrapping the enums as if they were anonymous enums and the resulting code is as per anonymous enums. +In fact, this approach is effectively wrapping the enums as if they were anonymous enums and the resulting code is as per anonymous enums. The implementation is in the "enumsimple.swg" file.

    @@ -1231,7 +1232,7 @@ SWIG-1.3.21 and earlier versions wrapped all enums using this approach. The type unsafe approach is preferable to this one and this simple approach is only included for backwards compatibility with these earlier versions of SWIG.

    -

    21.3.6 Pointers

    +

    22.3.6 Pointers

    @@ -1319,7 +1320,7 @@ C-style cast may return a bogus result whereas as the C++-style cast will return a NULL pointer if the conversion can't be performed.

    -

    21.3.7 Structures

    +

    22.3.7 Structures

    @@ -1428,8 +1429,8 @@ to by b.x. In this example, 16 integers would be copied. Like C, SWI no assumptions about bounds checking---if you pass a bad pointer, you may get a segmentation fault or access violation. The default wrapping makes it hard to set or get just one element of the array and so array access from Java is somewhat limited. -This can be changed easily though by using the approach outlined later in the Wrapping C arrays with Java arrays and -Unbounded C Arrays sections. +This can be changed easily though by using the approach outlined later in the Wrapping C arrays with Java arrays and +Unbounded C Arrays sections.

    @@ -1487,7 +1488,7 @@ x.setA(3); // Modify x.a - this is the same as b.f.a -

    21.3.8 C++ classes

    +

    22.3.8 C++ classes

    @@ -1550,7 +1551,7 @@ int bar = Spam.getBar(); -

    21.3.9 C++ inheritance

    +

    22.3.9 C++ inheritance

    @@ -1611,7 +1612,7 @@ Note that Java does not support multiple inheritance so any multiple inheritance A warning is given when multiple inheritance is detected and only the first base class is used.

    -

    21.3.10 Pointers, references, arrays and pass by value

    +

    22.3.10 Pointers, references, arrays and pass by value

    @@ -1666,7 +1667,7 @@ to hold the result and a pointer is returned (Java will release this memory when the returned object's finalizer is run by the garbage collector).

    -

    21.3.10.1 Null pointers

    +

    22.3.10.1 Null pointers

    @@ -1690,7 +1691,7 @@ For spam1 and spam4 above the Java null gets translat The converse also occurs, that is, NULL pointers are translated into null Java objects when returned from a C/C++ function.

    -

    21.3.11 C++ overloaded functions

    +

    22.3.11 C++ overloaded functions

    @@ -1805,7 +1806,7 @@ void spam(unsigned short); // Ignored -

    21.3.12 C++ default arguments

    +

    22.3.12 C++ default arguments

    @@ -1848,11 +1849,13 @@ Further details on default arguments and how to restore this approach are given

    -

    21.3.13 C++ namespaces

    +

    22.3.13 C++ namespaces

    -SWIG is aware of C++ namespaces, but namespace names do not appear in +SWIG is aware of named C++ namespaces and they can be mapped to Java packages, however, +the default wrapping flattens the namespaces, effectively ignoring them. +So by default, the namespace names do not appear in the module nor do namespaces result in a module that is broken up into submodules or packages. For example, if you have a file like this,

    @@ -1908,7 +1911,23 @@ symbols separate, consider wrapping them as separate SWIG modules. Each SWIG module can be placed into a separate package.

    -

    21.3.14 C++ templates

    +

    +The default behaviour described above can be improved via the nspace feature. +Note that it only works for classes, structs, unions and enums declared within a named C++ namespace. +When the nspace feature is used, the C++ namespaces are converted into Java packages of the same name. +Proxy classes are thus declared within a package and this proxy makes numerous calls to the JNI intermediary class which is declared in the unnamed package by default. +As Java does not support types declared in a named package accessing types declared in an unnamed package, the -package commandline option described earlier must be used to provide a parent package. +So if SWIG is run using the -package com.myco option, a wrapped class, MyWorld::Material::Color, can then be accessed as com.myco.MyWorld.Material.Color. If you don't specify a package, you will get the following error message: +

    + +
    +
    +example.i:16: Error: The nspace feature used on 'MyWorld::Material::Color' is not supported unless a package is specified
    +with -package - Java does not support types declared in a named package accessing types declared in an unnamed package.
    +
    +
    + +

    22.3.14 C++ templates

    @@ -1957,7 +1976,7 @@ Obviously, there is more to template wrapping than shown in this example. More details can be found in the SWIG and C++ chapter.

    -

    21.3.15 C++ Smart Pointers

    +

    22.3.15 C++ Smart Pointers

    @@ -2041,7 +2060,7 @@ Foo f = p.__deref__(); // Returns underlying Foo * -

    21.4 Further details on the generated Java classes

    +

    22.4 Further details on the generated Java classes

    @@ -2056,7 +2075,7 @@ Finally enum classes are covered. First, the crucial intermediary JNI class is considered.

    -

    21.4.1 The intermediary JNI class

    +

    22.4.1 The intermediary JNI class

    @@ -2143,7 +2162,7 @@ class exampleJNI {

    This class contains the complete Java - C/C++ interface so all function calls go via this class. -As this class acts as a go-between for all JNI calls to C/C++ code from the Java proxy classes, type wrapper classes and module class, it is known as the intermediary JNI class. +As this class acts as a go-between for all JNI calls to C/C++ code from the Java proxy classes, type wrapper classes and module class, it is known as the intermediary JNI class.

    @@ -2152,14 +2171,14 @@ This approach leads to minimal JNI code which makes for better performance as JN SWIG favours generating Java code over JNI code as Java code is compiled into byte code and avoids the costly string operations needed in JNI code. This approach has a downside though as the proxy class might get collected before the native method has completed. You might notice above that there is an additional parameters with a underscore postfix, eg jarg1_. -These are added in order to prevent premature garbage collection when marshalling proxy classes. +These are added in order to prevent premature garbage collection when marshalling proxy classes.

    The functions in the intermediary JNI class cannot be accessed outside of its package. Access to them is gained through the module class for globals otherwise the appropriate proxy class.

    - +

    The name of the intermediary JNI class can be changed from its default, that is, the module name with JNI appended after it. The module directive attribute jniclassname is used to achieve this: @@ -2176,7 +2195,7 @@ If name is the same as modulename then the module class name g from modulename to modulenameModule.

    -

    21.4.1.1 The intermediary JNI class pragmas

    +

    22.4.1.1 The intermediary JNI class pragmas

    @@ -2242,20 +2261,20 @@ The jniclasscode pragma is quite useful for adding in a static block fo

    Pragmas will take either "" or %{ %} as delimiters. -For example, let's change the intermediary JNI class access to public. +For example, let's change the intermediary JNI class access to just the default package-private access.

    -%pragma(java) jniclassclassmodifiers="public class"
    +%pragma(java) jniclassclassmodifiers="class"
     

    -All the methods in the intermediary JNI class will then be callable outside of the package as the method modifiers are public by default. +All the methods in the intermediary JNI class will then not be callable outside of the package as the method modifiers have been changed from public access to default access. This is useful if you want to prevent users calling these low level functions.

    -

    21.4.2 The Java module class

    +

    22.4.2 The Java module class

    @@ -2286,7 +2305,7 @@ example.egg(new Foo()); The primary reason for having the module class wrapping the calls in the intermediary JNI class is to implement static type checking. In this case only a Foo can be passed to the egg function, whereas any long can be passed to the egg function in the intermediary JNI class.

    -

    21.4.2.1 The Java module class pragmas

    +

    22.4.2.1 The Java module class pragmas

    @@ -2333,16 +2352,16 @@ The pragma code appears in the generated module class like this:

    -See The intermediary JNI class pragmas section for further details on using pragmas. +See The intermediary JNI class pragmas section for further details on using pragmas.

    -

    21.4.3 Java proxy classes

    +

    22.4.3 Java proxy classes

    A Java proxy class is generated for each structure, union or C++ class that is wrapped. -Proxy classes have also been called peer classes. +Proxy classes have also been called peer classes. The default proxy class for our previous example looks like this:

    @@ -2357,7 +2376,7 @@ public class Foo { swigCPtr = cPtr; } - protected static long getCPtr(Foo obj) { + public static long getCPtr(Foo obj) { return (obj == null) ? 0 : obj.swigCPtr; } @@ -2413,7 +2432,7 @@ int y = f.spam(5, new Foo()); -

    21.4.3.1 Memory management

    +

    22.4.3.1 Memory management

    @@ -2507,7 +2526,7 @@ you're lucky, you will only get a segmentation fault. To work around this, the ownership flag of o needs changing to false. The ownership flag is a private member variable of the proxy class so this is not possible without some customization of the proxy class. This can be achieved by using a typemap to customise the proxy class with pure Java code as detailed later in the section on -Java typemaps. +Java typemaps.

    @@ -2569,13 +2588,13 @@ Obj obj = Factory.createObj(); // obj.swigCMemOwn = true; Some memory management issues are quite tricky to fix and may only be noticeable after using for a long time. One such issue is premature garbage collection of an object created from Java and resultant usage from C++ code. The section on typemap examples cover two such scenarios, -Memory management for objects passed to the C++ layer +Memory management for objects passed to the C++ layer and -Memory management when returning references to member variables +Memory management when returning references to member variables

    -

    21.4.3.2 Inheritance

    +

    22.4.3.2 Inheritance

    @@ -2608,7 +2627,7 @@ public class Base { swigCPtr = cPtr; } - protected static long getCPtr(Base obj) { + public static long getCPtr(Base obj) { return (obj == null) ? 0 : obj.swigCPtr; } @@ -2648,7 +2667,7 @@ public class Derived extends Base { swigCPtr = cPtr; } - protected static long getCPtr(Derived obj) { + public static long getCPtr(Derived obj) { return (obj == null) ? 0 : obj.swigCPtr; } @@ -2687,11 +2706,11 @@ This is a necessity as C++ compilers are free to implement pointers in the inher It is of course possible to extend Base using your own Java classes. If Derived is provided by the C++ code, you could for example add in a pure Java class Extended derived from Base. There is a caveat and that is any C++ code will not know about your pure Java class Extended so this type of derivation is restricted. -However, true cross language polymorphism can be achieved using the directors feature. +However, true cross language polymorphism can be achieved using the directors feature.

    -

    21.4.3.3 Proxy classes and garbage collection

    +

    22.4.3.3 Proxy classes and garbage collection

    @@ -2740,7 +2759,7 @@ You can encourage the garbage collector to call the finalizers, for example, add }

    Although this usually works, the documentation doesn't guarantee that runFinalization() will actually call the finalizers. -As the the shutdown hook is guaranteed you could also make a JNI call to clean up any resources that are being tracked by the C/C++ code.

    +As the shutdown hook is guaranteed you could also make a JNI call to clean up any resources that are being tracked by the C/C++ code.

  • @@ -2765,7 +2784,7 @@ The SWIG generated code ensures that the memory is not deleted twice, in the eve

    Write your own object manager in Java. You could derive all SWIG classes from a single base class which could track which objects have had their finalizers run, then call the rest of them on program termination. -The section on Java typemaps details how to specify a pure Java base class. +The section on Java typemaps details how to specify a pure Java base class.

  • @@ -2774,7 +2793,7 @@ The section on Java typemaps details how to specify See the How to Handle Java Finalization's Memory-Retention Issues article for alternative approaches to managing memory by avoiding finalizers altogether.

    -

    21.4.3.4 The premature garbage collection prevention parameter for proxy class marshalling

    +

    22.4.3.4 The premature garbage collection prevention parameter for proxy class marshalling

    @@ -2883,7 +2902,7 @@ The implementation for this extra parameter generation requires the "jtype" type

    The additional parameter does impose a slight performance overhead and the parameter generation can be suppressed globally with the -nopgcpp commandline option. -More selective suppression is possible with the 'nopgcpp' attribute in the "jtype" Java typemap. +More selective suppression is possible with the 'nopgcpp' attribute in the "jtype" Java typemap. The attribute is a flag and so should be set to "1" to enable the suppression, or it can be omitted or set to "0" to disable. For example:

    @@ -2896,7 +2915,7 @@ For example: Compatibility note: The generation of this additional parameter did not occur in versions prior to SWIG-1.3.30.

    -

    21.4.3.5 Single threaded applications and thread safety

    +

    22.4.3.5 Single threaded applications and thread safety

    @@ -2927,7 +2946,7 @@ public class Test { swigCPtr = cPtr; } - protected static long getCPtr(Test obj) { + public static long getCPtr(Test obj) { return (obj == null) ? 0 : obj.swigCPtr; } @@ -2984,7 +3003,7 @@ for (int i=0; i<100000; i++) { -

    21.4.4 Type wrapper classes

    +

    22.4.4 Type wrapper classes

    @@ -3013,7 +3032,7 @@ public class SWIGTYPE_p_int { The methods do not have public access, so by default it is impossible to do anything with objects of this class other than pass them around. The methods in the class are part of the inner workings of SWIG. If you need to mess around with pointers you will have to use some typemaps specific to the Java module to achieve this. -The section on Java typemaps details how to modify the generated code. +The section on Java typemaps details how to modify the generated code.

    @@ -3071,16 +3090,16 @@ public static void spam(SWIGTYPE_p_int x, SWIGTYPE_p_int y, int z) { ... } -

    21.4.5 Enum classes

    +

    22.4.5 Enum classes

    SWIG can generate three types of enum classes. -The Enumerations section discussed these but omitted all the details. +The Enumerations section discussed these but omitted all the details. The following sub-sections detail the various types of enum classes that can be generated.

    -

    21.4.5.1 Typesafe enum classes

    +

    22.4.5.1 Typesafe enum classes

    @@ -3164,7 +3183,7 @@ The swigValue method is used for marshalling in the other direction. The toString method is overridden so that the enum name is available.

    -

    21.4.5.2 Proper Java enum classes

    +

    22.4.5.2 Proper Java enum classes

    @@ -3239,10 +3258,10 @@ The next variable is in the SwigNext inner class rather than i Marshalling between Java enums and the C/C++ enum integer value is handled via the swigToEnum and swigValue methods. All the constructors and methods in the Java enum are required just to handle C/C++ enums with initializers. These needn't be generated if the enum being wrapped does not have any initializers and the -Simpler Java enums for enums without initializers section describes how typemaps can be used to achieve this. +Simpler Java enums for enums without initializers section describes how typemaps can be used to achieve this.

    -

    21.4.5.3 Type unsafe enum classes

    +

    22.4.5.3 Type unsafe enum classes

    @@ -3273,7 +3292,7 @@ public final class Beverage { -

    21.5 Cross language polymorphism using directors

    +

    22.5 Cross language polymorphism using directors

    @@ -3295,7 +3314,7 @@ The upshot is that C++ classes can be extended in Java and from C++ these extens Neither C++ code nor Java code needs to know where a particular method is implemented: the combination of proxy classes, director classes, and C wrapper functions transparently takes care of all the cross-language method routing.

    -

    21.5.1 Enabling directors

    +

    22.5.1 Enabling directors

    @@ -3366,7 +3385,7 @@ public: -

    21.5.2 Director classes

    +

    22.5.2 Director classes

    @@ -3393,7 +3412,7 @@ If the correct implementation is in Java, the Java API is used to call the metho

    -

    21.5.3 Overhead and code bloat

    +

    22.5.3 Overhead and code bloat

    @@ -3411,7 +3430,7 @@ This situation can be optimized by selectively enabling director methods (using

    -

    21.5.4 Simple directors example

    +

    22.5.4 Simple directors example

    @@ -3476,7 +3495,7 @@ DirectorDerived::upcall_method() invoked. -

    21.5.5 Director threading issues

    +

    22.5.5 Director threading issues

    @@ -3496,7 +3515,7 @@ Macros can be defined on the commandline when compiling your C++ code, or altern -

    21.6 Accessing protected members

    +

    22.6 Accessing protected members

    @@ -3592,7 +3611,7 @@ class MyProtectedBase extends ProtectedBase -

    21.7 Common customization features

    +

    22.7 Common customization features

    @@ -3604,7 +3623,7 @@ be awkward. This section describes some common SWIG features that are used to improve the interface to existing C/C++ code.

    -

    21.7.1 C/C++ helper functions

    +

    22.7.1 C/C++ helper functions

    @@ -3670,7 +3689,7 @@ hard to implement. It is possible to improve on this using Java code, typemaps, customization features as covered in later sections, but sometimes helper functions are a quick and easy solution to difficult cases.

    -

    21.7.2 Class extension with %extend

    +

    22.7.2 Class extension with %extend

    @@ -3733,14 +3752,14 @@ Vector(2,3,4) in any way---the extensions only show up in the Java interface.

    -

    21.7.3 Exception handling with %exception and %javaexception

    +

    22.7.3 Exception handling with %exception and %javaexception

    If a C or C++ function throws an error, you may want to convert that error into a Java exception. To do this, you can use the %exception directive. The %exception directive simply lets you rewrite part of the generated wrapper code to include an error check. -It is detailed in full in the Exception handling with %exception section. +It is detailed in full in the Exception handling with %exception section.

    @@ -3810,7 +3829,7 @@ The $action is a SWIG special variable and is replaced by the C/C++ f The return $null; handles all native method return types, namely those that have a void return and those that do not. This is useful for typemaps that will be used in native method returning all return types. See the section on -Java special variables for further explanation. +Java special variables for further explanation.

    @@ -3883,16 +3902,16 @@ public class FooClass {

    The examples above first use the C JNI calling syntax then the C++ JNI calling syntax. The C++ calling syntax will not compile as C and also vice versa. -It is however possible to write JNI calls which will compile under both C and C++ and is covered in the Typemaps for both C and C++ compilation section. +It is however possible to write JNI calls which will compile under both C and C++ and is covered in the Typemaps for both C and C++ compilation section.

    The language-independent exception.i library file can also be used to raise exceptions. See the SWIG Library chapter. -The typemap example Handling C++ exception specifications as Java exceptions provides further exception handling capabilities. +The typemap example Handling C++ exception specifications as Java exceptions provides further exception handling capabilities.

    -

    21.7.4 Method access with %javamethodmodifiers

    +

    22.7.4 Method access with %javamethodmodifiers

    @@ -3918,7 +3937,7 @@ protected static void protect_me() { -

    21.8 Tips and techniques

    +

    22.8 Tips and techniques

    @@ -3928,7 +3947,7 @@ strings and arrays. This chapter discusses the common techniques for solving these problems.

    -

    21.8.1 Input and output parameters using primitive pointers and references

    +

    22.8.1 Input and output parameters using primitive pointers and references

    @@ -4102,7 +4121,7 @@ void foo(Bar *OUTPUT); will not have the intended effect since typemaps.i does not define an OUTPUT rule for Bar.

    -

    21.8.2 Simple pointers

    +

    22.8.2 Simple pointers

    @@ -4168,7 +4187,7 @@ System.out.println("3 + 4 = " + result); See the SWIG Library chapter for further details.

    -

    21.8.3 Wrapping C arrays with Java arrays

    +

    22.8.3 Wrapping C arrays with Java arrays

    @@ -4235,7 +4254,7 @@ Please be aware that the typemaps in this library are not efficient as all the e There is an alternative approach using the SWIG array library and this is covered in the next section.

    -

    21.8.4 Unbounded C Arrays

    +

    22.8.4 Unbounded C Arrays

    @@ -4380,7 +4399,7 @@ well suited for applications in which you need to create buffers, package binary data, etc.

    -

    21.8.5 Overriding new and delete to allocate from Java heap

    +

    22.8.5 Overriding new and delete to allocate from Java heap

    @@ -4497,13 +4516,13 @@ model and use these functions in place of malloc and free in your own code.

    -

    21.9 Java typemaps

    +

    22.9 Java typemaps

    This section describes how you can modify SWIG's default wrapping behavior for various C/C++ datatypes using the %typemap directive. -You are advised to be familiar with the the material in the "Typemaps" chapter. +You are advised to be familiar with the material in the "Typemaps" chapter. While not absolutely essential knowledge, this section assumes some familiarity with the Java Native Interface (JNI). JNI documentation can be consulted either online at Sun's Java web site or from a good JNI book. The following two books are recommended:

    @@ -4518,7 +4537,7 @@ Before proceeding, it should be stressed that typemaps are not a required part of using SWIG---the default wrapping behavior is enough in most cases. Typemaps are only used if you want to change some aspect of the generated code. -

    21.9.1 Default primitive type mappings

    +

    22.9.1 Default primitive type mappings

    @@ -4670,7 +4689,7 @@ However, the mappings allow the full range of values for each C type from Java.

    -

    21.9.2 Default typemaps for non-primitive types

    +

    22.9.2 Default typemaps for non-primitive types

    @@ -4685,7 +4704,7 @@ So in summary, the C/C++ pointer to non-primitive types is cast into the 64 bit The Java type is either the proxy class or type wrapper class.

    -

    21.9.3 Sixty four bit JVMs

    +

    22.9.3 Sixty four bit JVMs

    @@ -4698,7 +4717,7 @@ Unfortunately it won't of course hold true for JNI code.

    -

    21.9.4 What is a typemap?

    +

    22.9.4 What is a typemap?

    @@ -4821,7 +4840,7 @@ int c = example.count('e',"Hello World"); -

    21.9.5 Typemaps for mapping C/C++ types to Java types

    +

    22.9.5 Typemaps for mapping C/C++ types to Java types

    @@ -4875,7 +4894,7 @@ The most important of these implement the mapping of C/C++ types to Java types: These are Java code typemaps which transform the type used in the Java intermediary JNI class (as specified in the "jtype" typemap) to the Java type used in the Java module class, proxy classes and type wrapper classes (as specified in the "jstype" typemap). This typemap provides the conversion for the parameters in the director methods when calling up from C++ to Java. - See Director typemaps. + See Director typemaps. @@ -4884,7 +4903,7 @@ The most important of these implement the mapping of C/C++ types to Java types: These are Java code typemaps which transform the type used in the Java module class, proxy classes and type wrapper classes (as specified in the "jstype" typemap) to the type used in the Java intermediary JNI class (as specified in the "jtype" typemap). This typemap provides the conversion for the return type in the director methods when returning from the C++ to Java upcall. - See Director typemaps. + See Director typemaps. @@ -4892,7 +4911,7 @@ The most important of these implement the mapping of C/C++ types to Java types: Conversion from C++ type to jni type for director methods. These are C++ typemaps which convert the parameters used in the C++ director method to the appropriate JNI intermediary type. The conversion is done in JNI code prior to calling the Java function from the JNI code. - See Director typemaps. + See Director typemaps. @@ -4900,7 +4919,7 @@ The most important of these implement the mapping of C/C++ types to Java types: Conversion from jni type to C++ type for director methods. These are C++ typemaps which convert the JNI return type used in the C++ director method to the appropriate C++ return type. The conversion is done in JNI code after calling the Java function from the JNI code. - See Director typemaps. + See Director typemaps. @@ -4978,12 +4997,12 @@ SWIGEXPORT jlong JNICALL Java_exampleJNI_FooBar(JNIEnv *jenv, jclass jcls,

    If you are using gcc as your C compiler, you might get a "dereferencing type-punned pointer will break strict-aliasing rules" warning about this. -Please see Compiling a dynamic module to avoid runtime problems with these strict aliasing rules. +Please see Compiling a dynamic module to avoid runtime problems with these strict aliasing rules.

    The default code generated by SWIG for the Java module comes from the typemaps in the "java.swg" library file which implements the -Default primitive type mappings and +Default primitive type mappings and Default typemaps for non-primitive types covered earlier. There are other type mapping typemaps in the Java library. These are listed below: @@ -5081,7 +5100,7 @@ These are listed below: -

    21.9.6 Java typemap attributes

    +

    22.9.6 Java typemap attributes

    @@ -5091,7 +5110,7 @@ There are a few additional typemap attributes that the Java module supports.

    The first of these is the 'throws' attribute. The throws attribute is optional and specified after the typemap name and contains one or more comma separated classes for adding to the throws clause for any methods that use that typemap. -It is analogous to the %javaexception feature's throws attribute. +It is analogous to the %javaexception feature's throws attribute.

    @@ -5103,7 +5122,7 @@ It is analogous to the %javaexception feature'

    The attribute is necessary for supporting Java checked exceptions and can be added to just about any typemap. The list of typemaps include all the C/C++ (JNI) typemaps in the "Typemaps" chapter and the -Java specific typemaps listed in the previous section, barring +Java specific typemaps listed in the previous section, barring the "jni", "jtype" and "jstype" typemaps as they could never contain code to throw an exception.

    @@ -5111,23 +5130,23 @@ the "jni", "jtype" and "jstype" typemaps as they could never contain code to thr The throws clause is generated for the proxy method as well as the JNI method in the JNI intermediary class. If a method uses more than one typemap and each of those typemaps have classes specified in the throws clause, the union of the exception classes is added to the throws clause ensuring there are no duplicate classes. -See the NaN exception example for further usage. +See the NaN exception example for further usage.

    -The "jtype" typemap has the optional 'nopgcpp' attribute which can be used to suppress the generation of the premature garbage collection prevention parameter. +The "jtype" typemap has the optional 'nopgcpp' attribute which can be used to suppress the generation of the premature garbage collection prevention parameter.

    -The "javain" typemap has the optional 'pre', 'post' and 'pgcppname' attributes. These are used for generating code before and after the JNI call in the proxy class or module class. The 'pre' attribute contains code that is generated before the JNI call and the 'post' attribute contains code generated after the JNI call. The 'pgcppname' attribute is used to change the premature garbage collection prevention parameter name passed to the JNI function. This is sometimes needed when the 'pre' typemap creates a temporary variable which is then passed to the JNI function. +The "javain" typemap has the optional 'pre', 'post' and 'pgcppname' attributes. These are used for generating code before and after the JNI call in the proxy class or module class. The 'pre' attribute contains code that is generated before the JNI call and the 'post' attribute contains code generated after the JNI call. The 'pgcppname' attribute is used to change the premature garbage collection prevention parameter name passed to the JNI function. This is sometimes needed when the 'pre' typemap creates a temporary variable which is then passed to the JNI function.

    - -Note that when the 'pre' or 'post' attributes are specified and the associated type is used in a constructor, a constructor helper function is generated. This is necessary as the Java proxy constructor wrapper makes a call to a support constructor using a this call. In Java the this call must be the first statement in the constructor body. The constructor body thus calls the helper function and the helper function instead makes the JNI call, ensuring the 'pre' code is called before the JNI call is made. There is a Date marshalling example showing 'pre', 'post' and 'pgcppname' attributes in action. + +Note that when the 'pre' or 'post' attributes are specified and the associated type is used in a constructor, a constructor helper function is generated. This is necessary as the Java proxy constructor wrapper makes a call to a support constructor using a this call. In Java the this call must be the first statement in the constructor body. The constructor body thus calls the helper function and the helper function instead makes the JNI call, ensuring the 'pre' code is called before the JNI call is made. There is a Date marshalling example showing 'pre', 'post' and 'pgcppname' attributes in action.

    -

    21.9.7 Java special variables

    +

    22.9.7 Java special variables

    @@ -5150,6 +5169,14 @@ If the type does not have an associated proxy class, it expands to the type wrap SWIGTYPE_p_unsigned_short is generated when wrapping unsigned short *.

    +

    +$javaclazzname
    +This special variable works like $javaclassname, but expands the fully qualified C++ class into the package name, +if used by the nspace feature, and the proxy class name, mangled for use as a function name. +For example, Namespace1::Namespace2::Klass is expanded into Namespace1_Namespace2_Klass_. +This special variable is usually used for making calls to a function in the intermediary JNI class, as they are mangled with this prefix. +

    +

    $null
    Used in input typemaps to return early from JNI functions that have either void or a non-void return type. Example: @@ -5256,7 +5283,7 @@ can be wrapped with the Java equivalent, that is, static inner proxy classes.

    $jniinput, $javacall and $packagepath
    -These special variables are used in the directors typemaps. See Director specific typemaps for details. +These special variables are used in the directors typemaps. See Director specific typemaps for details.

    @@ -5267,10 +5294,10 @@ This special variable expands to the module name, as specified by %module $imclassname
    This special variable expands to the intermediary class name. Usually this is the same as '$moduleJNI', -unless the jniclassname attribute is specified in the %module directive. +unless the jniclassname attribute is specified in the %module directive.

    -

    21.9.8 Typemaps for both C and C++ compilation

    +

    22.9.8 Typemaps for both C and C++ compilation

    @@ -5307,7 +5334,7 @@ If you do not intend your code to be targeting both C and C++ then your typemaps

    -

    21.9.9 Java code typemaps

    +

    22.9.9 Java code typemaps

    @@ -5448,9 +5475,9 @@ The "javaimports" typemap is ignored if the enum class is wrapped by an inner Ja

    The defaults can be overridden to tailor these classes. -Here is an example which will change the getCPtr method and constructor from the default protected access to public access. -This has a practical application if you are invoking SWIG more than once and generating the wrapped classes into different packages in each invocation. -If the classes in one package are using the classes in another package, then these methods need to be public. +Here is an example which will change the getCPtr method and constructor from the default public access to protected access. +If the classes in one package are not using the classes in another package, then these methods need not be public and removing access to these low level implementation details, is a good thing. +If you are invoking SWIG more than once and generating the wrapped classes into different packages in each invocation, then you cannot do this as you will then have different packages.

    @@ -5459,12 +5486,12 @@ If the classes in one package are using the classes in another package, then the private long swigCPtr; protected boolean swigCMemOwn; - public $javaclassname(long cPtr, boolean cMemoryOwn) { + protected $javaclassname(long cPtr, boolean cMemoryOwn) { swigCMemOwn = cMemoryOwn; swigCPtr = cPtr; } - public static long getCPtr($javaclassname obj) { + protected static long getCPtr($javaclassname obj) { return (obj == null) ? 0 : obj.swigCPtr; } %} @@ -5472,12 +5499,19 @@ If the classes in one package are using the classes in another package, then the

    -The typemap code is the same that is in "java.swg", barring the two method modifiers. +The typemap code is the same that is in "java.swg", barring the last two method modifiers. Note that SWIGTYPE will target all proxy classes, but not the type wrapper classes. Also the above typemap is only used for proxy classes that are potential base classes. To target proxy classes that are derived from a wrapped class as well, the "javabody_derived" typemap should also be overridden. +There is a macro in java.swg that implements this and the above can instead be implemented using:

    +
    +
    +SWIG_JAVABODY_METHODS(protected, protected, SWIGTYPE)
    +
    +
    +

    For the typemap to be used in all type wrapper classes, all the different types that type wrapper classes could be used for should be targeted:

    @@ -5506,7 +5540,7 @@ For the typemap to be used in all type wrapper classes, all the different types Again this is the same that is in "java.swg", barring the method modifier for getCPtr.

    -

    21.9.10 Director specific typemaps

    +

    22.9.10 Director specific typemaps

    @@ -5532,7 +5566,7 @@ For example, integers are converted as follows:

    $input is the SWIG name of the JNI temporary variable passed to Java in the upcall. The descriptor="I" will put an I into the JNI field descriptor that identifies the Java method that will be called from C++. -For more about JNI field descriptors and their importance, refer to the JNI documentation mentioned earlier. +For more about JNI field descriptors and their importance, refer to the JNI documentation mentioned earlier. A typemap for C character strings is:

    @@ -5731,7 +5765,7 @@ The basic strategy here is to provide a default package typemap for the majority
    -

    21.10 Typemap Examples

    +

    22.10 Typemap Examples

    @@ -5741,11 +5775,11 @@ the SWIG library.

    -

    21.10.1 Simpler Java enums for enums without initializers

    +

    22.10.1 Simpler Java enums for enums without initializers

    -The default Proper Java enums approach to wrapping enums is somewhat verbose. +The default Proper Java enums approach to wrapping enums is somewhat verbose. This is to handle all possible C/C++ enums, in particular enums with initializers. The generated code can be simplified if the enum being wrapped does not have any initializers.

    @@ -5820,7 +5854,7 @@ This would be done by using the original versions of these typemaps in "enums.sw

    -

    21.10.2 Handling C++ exception specifications as Java exceptions

    +

    22.10.2 Handling C++ exception specifications as Java exceptions

    @@ -5888,7 +5922,7 @@ If, however, we wanted to throw a checked exception, say java.io.IOException

    -Note that this typemap uses the 'throws' typemap attribute to ensure a throws clause is generated. +Note that this typemap uses the 'throws' typemap attribute to ensure a throws clause is generated. The generated proxy method then specifies the checked exception by containing java.io.IOException in the throws clause:

    @@ -5945,7 +5979,7 @@ We could alternatively have used %rename to rename what() into

    -

    21.10.3 NaN Exception - exception handling for a particular type

    +

    22.10.3 NaN Exception - exception handling for a particular type

    @@ -6045,13 +6079,13 @@ public class example {

    -See the Date marshalling example for an example using further "javain" typemap attributes. +See the Date marshalling example for an example using further "javain" typemap attributes.

    If we decide that what we actually want is a checked exception instead of a runtime exception, we can change this easily enough. The proxy method that uses float as an input, must then add the exception class to the throws clause. -SWIG can handle this as it supports the 'throws' typemap attribute for specifying classes for the throws clause. +SWIG can handle this as it supports the 'throws' typemap attribute for specifying classes for the throws clause. Thus we can modify the pragma and the typemap for the throws clause:

    @@ -6100,7 +6134,7 @@ If we were a martyr to the JNI cause, we could replace the succinct code within If we had, we would have put it in the "in" typemap which, like all JNI and Java typemaps, also supports the 'throws' attribute.

    -

    21.10.4 Converting Java String arrays to char **

    +

    22.10.4 Converting Java String arrays to char **

    @@ -6244,7 +6278,7 @@ Lastly the "jni", "jtype" and "jstype" typemaps are also required to specify what Java types to use.

    -

    21.10.5 Expanding a Java object to multiple arguments

    +

    22.10.5 Expanding a Java object to multiple arguments

    @@ -6326,7 +6360,7 @@ example.foo(new String[]{"red", "green", "blue", "white"}); -

    21.10.6 Using typemaps to return arguments

    +

    22.10.6 Using typemaps to return arguments

    @@ -6444,7 +6478,7 @@ $ java runme 1 12.0 340.0 -

    21.10.7 Adding Java downcasts to polymorphic return types

    +

    22.10.7 Adding Java downcasts to polymorphic return types

    @@ -6650,7 +6684,7 @@ SWIG usually generates code which constructs the proxy classes using Java code a Note that the JNI code above uses a number of string lookups to call a constructor, whereas this would not occur using byte compiled Java code.

    -

    21.10.8 Adding an equals method to the Java classes

    +

    22.10.8 Adding an equals method to the Java classes

    @@ -6694,7 +6728,7 @@ System.out.println("foo1? " + foo1.equals(foo2)); -

    21.10.9 Void pointers and a common Java base class

    +

    22.10.9 Void pointers and a common Java base class

    @@ -6753,7 +6787,7 @@ This example contains some useful functionality which you may want in your code.

  • It also has a function which effectively implements a cast from the type of the proxy/type wrapper class to a void pointer. This is necessary for passing a proxy class or a type wrapper class to a function that takes a void pointer. -

    21.10.10 Struct pointer to pointer

    +

    22.10.10 Struct pointer to pointer

    @@ -6933,7 +6967,7 @@ The C functional interface has been completely morphed into an object-oriented i the Butler class would behave much like any pure Java class and feel more natural to Java users.

    -

    21.10.11 Memory management when returning references to member variables

    +

    22.10.11 Memory management when returning references to member variables

    @@ -7056,7 +7090,7 @@ public class Bike { Note the addReference call.

    -

    21.10.12 Memory management for objects passed to the C++ layer

    +

    22.10.12 Memory management for objects passed to the C++ layer

    @@ -7172,11 +7206,11 @@ The 'javacode' typemap simply adds in the specified code into the Java proxy cla -

    21.10.13 Date marshalling using the javain typemap and associated attributes

    +

    22.10.13 Date marshalling using the javain typemap and associated attributes

    -The NaN Exception example is a simple example of the "javain" typemap and its 'pre' attribute. +The NaN Exception example is a simple example of the "javain" typemap and its 'pre' attribute. This example demonstrates how a C++ date class, say CDate, can be mapped onto the standard Java date class, java.util.GregorianCalendar by using the 'pre', 'post' and 'pgcppname' attributes of the "javain" typemap. The idea is that the GregorianCalendar is used wherever the C++ API uses a CDate. @@ -7343,13 +7377,13 @@ A few things to note: more local variables with the same name would be generated.

  • The use of the "javain" typemap causes a constructor helper function (SwigConstructAction) to be generated. This allows Java code to be called before the JNI call and is required as the Java compiler won't compile code inserted before the 'this' call. -
  • The 'pgcppname' attribute is used to modify the object being passed as the premature garbage collection prevention parameter (the 2nd and 4th parameters in the JNI calls). +
  • The 'pgcppname' attribute is used to modify the object being passed as the premature garbage collection prevention parameter (the 2nd and 4th parameters in the JNI calls). -

    21.11 Living with Java Directors

    +

    22.11 Living with Java Directors

    @@ -7530,10 +7564,10 @@ public abstract class UserVisibleFoo extends Foo {

  • -

    21.12 Odds and ends

    +

    22.12 Odds and ends

    -

    21.12.1 JavaDoc comments

    +

    22.12.1 JavaDoc comments

    @@ -7589,7 +7623,7 @@ public class Barmy { -

    21.12.2 Functional interface without proxy classes

    +

    22.12.2 Functional interface without proxy classes

    @@ -7650,7 +7684,7 @@ All destructors have to be called manually for example the delete_Foo(foo) -

    21.12.3 Using your own JNI functions

    +

    22.12.3 Using your own JNI functions

    @@ -7700,7 +7734,7 @@ This directive is only really useful if you want to mix your own hand crafted JN

    -

    21.12.4 Performance concerns and hints

    +

    22.12.4 Performance concerns and hints

    @@ -7721,7 +7755,7 @@ However, you will have to be careful about memory management and make sure that This method normally calls the C++ destructor or free() for C code.

    -

    21.12.5 Debugging

    +

    22.12.5 Debugging

    @@ -7743,7 +7777,7 @@ The -verbose:jni and -verbose:gc are also useful options for monitoring code beh

    -

    21.13 Examples

    +

    22.13 Examples

    diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html index 833a38393..285192d5e 100644 --- a/Doc/Manual/Library.html +++ b/Doc/Manual/Library.html @@ -27,9 +27,10 @@

  • STL/C++ Library
  • Utility Libraries
      @@ -893,7 +894,7 @@ char *foo(); This will release the result if the appropriate target language support is available. SWIG provides the appropriate "newfree" typemap for char * so that the memory is released, however, you may need to provide your own "newfree" typemap for other types. -See Object ownership and %newobject for more details. +See Object ownership and %newobject for more details.

      8.3.4 cstring.i

      @@ -1383,6 +1384,7 @@ The following table shows which C++ classes are supported and the equivalent SWI std::set set std_set.i std::string string std_string.i std::vector vector std_vector.i + std::shared_ptr shared_ptr std_shared_ptr.i @@ -1392,7 +1394,7 @@ Please look for the library files in the appropriate language library directory.

      -

      8.4.1 std_string.i

      +

      8.4.1 std::string

      @@ -1476,16 +1478,11 @@ void foo(string s, const String &t); // std_string typemaps still applie -

      -Note: The std_string library is incompatible with Perl on some platforms. -We're looking into it. -

      - -

      8.4.2 std_vector.i

      +

      8.4.2 std::vector

      -The std_vector.i library provides support for the C++ vector class in the STL. +The std_vector.i library provides support for the C++ std::vector class in the STL. Using this library involves the use of the %template directive. All you need to do is to instantiate different versions of vector for the types that you want to use. For example:

      @@ -1660,11 +1657,6 @@ if you want to make their head explode. details and the public API exposed to the interpreter vary.

      -

      -Note: std_vector.i was written by Luigi "The Amazing" Ballabio. -

      - -

      8.4.3 STL exceptions

      @@ -1715,6 +1707,124 @@ The %exception directive can be used by placing the following code befo Any thrown STL exceptions will then be gracefully handled instead of causing a crash.

      +

      8.4.4 shared_ptr smart pointer

      + + +

      +Some target languages have support for handling the widely used boost::shared_ptr smart pointer. +This smart pointer is also available as std::tr1::shared_ptr before it becomes fully standardized as std::shared_ptr. +The boost_shared_ptr.i library provides support for boost::shared_ptr and std_shared_ptr.i provides support for std::shared_ptr, but if the following macro is defined as shown, it can be used for std::tr1::shared_ptr: +

      + +
      +
      +#define SWIG_SHARED_PTR_SUBNAMESPACE tr1
      +%include <std_shared_ptr.i>
      +
      +
      + +

      +You can only use one of these variants of shared_ptr in your interface file at a time. +and all three variants must be used in conjunction with the %shared_ptr(T) macro, +where T is the underlying pointer type equating to usage shared_ptr<T>. +The type T must be non-primitive. +A simple example demonstrates usage: +

      + +
      +
      +%module example
      +%include <boost_shared_ptr.i>
      +%shared_ptr(IntValue)
      +
      +%inline %{
      +#include <boost/shared_ptr.hpp>
      +
      +struct IntValue {
      +  int value;
      +  IntValue(int v) : value(v) {}
      +};
      +
      +static int extractValue(const IntValue &t) {
      +  return t.value;
      +}
      +
      +static int extractValueSmart(boost::shared_ptr<IntValue> t) {
      +  return t->value;
      +}
      +%}
      +
      +
      + +

      +Note that the %shared_ptr(IntValue) declaration occurs after the inclusion of the boost_shared_ptr.i +library which provides the macro and, very importantly, before any usage or declaration of the type, IntValue. +The %shared_ptr macro provides, a few things for handling this smart pointer, but mostly a number of +typemaps. These typemaps override the default typemaps so that the underlying proxy class is stored and passed around +as a pointer to a shared_ptr instead of a plain pointer to the underlying type. +This approach means that any instantiation of the type can be passed to methods taking the type by value, reference, pointer +or as a smart pointer. +The interested reader might want to look at the generated code, however, usage is simple and no different +handling is required from the target language. +For example, a simple use case of the above code from Java would be: +

      + +
      +
      +IntValue iv = new IntValue(1234);
      +int val1 = example.extractValue(iv);
      +int val2 = example.extractValueSmart(iv);
      +System.out.println(val1 + " " + val2);
      +
      +
      + +

      +This shared_ptr library works quite differently to SWIG's normal, but somewhat limited, +smart pointer handling. +The shared_ptr library does not generate extra wrappers, just for smart pointer handling, in addition to the proxy class. +The normal proxy class including inheritance relationships is generated as usual. +The only real change introduced by the %shared_ptr macro is that the proxy class stores a pointer to the shared_ptr instance instead of a raw pointer to the instance. +A proxy class derived from a base which is being wrapped with shared_ptr can and must be wrapped as a shared_ptr too. +In other words all classes in an inheritance hierarchy must all be used with the %shared_ptr macro. +For example the following code can be used with the base class shown earlier: +

      + +
      +
      +%shared_ptr(DerivedIntValue)
      +%inline %{
      +struct DerivedIntValue : IntValue {
      +  DerivedIntValue(int value) : IntValue(value) {}
      +  ...
      +};
      +%}
      +
      +
      + +

      +Note that if the %shared_ptr macro is omitted for any class in the inheritance hierarchy, it will +result in a C++ compiler error. +For example if the above %shared_ptr(DerivedIntValue) is omitted, the following is typical of the compiler error that will result: +

      + +
      +
      +example_wrap.cxx: In function 'void Java_exampleJNI_delete_1DerivedIntValue(JNIEnv*, _jclass*, jlong)':
      +example_wrap.cxx:3169: error: 'smartarg1' was not declared in this scope
      +
      +
      + +

      +A shared_ptr of the derived class can now be passed to a method where the base is expected in the target language, just as it can in C++: +

      + +
      +
      +DerivedIntValue div = new DerivedIntValue(5678);
      +int val3 = example.extractValue(div);
      +int val4 = example.extractValueSmart(div);
      +
      +

      8.5 Utility Libraries

      diff --git a/Doc/Manual/Lisp.html b/Doc/Manual/Lisp.html index 53cddab83..b9b5b6c1e 100644 --- a/Doc/Manual/Lisp.html +++ b/Doc/Manual/Lisp.html @@ -6,7 +6,7 @@ -

      22 SWIG and Common Lisp

      +

      23 SWIG and Common Lisp

        @@ -41,16 +41,16 @@ Lisp, Common Foreign Function Interface(CFFI), CLisp and UFFI foreign function interfaces.

        -

        22.1 Allegro Common Lisp

        +

        23.1 Allegro Common Lisp

        Allegro Common Lisp support in SWIG has been updated to include support for both C and C++. You can read about the interface - here + here

        -

        22.2 Common Foreign Function Interface(CFFI)

        +

        23.2 Common Foreign Function Interface(CFFI)

        @@ -77,7 +77,7 @@ swig -cffi -module module-name file-name files and the various things which you can do with them.

        -

        22.2.1 Additional Commandline Options

        +

        23.2.1 Additional Commandline Options

        @@ -96,14 +96,14 @@ swig -cffi -help -generate-typedef -If this option is given then defctype will be used to generate +If this option is given then defctype will be used to generate
        shortcuts according to the typedefs in the input. -[no]cwrap -Turn on or turn off generation of an intermediate C file when +Turn on or turn off generation of an intermediate C file when
        creating a C interface. By default this is only done for C++ code. @@ -118,7 +118,7 @@ swig -cffi -help -

        22.2.2 Generating CFFI bindings

        +

        23.2.2 Generating CFFI bindings

        As we mentioned earlier the ideal way to use SWIG is to use interface @@ -269,7 +269,7 @@ The generated SWIG Code will be: want to lispify the names, also, before we forget you want to export the generated lisp names. To do this, we will use the SWIG feature directive. + href="Customization.html#Customization_features">feature directive. Let's edit the interface file such that the C type "div_t*" is changed to Lisp type ":my-pointer", we lispify all names, export everything, and do some more stuff. @@ -392,7 +392,7 @@ The feature intern_function ensures that all C names are
      -

      22.2.3 Generating CFFI bindings for C++ code

      +

      23.2.3 Generating CFFI bindings for C++ code

      This feature to SWIG (for CFFI) is very new and still far from @@ -568,7 +568,7 @@ If you have any questions, suggestions, patches, etc., related to CFFI module feel free to contact us on the SWIG mailing list, and also please add a "[CFFI]" tag in the subject line. -

      22.2.4 Inserting user code into generated files

      +

      23.2.4 Inserting user code into generated files

      @@ -608,7 +608,7 @@ Note that the block %{ ... %} is effectively a shortcut for

      -

      22.3 CLISP

      +

      23.3 CLISP

      @@ -638,7 +638,7 @@ swig -clisp -module module-name file-name interface file for the CLISP module. The CLISP module tries to produce code which is both human readable and easily modifyable.

      -

      22.3.1 Additional Commandline Options

      +

      23.3.1 Additional Commandline Options

      @@ -671,7 +671,7 @@ and global variables will be created otherwise only definitions for
      -

      22.3.2 Details on CLISP bindings

      +

      23.3.2 Details on CLISP bindings

      @@ -795,7 +795,7 @@ struct bar { -

      22.4 UFFI

      +

      23.4 UFFI

      diff --git a/Doc/Manual/Lua.html b/Doc/Manual/Lua.html index b236ab9f7..c07fe66c8 100644 --- a/Doc/Manual/Lua.html +++ b/Doc/Manual/Lua.html @@ -6,7 +6,7 @@ -

      23 SWIG and Lua

      +

      24 SWIG and Lua

        @@ -67,13 +67,13 @@

        Lua is an extension programming language designed to support general procedural programming with data description facilities. It also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, light-weight configuration language for any program that needs one. Lua is implemented as a library, written in clean C (that is, in the common subset of ANSI C and C++). Its also a really tiny language, less than 6000 lines of code, which compiles to <100 kilobytes of binary code. It can be found at http://www.lua.org

        -

        23.1 Preliminaries

        +

        24.1 Preliminaries

        The current SWIG implementation is designed to work with Lua 5.0.x and Lua 5.1.x. It should work with later versions of Lua, but certainly not with Lua 4.0 due to substantial API changes. ((Currently SWIG generated code has only been tested on Windows with MingW, though given the nature of Lua, is should not have problems on other OS's)). It is possible to either static link or dynamic link a Lua module into the interpreter (normally Lua static links its libraries, as dynamic linking is not available on all platforms).

        -

        23.2 Running SWIG

        +

        24.2 Running SWIG

        @@ -105,7 +105,7 @@ This creates a C/C++ source file example_wrap.c or example_wrap.cxx

        The name of the wrapper file is derived from the name of the input file. For example, if the input file is example.i, the name of the wrapper file is example_wrap.c. To change this, you can use the -o option. The wrappered module will export one function "int luaopen_example(lua_State* L)" which must be called to register the module with the Lua interpreter. The name "luaopen_example" depends upon the name of the module.

        -

        23.2.1 Compiling and Linking and Interpreter

        +

        24.2.1 Compiling and Linking and Interpreter

        @@ -152,7 +152,7 @@ $ gcc -c example.c -o example.o $ gcc -I/usr/include/lua -L/usr/lib/lua min.o example_wrap.o example.o -o my_lua

      -

      23.2.2 Compiling a dynamic module

      +

      24.2.2 Compiling a dynamic module

      @@ -220,7 +220,7 @@ Is quite obvious (Go back and consult the Lua documents on how to enable loadlib -

      23.2.3 Using your module

      +

      24.2.3 Using your module

      @@ -238,19 +238,19 @@ $ ./my_lua > -

      23.3 A tour of basic C/C++ wrapping

      +

      24.3 A tour of basic C/C++ wrapping

      By default, SWIG tries to build a very natural Lua interface to your C/C++ code. This section briefly covers the essential aspects of this wrapping.

      -

      23.3.1 Modules

      +

      24.3.1 Modules

      The SWIG module directive specifies the name of the Lua module. If you specify `module example', then everything is wrapped into a Lua table 'example' containing all the functions and variables. When choosing a module name, make sure you don't use the same name as a built-in Lua command or standard module name.

      -

      23.3.2 Functions

      +

      24.3.2 Functions

      @@ -288,7 +288,7 @@ It is also possible to rename the module with an assignment. 24 -

      23.3.3 Global variables

      +

      24.3.3 Global variables

      @@ -334,7 +334,7 @@ extern double Foo; %mutable;

      -SWIG will allow the the reading of Foo but when a set attempt is made, an error function will be called. +SWIG will allow the reading of Foo but when a set attempt is made, an error function will be called.

       > print(e.Foo) -- reading works ok
      @@ -362,7 +362,7 @@ nil
       3.142
       
      -

      23.3.4 Constants and enums

      +

      24.3.4 Constants and enums

      @@ -385,7 +385,7 @@ example.SUNDAY=0

      Constants are not guaranteed to remain constant in Lua. The name of the constant could be accidentally reassigned to refer to some other object. Unfortunately, there is no easy way for SWIG to generate code that prevents this. You will just have to be careful.

      -

      23.3.5 Pointers

      +

      24.3.5 Pointers

      @@ -423,7 +423,7 @@ Lua enforces the integrity of its userdata, so it is virtually impossible to cor nil -

      23.3.6 Structures

      +

      24.3.6 Structures

      @@ -509,7 +509,7 @@ Because the pointer points inside the structure, you can modify the contents and > x.a = 3 -- Modifies the same structure -

      23.3.7 C++ classes

      +

      24.3.7 C++ classes

      @@ -570,7 +570,7 @@ It is not (currently) possible to access static members of an instance: -- does NOT work -

      23.3.8 C++ inheritance

      +

      24.3.8 C++ inheritance

      @@ -595,7 +595,7 @@ then the function spam() accepts a Foo pointer or a pointer to any clas

      It is safe to use multiple inheritance with SWIG.

      -

      23.3.9 Pointers, references, values, and arrays

      +

      24.3.9 Pointers, references, values, and arrays

      @@ -626,7 +626,7 @@ Foo spam7();

      then all three functions will return a pointer to some Foo object. Since the third function (spam7) returns a value, newly allocated memory is used to hold the result and a pointer is returned (Lua will release this memory when the return value is garbage collected). The other two are pointers which are assumed to be managed by the C code and so will not be garbage collected.

      -

      23.3.10 C++ overloaded functions

      +

      24.3.10 C++ overloaded functions

      @@ -712,7 +712,7 @@ Please refer to the "SWIG and C++" chapter for more information about overloadin

      Dealing with the Lua coercion mechanism, the priority is roughly (integers, floats, strings, userdata). But it is better to rename the functions rather than rely upon the ordering.

      -

      23.3.11 C++ operators

      +

      24.3.11 C++ operators

      @@ -824,7 +824,7 @@ It is also possible to overload the operator[], but currently this cann }; -

      23.3.12 Class extension with %extend

      +

      24.3.12 Class extension with %extend

      @@ -879,7 +879,7 @@ true

      Extend works with both C and C++ code, on classes and structs. It does not modify the underlying object in any way---the extensions only show up in the Lua interface. The only item to take note of is the code has to use the '$self' instead of 'this', and that you cannot access protected/private members of the code (as you are not officially part of the class).

      -

      23.3.13 C++ templates

      +

      24.3.13 C++ templates

      @@ -914,7 +914,7 @@ In Lua:

      Obviously, there is more to template wrapping than shown in this example. More details can be found in the SWIG and C++ chapter. Some more complicated examples will appear later.

      -

      23.3.14 C++ Smart Pointers

      +

      24.3.14 C++ Smart Pointers

      @@ -966,7 +966,7 @@ If you ever need to access the underlying pointer returned by operator->( > f = p:__deref__() -- Returns underlying Foo * -

      23.3.15 C++ Exceptions

      +

      24.3.15 C++ Exceptions

      @@ -1099,23 +1099,23 @@ userdata: 0003D880

      -Note: is is also possible (though tedious) to have a function throw several different kinds of exceptions. To process this +Note: it is also possible (though tedious) to have a function throw several different kinds of exceptions. To process this will require a pcall, followed by a set of if statements checking the type of the error.

      All of this code assumes that your C++ code uses exception specification (which a lot doesn't). If it doesn't consult the "Exception handling with %catches" section -and the "Exception handling with %exception" section, for more details on how to +and the "Exception handling with %exception" section, for more details on how to add exception specification to functions or globally (respectively).

      -

      23.4 Typemaps

      +

      24.4 Typemaps

      This section explains what typemaps are and the usage of them. The default wrappering behaviour of SWIG is enough in most cases. However sometimes SWIG may need a little additional assistance to know which typemap to apply to provide the best wrappering. This section will be explaining how to use typemaps to best effect

      -

      23.4.1 What is a typemap?

      +

      24.4.1 What is a typemap?

      A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from Lua to C, you might define a typemap like this:

      @@ -1143,7 +1143,7 @@ Received an integer : 6 720 -

      23.4.2 Using typemaps

      +

      24.4.2 Using typemaps

      There are many ready written typemaps built into SWIG for all common types (int, float, short, long, char*, enum and more), which SWIG uses automatically, with no effort required on your part.

      @@ -1196,7 +1196,7 @@ void swap(int *sx, int *sy);

      Note: C++ references must be handled exactly the same way. However SWIG will automatically wrap a const int& as an input parameter (since that it obviously input).

      -

      23.4.3 Typemaps and arrays

      +

      24.4.3 Typemaps and arrays

      Arrays present a challenge for SWIG, because like pointers SWIG does not know whether these are input or output values, nor @@ -1210,7 +1210,7 @@ extern void sort_double(double* arr, int len);

      There are basically two ways that SWIG can deal with this. The first way, uses the <carrays.i> library to create an array in C/C++ then this can be filled within Lua and passed into the function. It works, but its a bit tedious. -More details can be found in the carrays.i documention.

      +More details can be found in the carrays.i documention.

      The second and more intuitive way, would be to pass a Lua table directly into the function, and have SWIG automatically convert between Lua-table and C-array. Within the <typemaps.i> file there are typemaps ready written to perform this task. To use them is again a matter of using %appy in the correct manner.

      @@ -1260,7 +1260,7 @@ and Lua tables to be 1..N, (the indexing follows the norm for the language). In

      Note: SWIG also can support arrays of pointers in a similar manner.

      -

      23.4.4 Typemaps and pointer-pointer functions

      +

      24.4.4 Typemaps and pointer-pointer functions

      Several C++ libraries use a pointer-pointer functions to create its objects. These functions require a pointer to a pointer which is then filled with the pointer to the new object. Microsoft's COM and DirectX as well as many other libraries have this kind of function. An example is given below:

      @@ -1294,7 +1294,7 @@ int Create_Math(iMath** pptr); // its creator (assume it mallocs) ptr=nil -- the iMath* will be GC'ed as normal -

      23.5 Writing typemaps

      +

      24.5 Writing typemaps

      This section describes how you can modify SWIG's default wrapping behavior for various C/C++ datatypes using the %typemap directive. This is an advanced topic that assumes familiarity with the Lua C API as well as the material in the "Typemaps" chapter.

      @@ -1303,7 +1303,7 @@ ptr=nil -- the iMath* will be GC'ed as normal

      Before proceeding, you should read the previous section on using typemaps, as well as read the ready written typemaps found in luatypemaps.swg and typemaps.i. These are both well documented and fairly easy to read. You should not attempt to write your own typemaps until you have read and can understand both of these files (they may well also give you a idea to base your worn on).

      -

      23.5.1 Typemaps you can write

      +

      24.5.1 Typemaps you can write

      There are many different types of typemap that can be written, the full list can be found in the "Typemaps" chapter. However the following are the most commonly used ones.

      @@ -1316,7 +1316,7 @@ ptr=nil -- the iMath* will be GC'ed as normal (the syntax for the typecheck is different from the typemap, see typemaps for details).
    -

    23.5.2 SWIG's Lua-C API

    +

    24.5.2 SWIG's Lua-C API

    This section explains the SWIG specific Lua-C API. It does not cover the main Lua-C api, as this is well documented and not worth covering.

    @@ -1365,7 +1365,7 @@ This macro, when called within the context of a SWIG wrappered function, will di
    Similar to SWIG_fail_arg, except that it will display the swig_type_info information instead.
    -

    23.6 Customization of your Bindings

    +

    24.6 Customization of your Bindings

    @@ -1374,7 +1374,7 @@ This section covers adding of some small extra bits to your module to add the la -

    23.6.1 Writing your own custom wrappers

    +

    24.6.1 Writing your own custom wrappers

    @@ -1393,7 +1393,7 @@ int native_function(lua_State*L) // my native code The %native directive in the above example, tells SWIG that there is a function int native_function(lua_State*L); which is to be added into the module under the name 'my_func'. SWIG will not add any wrappering for this function, beyond adding it into the function table. How you write your code is entirely up to you.

    -

    23.6.2 Adding additional Lua code

    +

    24.6.2 Adding additional Lua code

    @@ -1431,7 +1431,7 @@ Good uses for this feature is adding of new code, or writing helper functions to See Examples/lua/arrays for an example of this code.

    -

    23.7 Details on the Lua binding

    +

    24.7 Details on the Lua binding

    @@ -1442,7 +1442,7 @@ See Examples/lua/arrays for an example of this code.

    -

    23.7.1 Binding global data into the module.

    +

    24.7.1 Binding global data into the module.

    @@ -1502,7 +1502,7 @@ end

    That way when you call 'a=example.Foo', the interpreter looks at the table 'example' sees that there is no field 'Foo' and calls __index. This will in turn check in '.get' table and find the existence of 'Foo' and then return the value of the C function call 'Foo_get()'. Similarly for the code 'example.Foo=10', the interpreter will check the table, then call the __newindex which will then check the '.set' table and call the C function 'Foo_set(10)'.

    -

    23.7.2 Userdata and Metatables

    +

    24.7.2 Userdata and Metatables

    @@ -1582,7 +1582,7 @@ Note: Both the opaque structures (like the FILE*) and normal wrappered classes/s

    Note: Operator overloads are basically done in the same way, by adding functions such as '__add' & '__call' to the classes metatable. The current implementation is a bit rough as it will add any member function beginning with '__' into the metatable too, assuming its an operator overload.

    -

    23.7.3 Memory management

    +

    24.7.3 Memory management

    diff --git a/Doc/Manual/Makefile b/Doc/Manual/Makefile index 4c907791b..69d361f07 100644 --- a/Doc/Manual/Makefile +++ b/Doc/Manual/Makefile @@ -9,6 +9,7 @@ # validation. # # Additional html validation can be done using the validate target. +# Additional link checking can be done using the linkchecker target. # # Note the # and " are escaped @@ -28,9 +29,9 @@ CCache.html: ../../CCache/ccache.yo # it is just used as a primitive HTML checker. # CCache.html is generated by yodl2html and has a few insignificant problems, so we don't put it through tidy check: - tidy -errors --gnu-emacs yes -quiet index.html - tidy -errors --gnu-emacs yes -quiet Sections.html - all=`sed '/^#/d' chapters | grep -v CCache.html`; for a in $$all; do tidy -errors --gnu-emacs yes -quiet $$a; done; + tidy -errors --gnu-emacs yes -quiet index.html + tidy -errors --gnu-emacs yes -quiet Sections.html + all=`sed '/^#/d' chapters | grep -v CCache.html`; for a in $$all; do tidy -errors --gnu-emacs yes -quiet $$a; done; generate: swightml.book swigpdf.book htmldoc --batch swightml.book || true @@ -49,7 +50,7 @@ swightml.book: echo "Sections.html" >> swightml.book cat chapters >> swightml.book -clean: clean-baks +maintainer-clean: clean-baks rm -f swightml.book rm -f swigpdf.book rm -f CCache.html @@ -60,11 +61,15 @@ clean-baks: rm -f *.bak test: - grep "href=\".*\.html\"" index.html - grep "href=\".*\.html\"" Sections.html - all=`sed '/^#/d' chapters`; for a in $$all; do grep -l "href=\".*\.html\"" $$a; done; + grep "href=\".*\.html\"" index.html + grep "href=\".*\.html\"" Sections.html + all=`sed '/^#/d' chapters`; for a in $$all; do grep -l "href=\".*\.html\"" $$a; done; # Validating using the WDG offline validator - http://www.htmlhelp.com/tools/validator/offline/ validate: - all=`sed '/^#/d' chapters`; for a in $$all; do validate --emacs $$a; done; + all=`sed '/^#/d' chapters`; for a in $$all; do validate --emacs $$a; done; + +# Link checking using linkchecker (can take a while - 30 mins) +linkchecker: + linkchecker --anchors Contents.html diff --git a/Doc/Manual/Modula3.html b/Doc/Manual/Modula3.html index c4e485202..71611e3c5 100644 --- a/Doc/Manual/Modula3.html +++ b/Doc/Manual/Modula3.html @@ -5,42 +5,39 @@ -

    24 SWIG and Modula-3

    +

    25 SWIG and Modula-3

    @@ -49,24 +46,29 @@

    This chapter describes SWIG's support of -Modula-3. +Modula-3. You should be familiar with the basics of SWIG, especially -typemaps. +typemaps.

    -

    24.1 Overview

    +

    25.1 Overview

    -The Modula-3 support is very basic and highly experimental! +Modula-3 is a compiled language in the tradition of Niklaus Wirth's Modula 2, +which is in turn a successor to Pascal. +

    + +

    +SWIG's Modula-3 support is currently very basic and highly experimental! Many features are still not designed satisfyingly and I need more discussion about the odds and ends. Don't rely on any feature, incompatible changes are likely in the future! -The Modula-3 generator was already useful for interfacing -to the libraries +However, the Modula-3 generator was already useful for interfacing +to the libraries:

      @@ -78,130 +80,34 @@ PLPlot
    1. FFTW - . +
    - -

    -I took some more time to explain -why I think it's right what I'm doing. -So the introduction got a bit longer than it should ... ;-) -

    - - -

    24.1.1 Why not scripting ?

    +

    25.1.1 Motivation

    -SWIG started as wrapper from the fast compiled languages C and C++ -to high level scripting languages like Python. -Although scripting languages are designed -to make programming life easier -by hiding machine internals from the programmer -there are several aspects of today's scripting languages -that are unfavourable in my opinion. +Although it is possible to write Modula-3 code that performs as well as C/C++ +most existing libraries are not written in Modula-3 but in C or C++, and +even libraries in other languages may provide C header files.

    -Besides C, C++, Cluster (a Modula derivate for Amiga computers) -I evaluated several scripting like languages in the past: -Different dialects of BASIC, -Perl, ARexx (a variant of Rexx for Amiga computers), -shell scripts. -I found them too inconsistent, -too weak in distinguishing types, -too weak in encapsulating pieces of code. -Eventually I have started several projects in Python -because of the fine syntax. -But when projects became larger -I lost the track. -I got convinced that one can not have -maintainable code in a language -that is not statically typed. -In fact the main advantages of scripting languages -e.g. matching regular expressions, -complex built-in datatypes like lists, dictionaries, -are not advantages of the language itself -but can be provided by function libraries. -

    - -

    24.1.2 Why Modula-3 ?

    - - -

    -Modula-3 is a compiler language -in the tradition of Niklaus Wirth's Modula 2, -which is in turn a successor of the popular Pascal. -I have chosen Modula-3 -because of its -logical syntax, -strong modularization, -the type system which is very detailed -for machine types compared to other languages. -Of course it supports all of the modern games -like exceptions, objects, garbage collection, threads. -While C++ programmers must -control three languages, -namely the preprocessor, C and ++, -Modula-3 is made in one go -and the language definition is really compact. +Fortunately Modula-3 can call C functions, but you have to write Modula-3 +interfaces to them, and to make things comfortable you will also need +wrappers that convert between high-level features of Modula-3 (garbage +collecting, exceptions) and the explicit tracking of allocated memory and +exception codes used by C APIs.

    -On the one hand Modula-3 can be safe -(but probably less efficient) in normal modules -while providing much static and dynamic safety. -On the other hand you can write efficient -but less safe code in the style of C -within UNSAFE modules. +SWIG converts C headers to Modula-3 interfaces for you, and using typemaps +you can pass TEXTs or open arrays, and convert error return codes +into exceptions.

    -Unfortunately Modula's safety and strength -requires more writing than scripting languages do. -Today if I want to safe characters -I prefer Haskell (similar to OCAML) - -it's statically typed, too. -

    - - -

    24.1.3 Why C / C++ ?

    - - -

    -Although it is no problem to write Modula-3 programs -that performs as fast as C -most libraries are not written in Modula-3 but in C. -Fortunately the binary interface of most function libraries -can be addressed by Modula-3. -Even more fortunately even non-C libraries may provide C header files. -This is where SWIG becomes helpful. -

    - -

    24.1.4 Why SWIG ?

    - - -

    -The C headers and the possibility to interface to C libraries -still leaves the work for you -to write Modula-3 interfaces to them. -To make things comfortable you will also need -wrappers that convert between high-level features of Modula-3 -(garbage collecting, exceptions) -and the low level of the C libraries. -

    - -

    -SWIG converts C headers to Modula-3 interfaces for you. -You could call the C functions without loss -of efficiency but it won't be joy -because you could not pass TEXTs -or open arrays and -you would have to process error return codes -rather then exceptions. -But using some typemaps SWIG will also generate -wrappers that bring the whole Modula-3 comfort to you. If the library API is ill designed writing appropriate typemaps can be still time-consuming. E.g. C programmers are very creative to work-around @@ -211,55 +117,28 @@ otherwise you lose static safety and consistency.

    - -But you have still a problem: -C library interfaces are often ill. -They lack for certain information -because C compilers wouldn't care about. -You should integrate detailed type information -by adding typedefs and consts -and you should persuade the C library programmer -to add this information to his interface. -Only this way other language users can benefit from your work -and only this way you can easily update your interfaces -when a new library version is released. - -You will realise that writing good SWIG interfaces -is very costly and it will only amortise -when considering evolving libraries. -

    - - -

    -Without SWIG you would probably never consider -to call C++ libraries from Modula-3. -But with SWIG this is worth a consideration. -SWIG can write C wrappers to C++ functions and object methods -that may throw exceptions. -In fact it breaks down C++ libraries to C interfaces -which can be in turn called from Modula-3. -To make it complete you can hide the C interface -with Modula-3 classes and exceptions. +Without SWIG you would probably never consider trying to call C++ libraries +from Modula-3, but with SWIG this is becomes feasible. +SWIG can generate C wrappers to C++ functions and object methods +that may throw exceptions, and then wrap these C wrappers for Module-3. +To make it complete you can then hide the C interface with Modula-3 classes and +exceptions.

    -Although SWIG does the best it can do -it can only serve as a one-way strategy. -That means you can use C++ libraries -with Modula-3 (even with call back functions), -but it's certainly not possible to smoothly -integrate Modula-3 code into a C / C++ project. +SWIG allows you to call C and C++ libraries from Modula-3 (even with call back +functions), but it doesn't allow you to easily integrate a Module-3 module into +a C/C++ project.

    - -

    24.2 Conception

    +

    25.2 Conception

    -

    24.2.1 Interfaces to C libraries

    +

    25.2.1 Interfaces to C libraries

    -Modula-3 has an integrated support for calling C functions. +Modula-3 has integrated support for calling C functions. This is also extensively used by the standard Modula-3 libraries to call OS functions. The Modula-3 part of SWIG and the corresponding SWIG library @@ -404,7 +283,7 @@ and the principal type must be renamed (%typemap).

    -

    24.2.2 Interfaces to C++ libraries

    +

    25.2.2 Interfaces to C++ libraries

    @@ -417,7 +296,7 @@ with a C interface.

    Here's a scheme of how the function calls to Modula-3 wrappers -a redirected to C library functions: +are redirected to C library functions:

    @@ -477,13 +356,13 @@ Is it possible to sub-class C++ classes with Modula-3 code? This issue is addressed by directors, a feature that was experimentally added to some Language modules like -Java and -Python. +Java and +Python.
  • How to manage storage with the garbage collector of Modula-3? Support for - + %newobject and %typemap(newfree) isn't implemented, yet. What's about resources that are managed by the garbage collector @@ -494,7 +373,7 @@ as far as I know.
  • How to turn C++ exceptions into Modula-3 exceptions? There's also no support for - + %exception, yet.
  • @@ -505,10 +384,10 @@ There is no C++ library I wrote a SWIG interface for, so I'm not sure if this is possible or sensible, yet.

    -

    24.3 Preliminaries

    +

    25.3 Preliminaries

    -

    24.3.1 Compilers

    +

    25.3.1 Compilers

    @@ -522,7 +401,7 @@ For testing examples I use Critical Mass cm3.

    -

    24.3.2 Additional Commandline Options

    +

    25.3.2 Additional Commandline Options

    @@ -599,10 +478,10 @@ Instead generate templates for some basic typemaps.

    -

    24.4 Modula-3 typemaps

    +

    25.4 Modula-3 typemaps

    -

    24.4.1 Inputs and outputs

    +

    25.4.1 Inputs and outputs

    @@ -818,7 +697,7 @@ consist of the following parts: -

    24.4.2 Subranges, Enumerations, Sets

    +

    25.4.2 Subranges, Enumerations, Sets

    @@ -870,7 +749,7 @@ that I'd like to automate.

    -

    24.4.3 Objects

    +

    25.4.3 Objects

    @@ -883,7 +762,7 @@ is not really useful, yet.

    -

    24.4.4 Imports

    +

    25.4.4 Imports

    @@ -918,7 +797,7 @@ IMPORT M3toC; -

    24.4.5 Exceptions

    +

    25.4.5 Exceptions

    @@ -942,7 +821,7 @@ you should declare %typemap("m3wrapinconv:throws") blah * %{OSError.E%}.

    -

    24.4.6 Example

    +

    25.4.6 Example

    @@ -989,10 +868,10 @@ where almost everything is generated by a typemap: -

    24.5 More hints to the generator

    +

    25.5 More hints to the generator

    -

    24.5.1 Features

    +

    25.5.1 Features

    @@ -1022,14 +901,14 @@ where almost everything is generated by a typemap: This is necessary in the cases where it was defined by a non-trivial C expression. This feature is used by the - -generateconstoption. + -generateconstoption. In future it may be generalized to other kind of values such as strings.
    -

    24.5.2 Pragmas

    +

    25.5.2 Pragmas

    @@ -1052,14 +931,14 @@ where almost everything is generated by a typemap:
    -

    24.6 Remarks

    +

    25.6 Remarks

    • The Modula-3 part of SWIG doesn't try to generate nicely formatted code. -Use m3pp to postprocess the Modula files, -it does a very good job here. +If you need to read the generated code, use m3pp to postprocess the +Modula files.
    diff --git a/Doc/Manual/Modules.html b/Doc/Manual/Modules.html index 406bdeaef..69cc58c30 100644 --- a/Doc/Manual/Modules.html +++ b/Doc/Manual/Modules.html @@ -13,7 +13,7 @@
  • Modules Introduction
  • Basics
  • The SWIG runtime code -
  • External access to the runtime +
  • External access to the runtime
  • A word of caution about static libraries
  • References
  • Reducing the wrapper file size @@ -29,7 +29,7 @@

    Each invocation of SWIG requires a module name to be specified. The module name is used to name the resulting target language extension module. -Exactly what this means and and what the name is used for +Exactly what this means and what the name is used for depends on the target language, for example the name can define a target language namespace or merely be a useful name for naming files or helper classes. Essentially, a module comprises target language wrappers for a chosen collection of global variables/functions, structs/classes and other C/C++ types. @@ -241,10 +241,10 @@ can peacefully coexist. So the type structures are separated by the is empty. Only modules compiled with the same pair will share type information.

    -

    15.4 External access to the runtime

    +

    15.4 External access to the runtime

    -

    As described in The run-time type checker, +

    As described in The run-time type checker, the functions SWIG_TypeQuery, SWIG_NewPointerObj, and others sometimes need to be called. Calling these functions from a typemap is supported, since the typemap code is embedded into the _wrap.c file, which has those declarations available. If you need diff --git a/Doc/Manual/Mzscheme.html b/Doc/Manual/Mzscheme.html index 9413bb010..4351e34a7 100644 --- a/Doc/Manual/Mzscheme.html +++ b/Doc/Manual/Mzscheme.html @@ -8,7 +8,7 @@ -

    25 SWIG and MzScheme

    +

    26 SWIG and MzScheme

      @@ -22,7 +22,7 @@

      This section contains information on SWIG's support of MzScheme. -

      25.1 Creating native MzScheme structures

      +

      26.1 Creating native MzScheme structures

      diff --git a/Doc/Manual/Ocaml.html b/Doc/Manual/Ocaml.html index b65831192..6cbfa5510 100644 --- a/Doc/Manual/Ocaml.html +++ b/Doc/Manual/Ocaml.html @@ -6,7 +6,7 @@ -

      26 SWIG and Ocaml

      +

      27 SWIG and Ocaml

        @@ -80,7 +80,7 @@ If you're not familiar with the Objective Caml language, you can visit The Ocaml Website.

        -

        26.1 Preliminaries

        +

        27.1 Preliminaries

        @@ -99,7 +99,7 @@ file Examples/Makefile illustrate how to compile and link SWIG modules that will be loaded dynamically. This has only been tested on Linux so far.

        -

        26.1.1 Running SWIG

        +

        27.1.1 Running SWIG

        @@ -122,7 +122,7 @@ you will compile the file example_wrap.c with ocamlc or the resulting .ml and .mli files as well, and do the final link with -custom (not needed for native link).

        -

        26.1.2 Compiling the code

        +

        27.1.2 Compiling the code

        @@ -158,7 +158,7 @@ the user more freedom with respect to custom typing.

      -

      26.1.3 The camlp4 module

      +

      27.1.3 The camlp4 module

      @@ -234,7 +234,7 @@ let b = C_string (getenv "PATH") -

      26.1.4 Using your module

      +

      27.1.4 Using your module

      @@ -248,7 +248,7 @@ When linking any ocaml bytecode with your module, use the -custom option is not needed when you build native code.

      -

      26.1.5 Compilation problems and compiling with C++

      +

      27.1.5 Compilation problems and compiling with C++

      @@ -259,7 +259,7 @@ liberal with pointer types may not compile under the C++ compiler. Most code meant to be compiled as C++ will not have problems.

      -

      26.2 The low-level Ocaml/C interface

      +

      27.2 The low-level Ocaml/C interface

      @@ -360,7 +360,7 @@ is that you must append them to the return list with swig_result = caml_list_a signature for a function that uses value in this way.

      -

      26.2.1 The generated module

      +

      27.2.1 The generated module

      @@ -394,7 +394,7 @@ it describes the output SWIG will generate for class definitions. -

      26.2.2 Enums

      +

      27.2.2 Enums

      @@ -457,7 +457,7 @@ val x : Enum_test.c_obj = C_enum `a

    -

    26.2.2.1 Enum typing in Ocaml

    +

    27.2.2.1 Enum typing in Ocaml

    @@ -470,10 +470,10 @@ functions imported from different modules. You must convert values to master values using the swig_val function before sharing them with another module.

    -

    26.2.3 Arrays

    +

    27.2.3 Arrays

    -

    26.2.3.1 Simple types of bounded arrays

    +

    27.2.3.1 Simple types of bounded arrays

    @@ -494,7 +494,7 @@ arrays of simple types with known bounds in your code, but this only works for arrays whose bounds are completely specified.

    -

    26.2.3.2 Complex and unbounded arrays

    +

    27.2.3.2 Complex and unbounded arrays

    @@ -507,7 +507,7 @@ SWIG can't predict which of these methods will be used in the array, so you have to specify it for yourself in the form of a typemap.

    -

    26.2.3.3 Using an object

    +

    27.2.3.3 Using an object

    @@ -521,7 +521,7 @@ Consider writing an object when the ending condition of your array is complex, such as using a required sentinel, etc.

    -

    26.2.3.4 Example typemap for a function taking float * and int

    +

    27.2.3.4 Example typemap for a function taking float * and int

    @@ -572,7 +572,7 @@ void printfloats( float *tab, int len ); -

    26.2.4 C++ Classes

    +

    27.2.4 C++ Classes

    @@ -615,7 +615,7 @@ the underlying pointer, so using create_[x]_from_ptr alters the returned value for the same object.

    -

    26.2.4.1 STL vector and string Example

    +

    27.2.4.1 STL vector and string Example

    @@ -695,7 +695,7 @@ baz # -

    26.2.4.2 C++ Class Example

    +

    27.2.4.2 C++ Class Example

    @@ -725,7 +725,7 @@ public: }; -

    26.2.4.3 Compiling the example

    +

    27.2.4.3 Compiling the example

    @@ -743,7 +743,7 @@ bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
       -L$QTPATH/lib -cclib -lqt
     
    -

    26.2.4.4 Sample Session

    +

    27.2.4.4 Sample Session

    @@ -770,10 +770,10 @@ Assuming you have a working installation of QT, you will see a window
     containing the string "hi" in a button.  
     

    -

    26.2.5 Director Classes

    +

    27.2.5 Director Classes

    -

    26.2.5.1 Director Introduction

    +

    27.2.5.1 Director Introduction

    @@ -800,7 +800,7 @@ class foo { };

    -

    26.2.5.2 Overriding Methods in Ocaml

    +

    27.2.5.2 Overriding Methods in Ocaml

    @@ -828,7 +828,7 @@ In this example, I'll examine the objective caml code involved in providing an overloaded class. This example is contained in Examples/ocaml/shapes.

    -

    26.2.5.3 Director Usage Example

    +

    27.2.5.3 Director Usage Example

    @@ -887,7 +887,7 @@ in a more effortless style in ocaml, while leaving the "engine" part of the program in C++.

    -

    26.2.5.4 Creating director objects

    +

    27.2.5.4 Creating director objects

    @@ -928,7 +928,7 @@ object from causing a core dump, as long as the object is destroyed properly.

    -

    26.2.5.5 Typemaps for directors, directorin, directorout, directorargout

    +

    27.2.5.5 Typemaps for directors, directorin, directorout, directorargout

    @@ -939,7 +939,7 @@ well as a function return value in the same way you provide function arguments, and to receive arguments the same way you normally receive function returns.

    -

    26.2.5.6 directorin typemap

    +

    27.2.5.6 directorin typemap

    @@ -950,7 +950,7 @@ code receives when you are called. In general, a simple directorin typ can use the same body as a simple out typemap.

    -

    26.2.5.7 directorout typemap

    +

    27.2.5.7 directorout typemap

    @@ -961,7 +961,7 @@ for the same type, except when there are special requirements for object ownership, etc.

    -

    26.2.5.8 directorargout typemap

    +

    27.2.5.8 directorargout typemap

    @@ -978,7 +978,7 @@ In the event that you don't specify all of the necessary values, integral values will read zero, and struct or object returns have undefined results.

    -

    26.2.6 Exceptions

    +

    27.2.6 Exceptions

    diff --git a/Doc/Manual/Octave.html b/Doc/Manual/Octave.html index 7409d78f1..be512f0ce 100644 --- a/Doc/Manual/Octave.html +++ b/Doc/Manual/Octave.html @@ -8,7 +8,7 @@ -

    27 SWIG and Octave

    +

    28 SWIG and Octave

      @@ -54,21 +54,22 @@ More information can be found at www.octave.org< Also, there are a dozen or so examples in the Examples/octave directory, and hundreds in the test suite (Examples/test-suite and Examples/test-suite/octave).

      -

      27.1 Preliminaries

      +

      28.1 Preliminaries

      -The current SWIG implemention is based on Octave 2.9.12. Support for other versions (in particular the recent 3.0) has not been tested, nor has support for any OS other than Linux. +The SWIG implemention was first based on Octave 2.9.12, so this is the minimum version required. Testing has only been done on Linux.

      -

      27.2 Running SWIG

      +

      28.2 Running SWIG

      -Let's start with a very simple SWIG interface file: +Let's start with a very simple SWIG interface file, example.i:

      -
      %module example
      +
      +%module example
       %{
       #include "example.h"
       %}
      @@ -76,20 +77,27 @@ int gcd(int x, int y);
       extern double Foo; 

      -To build an Octave module, run SWIG using the -octave option. The -c++ option is required (for now) as Octave itself is written in C++ and thus the wrapper code must also be. +To build an Octave module when wrapping C code, run SWIG using the -octave option:

      +
      $ swig -octave example.i 
      + +

      +The -c++ option is also required when wrapping C++ code: +

      + +
      $ swig -octave -c++ example.i 

      -This creates a C/C++ source file example_wrap.cxx. The generated C++ source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application (in this case, the gcd implementation) to create an extension module. +This creates a C++ source file example_wrap.cxx. A C++ file is generated even when wrapping C code as Octave is itself written in C++ and requires wrapper code to be in the same language. The generated C++ source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application (in this case, the gcd implementation) to create an extension module.

      The swig command line has a number of options you can use, like to redirect it's output. Use swig --help to learn about these.

      -

      27.2.1 Compiling a dynamic module

      +

      28.2.1 Compiling a dynamic module

      @@ -116,7 +124,7 @@ $ mkoctfile example_wrap.cxx example.c

      octave:1> example
      -

      27.2.2 Using your module

      +

      28.2.2 Using your module

      @@ -134,10 +142,10 @@ octave:4> example.cvar.Foo=4; octave:5> example.cvar.Foo ans = 4

      -

      27.3 A tour of basic C/C++ wrapping

      +

      28.3 A tour of basic C/C++ wrapping

      -

      27.3.1 Modules

      +

      28.3.1 Modules

      @@ -179,7 +187,7 @@ One can also rename it by simple assignment, e.g., octave:1> some_vars = cvar;

    -

    27.3.2 Functions

    +

    28.3.2 Functions

    @@ -196,7 +204,7 @@ int fact(int n);

    octave:1> example.fact(4)
     24 
    -

    27.3.3 Global variables

    +

    28.3.3 Global variables

    @@ -231,7 +239,7 @@ extern double Foo;

    - SWIG will allow the the reading of Foo but when a set attempt is made, an error function will be called. + SWIG will allow the reading of Foo but when a set attempt is made, an error function will be called.

    octave:1> example
    @@ -249,7 +257,7 @@ octave:2> example.PI=3.142;
     octave:3> example.PI
     ans =  3.1420 
    -

    27.3.4 Constants and enums

    +

    28.3.4 Constants and enums

    @@ -271,7 +279,7 @@ example.SCONST="Hello World" example.SUNDAY=0 .... -

    27.3.5 Pointers

    +

    28.3.5 Pointers

    @@ -318,7 +326,7 @@ octave:2> f=example.fopen("not there","r"); error: value on right hand side of assignment is undefined error: evaluating assignment expression near line 2, column 2 -

    27.3.6 Structures and C++ classes

    +

    28.3.6 Structures and C++ classes

    @@ -453,7 +461,7 @@ ans = 1 Depending on the ownership setting of a swig_ref, it may call C++ destructors when its reference count goes to zero. See the section on memory management below for details.

    -

    27.3.7 C++ inheritance

    +

    28.3.7 C++ inheritance

    @@ -462,7 +470,7 @@ This information contains the full class hierarchy. When an indexing operation ( the tree is walked to find a match in the current class as well as any of its bases. The lookup is then cached in the swig_ref.

    -

    27.3.8 C++ overloaded functions

    +

    28.3.8 C++ overloaded functions

    @@ -472,7 +480,7 @@ The dispatch function selects which overload to call (if any) based on the passe typecheck typemaps are used to analyze each argument, as well as assign precedence. See the chapter on typemaps for details.

    -

    27.3.9 C++ operators

    +

    28.3.9 C++ operators

    @@ -572,7 +580,7 @@ On the C++ side, the default mappings are as follows: %rename(__brace) *::operator[]; -

    27.3.10 Class extension with %extend

    +

    28.3.10 Class extension with %extend

    @@ -602,7 +610,7 @@ octave:3> printf("%s\n",a); octave:4> a.__str() 4 -

    27.3.11 C++ templates

    +

    28.3.11 C++ templates

    @@ -679,14 +687,14 @@ ans = -

    27.3.12 C++ Smart Pointers

    +

    28.3.12 C++ Smart Pointers

    C++ smart pointers are fully supported as in other modules.

    -

    27.3.13 Directors (calling Octave from C++ code)

    +

    28.3.13 Directors (calling Octave from C++ code)

    @@ -766,14 +774,14 @@ c-side routine called octave-side routine called -

    27.3.14 Threads

    +

    28.3.14 Threads

    The use of threads in wrapped Director code is not supported; i.e., an Octave-side implementation of a C++ class must be called from the Octave interpreter's thread. Anything fancier (apartment/queue model, whatever) is left to the user. Without anything fancier, this amounts to the limitation that Octave must drive the module... like, for example, an optimization package that calls Octave to evaluate an objective function.

    -

    27.3.15 Memory management

    +

    28.3.15 Memory management

    @@ -807,14 +815,14 @@ The %newobject directive may be used to control this behavior for pointers retur In the case where one wishes for the C++ side to own an object that was created in Octave (especially a Director object), one can use the __disown() method to invert this logic. Then letting the Octave reference count go to zero will not destroy the object, but destroying the object will invalidate the Octave-side object if it still exists (and call destructors of other C++ bases in the case of multiple inheritance/subclass()'ing).

    -

    27.3.16 STL support

    +

    28.3.16 STL support

    -This is some skeleton support for various STL containers. +Various STL library files are provided for wrapping STL containers.

    -

    27.3.17 Matrix typemaps

    +

    28.3.17 Matrix typemaps

    diff --git a/Doc/Manual/Perl5.html b/Doc/Manual/Perl5.html index 40500dc5a..0c2733c0e 100644 --- a/Doc/Manual/Perl5.html +++ b/Doc/Manual/Perl5.html @@ -6,7 +6,7 @@ -

    28 SWIG and Perl5

    +

    29 SWIG and Perl5

      @@ -87,7 +87,7 @@ later. Earlier versions are problematic and SWIG generated extensions may not compile or run correctly.

      -

      28.1 Overview

      +

      29.1 Overview

      @@ -108,7 +108,7 @@ described. Advanced customization features, typemaps, and other options are found near the end of the chapter.

      -

      28.2 Preliminaries

      +

      29.2 Preliminaries

      @@ -133,7 +133,7 @@ To build the module, you will need to compile the file example_wrap.c and link it with the rest of your program.

      -

      28.2.1 Getting the right header files

      +

      29.2.1 Getting the right header files

      @@ -165,7 +165,7 @@ loaded, an easy way to find out is to run Perl itself.

    -

    28.2.2 Compiling a dynamic module

    +

    29.2.2 Compiling a dynamic module

    @@ -198,7 +198,7 @@ the target should be named `example.so', `example.sl', or the appropriate dynamic module name on your system.

    -

    28.2.3 Building a dynamic module with MakeMaker

    +

    29.2.3 Building a dynamic module with MakeMaker

    @@ -232,7 +232,7 @@ the preferred approach to compilation. More information about MakeMaker can be found in "Programming Perl, 2nd ed." by Larry Wall, Tom Christiansen, and Randal Schwartz.

    -

    28.2.4 Building a static version of Perl

    +

    29.2.4 Building a static version of Perl

    @@ -301,7 +301,7 @@ added to it. Depending on your machine, you may need to link with additional libraries such as -lsocket, -lnsl, -ldl, etc.

    -

    28.2.5 Using the module

    +

    29.2.5 Using the module

    @@ -456,7 +456,7 @@ system configuration (this requires root access and you will need to read the man pages).

    -

    28.2.6 Compilation problems and compiling with C++

    +

    29.2.6 Compilation problems and compiling with C++

    @@ -599,7 +599,7 @@ have to find the macro that conflicts and add an #undef into the .i file. Pleas any conflicting macros you find to swig-user mailing list.

    -

    28.2.7 Compiling for 64-bit platforms

    +

    29.2.7 Compiling for 64-bit platforms

    @@ -626,7 +626,7 @@ also introduce problems on platforms that support more than one linking standard (e.g., -o32 and -n32 on Irix).

    -

    28.3 Building Perl Extensions under Windows

    +

    29.3 Building Perl Extensions under Windows

    @@ -637,7 +637,7 @@ section assumes you are using SWIG with Microsoft Visual C++ although the procedure may be similar with other compilers.

    -

    28.3.1 Running SWIG from Developer Studio

    +

    29.3.1 Running SWIG from Developer Studio

    @@ -700,7 +700,7 @@ print "$a\n"; -

    28.3.2 Using other compilers

    +

    29.3.2 Using other compilers

    @@ -708,7 +708,7 @@ SWIG is known to work with Cygwin and may work with other compilers on Windows. For general hints and suggestions refer to the Windows chapter.

    -

    28.4 The low-level interface

    +

    29.4 The low-level interface

    @@ -718,7 +718,7 @@ can be used to control your application. However, it is also used to construct more user-friendly proxy classes as described in the next section.

    -

    28.4.1 Functions

    +

    29.4.1 Functions

    @@ -741,7 +741,7 @@ use example; $a = &example::fact(2); -

    28.4.2 Global variables

    +

    29.4.2 Global variables

    @@ -811,7 +811,7 @@ extern char *path; // Declared later in the input -

    28.4.3 Constants

    +

    29.4.3 Constants

    @@ -851,7 +851,7 @@ print example::FOO,"\n"; -

    28.4.4 Pointers

    +

    29.4.4 Pointers

    @@ -960,7 +960,7 @@ as XS and xsubpp. Given the advancement of the SWIG typesystem and the SWIG and XS, this is no longer supported.

    -

    28.4.5 Structures

    +

    29.4.5 Structures

    @@ -1094,7 +1094,7 @@ void Bar_f_set(Bar *b, Foo *val) { -

    28.4.6 C++ classes

    +

    29.4.6 C++ classes

    @@ -1159,7 +1159,7 @@ provides direct access to C++ objects. A higher level interface using Perl prox can be built using these low-level accessors. This is described shortly.

    -

    28.4.7 C++ classes and type-checking

    +

    29.4.7 C++ classes and type-checking

    @@ -1195,7 +1195,7 @@ If necessary, the type-checker also adjusts the value of the pointer (as is nece multiple inheritance is used).

    -

    28.4.8 C++ overloaded functions

    +

    29.4.8 C++ overloaded functions

    @@ -1239,7 +1239,7 @@ example::Spam_foo_d($s,3.14); Please refer to the "SWIG Basics" chapter for more information.

    -

    28.4.9 Operators

    +

    29.4.9 Operators

    @@ -1266,7 +1266,7 @@ The following C++ operators are currently supported by the Perl module:

  • operator or
  • -

    28.4.10 Modules and packages

    +

    29.4.10 Modules and packages

    @@ -1361,7 +1361,7 @@ print Foo::fact(4),"\n"; # Call a function in package FooBar --> -

    28.5 Input and output parameters

    +

    29.5 Input and output parameters

    @@ -1580,7 +1580,7 @@ print "$c\n"; Note: The REFERENCE feature is only currently supported for numeric types (integers and floating point).

    -

    28.6 Exception handling

    +

    29.6 Exception handling

    @@ -1745,7 +1745,7 @@ This is still supported, but it is deprecated. The newer %exception di functionality, but it has additional capabilities that make it more powerful.

    -

    28.7 Remapping datatypes with typemaps

    +

    29.7 Remapping datatypes with typemaps

    @@ -1762,7 +1762,7 @@ Typemaps are only used if you want to change some aspect of the primitive C-Perl interface.

    -

    28.7.1 A simple typemap example

    +

    29.7.1 A simple typemap example

    @@ -1866,7 +1866,7 @@ example::count("e","Hello World"); -

    28.7.2 Perl5 typemaps

    +

    29.7.2 Perl5 typemaps

    @@ -1971,7 +1971,7 @@ Return of C++ member data (all languages). Check value of input parameter. -

    28.7.3 Typemap variables

    +

    29.7.3 Typemap variables

    @@ -2042,7 +2042,7 @@ properly assigned. The Perl name of the wrapper function being created. -

    28.7.4 Useful functions

    +

    29.7.4 Useful functions

    @@ -2111,7 +2111,7 @@ int sv_isa(SV *, char *0; -

    28.8 Typemap Examples

    +

    29.8 Typemap Examples

    @@ -2120,7 +2120,7 @@ might look at the files "perl5.swg" and "typemaps.i" in the SWIG library.

    -

    28.8.1 Converting a Perl5 array to a char **

    +

    29.8.1 Converting a Perl5 array to a char **

    @@ -2212,7 +2212,7 @@ print @$b,"\n"; # Print it out -

    28.8.2 Return values

    +

    29.8.2 Return values

    @@ -2241,7 +2241,7 @@ can be done using the EXTEND() macro as in : } -

    28.8.3 Returning values from arguments

    +

    29.8.3 Returning values from arguments

    @@ -2295,7 +2295,7 @@ print "multout(7,13) = @r\n"; ($x,$y) = multout(7,13); -

    28.8.4 Accessing array structure members

    +

    29.8.4 Accessing array structure members

    @@ -2358,7 +2358,7 @@ the "in" typemap in the previous section would be used to convert an to copy the converted array into a C data structure.

    -

    28.8.5 Turning Perl references into C pointers

    +

    29.8.5 Turning Perl references into C pointers

    @@ -2423,7 +2423,7 @@ print "$c\n"; -

    28.8.6 Pointer handling

    +

    29.8.6 Pointer handling

    @@ -2502,7 +2502,7 @@ For example: -

    28.9 Proxy classes

    +

    29.9 Proxy classes

    @@ -2518,7 +2518,7 @@ to the underlying code. This section describes the implementation details of the proxy interface.

    -

    28.9.1 Preliminaries

    +

    29.9.1 Preliminaries

    @@ -2540,7 +2540,7 @@ SWIG creates a collection of high-level Perl wrappers. In your scripts, you wil high level wrappers. The wrappers, in turn, interact with the low-level procedural module.

    -

    28.9.2 Structure and class wrappers

    +

    29.9.2 Structure and class wrappers

    @@ -2666,7 +2666,7 @@ $v->DESTROY(); -

    28.9.3 Object Ownership

    +

    29.9.3 Object Ownership

    @@ -2753,7 +2753,7 @@ counting, garbage collection, or advanced features one might find in sophisticated languages.

    -

    28.9.4 Nested Objects

    +

    29.9.4 Nested Objects

    @@ -2806,7 +2806,7 @@ $p->{f}->{x} = 0.0; %${$p->{v}} = ( x=>0, y=>0, z=>0); -

    28.9.5 Proxy Functions

    +

    29.9.5 Proxy Functions

    @@ -2840,7 +2840,7 @@ This function replaces the original function, but operates in an identical manner.

    -

    28.9.6 Inheritance

    +

    29.9.6 Inheritance

    @@ -2916,12 +2916,12 @@ particular, inheritance of data members is extremely tricky (and I'm not even sure if it really works).

    -

    28.9.7 Modifying the proxy methods

    +

    29.9.7 Modifying the proxy methods

    It is possible to override the SWIG generated proxy/shadow methods, using %feature("shadow"). -It works like all the other %feature directives. +It works like all the other %feature directives. Here is a simple example showing how to add some Perl debug code to the constructor:

    @@ -2944,7 +2944,7 @@ public: }; -

    28.10 Adding additional Perl code

    +

    29.10 Adding additional Perl code

    diff --git a/Doc/Manual/Php.html b/Doc/Manual/Php.html index b9dcb83c5..c9ee74f38 100644 --- a/Doc/Manual/Php.html +++ b/Doc/Manual/Php.html @@ -7,7 +7,7 @@ -

    29 SWIG and PHP

    +

    30 SWIG and PHP

      @@ -75,7 +75,7 @@ your extension into php directly, you will need the complete PHP source tree available.

      -

      29.1 Generating PHP Extensions

      +

      30.1 Generating PHP Extensions

      @@ -122,7 +122,7 @@ and it doesn't play nicely with package system. We don't recommend this approach, or provide explicit support for it.

      -

      29.1.1 Building a loadable extension

      +

      30.1.1 Building a loadable extension

      @@ -137,7 +137,7 @@ least work for Linux though): gcc -shared example_wrap.o -o example.so

    -

    29.1.2 Using PHP Extensions

    +

    30.1.2 Using PHP Extensions

    @@ -168,7 +168,7 @@ attempts to do the dl() call for you: include("example.php"); -

    29.2 Basic PHP interface

    +

    30.2 Basic PHP interface

    @@ -178,7 +178,7 @@ possible for names of symbols in one extension module to clash with other symbols unless care is taken to %rename them.

    -

    29.2.1 Constants

    +

    30.2.1 Constants

    @@ -303,7 +303,7 @@ both point to the same value, without the case test taking place. ( Apologies, this paragraph needs rewriting to make some sense. )

    -

    29.2.2 Global Variables

    +

    30.2.2 Global Variables

    @@ -352,7 +352,7 @@ undefined. At this time SWIG does not support custom accessor methods.

    -

    29.2.3 Functions

    +

    30.2.3 Functions

    @@ -405,7 +405,7 @@ print $s; # The value of $s was not changed. --> -

    29.2.4 Overloading

    +

    30.2.4 Overloading

    @@ -413,7 +413,7 @@ Although PHP does not support overloading functions natively, swig will generate dispatch functions which will use %typecheck typemaps to allow overloading. This dispatch function's operation and precedence is described in Wrapping +href="SWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions and Methods.

    @@ -461,7 +461,7 @@ taking the integer argument.

    --> -

    29.2.5 Pointers and References

    +

    30.2.5 Pointers and References

    @@ -593,7 +593,7 @@ PHP in a number of ways: by using unset on an existing variable, or assigning NULL to a variable.

    -

    29.2.6 Structures and C++ classes

    +

    30.2.6 Structures and C++ classes

    @@ -652,7 +652,7 @@ Would be used in the following way from PHP5: Member variables and methods are accessed using the -> operator.

    -

    29.2.6.1 Using -noproxy

    +

    30.2.6.1 Using -noproxy

    @@ -678,7 +678,7 @@ Complex_im_set($obj,$d); Complex_im_get($obj); -

    29.2.6.2 Constructors and Destructors

    +

    30.2.6.2 Constructors and Destructors

    @@ -719,7 +719,7 @@ the programmer can either reassign the variable or call unset($v)

    -

    29.2.6.3 Static Member Variables

    +

    30.2.6.3 Static Member Variables

    @@ -762,7 +762,7 @@ Ko::threats(10); echo "There has now been " . Ko::threats() . " threats\n"; -

    29.2.6.4 Static Member Functions

    +

    30.2.6.4 Static Member Functions

    @@ -784,7 +784,7 @@ Ko::threats(); -

    29.2.7 PHP Pragmas, Startup and Shutdown code

    +

    30.2.7 PHP Pragmas, Startup and Shutdown code

    @@ -857,7 +857,7 @@ either %init or %minit.

    To insert code into the PHP_MSHUTDOWN_FUNCTION, one can use -either %init or %minit. +either %shutdown or %mshutdown.

    @@ -868,11 +868,11 @@ either %init or %minit.
     

    -The %rinit and %rshutdown statements insert code -into the request init and shutdown code respectively. +The %rinit and %rshutdown statements are very similar but insert code +into the request init (PHP_RINIT_FUNCTION) and request shutdown (PHP_RSHUTDOWN_FUNCTION) code respectively.

    -

    29.3 Cross language polymorphism

    +

    30.3 Cross language polymorphism

    @@ -907,7 +907,7 @@ wrapper functions takes care of all the cross-language method routing transparently.

    -

    29.3.1 Enabling directors

    +

    30.3.1 Enabling directors

    @@ -999,7 +999,7 @@ class MyFoo extends Foo { -

    29.3.2 Director classes

    +

    30.3.2 Director classes

    @@ -1079,7 +1079,7 @@ so there is no need for the extra overhead involved with routing the calls through PHP.

    -

    29.3.3 Ownership and object destruction

    +

    30.3.3 Ownership and object destruction

    @@ -1135,7 +1135,7 @@ In this example, we are assuming that FooContainer will take care of deleting all the Foo pointers it contains at some point.

    -

    29.3.4 Exception unrolling

    +

    30.3.4 Exception unrolling

    @@ -1194,7 +1194,7 @@ Swig::DirectorMethodException is thrown, PHP will register the exception as soon as the C wrapper function returns.

    -

    29.3.5 Overhead and code bloat

    +

    30.3.5 Overhead and code bloat

    @@ -1227,7 +1227,7 @@ optimized by selectively enabling director methods (using the %feature directive) for only those methods that are likely to be extended in PHP.

    -

    29.3.6 Typemaps

    +

    30.3.6 Typemaps

    @@ -1241,7 +1241,7 @@ need to be supported.

    -

    29.3.7 Miscellaneous

    +

    30.3.7 Miscellaneous

    Director typemaps for STL classes are mostly in place, and hence you diff --git a/Doc/Manual/Pike.html b/Doc/Manual/Pike.html index a47d07865..8f9e43735 100644 --- a/Doc/Manual/Pike.html +++ b/Doc/Manual/Pike.html @@ -6,7 +6,7 @@ -

    30 SWIG and Pike

    +

    31 SWIG and Pike

      @@ -46,10 +46,10 @@ least, make sure you read the "SWIG Basics" chapter.

      -

      30.1 Preliminaries

      +

      31.1 Preliminaries

      -

      30.1.1 Running SWIG

      +

      31.1.1 Running SWIG

      @@ -94,7 +94,7 @@ can use the -o option:

      $ swig -pike -o pseudonym.c example.i
      -

      30.1.2 Getting the right header files

      +

      31.1.2 Getting the right header files

      @@ -114,7 +114,7 @@ You're looking for files with the names global.h, program.h and so on.

      -

      30.1.3 Using your module

      +

      31.1.3 Using your module

      @@ -129,10 +129,10 @@ Pike v7.4 release 10 running Hilfe v3.5 (Incremental Pike Frontend) (1) Result: 24

    -

    30.2 Basic C/C++ Mapping

    +

    31.2 Basic C/C++ Mapping

    -

    30.2.1 Modules

    +

    31.2.1 Modules

    @@ -143,7 +143,7 @@ concerned), SWIG's %module directive doesn't really have any significance.

    -

    30.2.2 Functions

    +

    31.2.2 Functions

    @@ -168,11 +168,11 @@ exactly as you'd expect it to: (1) Result: 24 -

    30.2.3 Global variables

    +

    31.2.3 Global variables

    -Global variables are currently wrapped as a pair of of functions, one to get +Global variables are currently wrapped as a pair of functions, one to get the current value of the variable and another to set it. For example, the declaration

    @@ -197,7 +197,7 @@ will result in two functions, Foo_get() and Foo_set(): (3) Result: 3.141590 -

    30.2.4 Constants and enumerated types

    +

    31.2.4 Constants and enumerated types

    @@ -205,7 +205,7 @@ Enumerated types in C/C++ declarations are wrapped as Pike constants, not as Pike enums.

    -

    30.2.5 Constructors and Destructors

    +

    31.2.5 Constructors and Destructors

    @@ -213,7 +213,7 @@ Constructors are wrapped as create() methods, and destructors are wrapped as destroy() methods, for Pike classes.

    -

    30.2.6 Static Members

    +

    31.2.6 Static Members

    diff --git a/Doc/Manual/Preface.html b/Doc/Manual/Preface.html index 630657a9a..2d0aa093e 100644 --- a/Doc/Manual/Preface.html +++ b/Doc/Manual/Preface.html @@ -11,13 +11,12 @@

    @@ -49,34 +48,22 @@ has since evolved into a general purpose tool that is used in a wide variety of applications--in fact almost anything where C/C++ programming is involved. -

    1.2 Special Introduction for Version 1.3

    +

    1.2 SWIG Versions

    -Since SWIG was released in 1996, its user base and applicability has -continued to grow. Although its rate of development has varied, an -active development effort has continued to make improvements to the -system. Today, nearly a dozen developers are working to create -SWIG-2.0---a system that aims to provide wrapping support for nearly -all of the ANSI C++ standard and approximately ten target languages -including Guile, Java, Mzscheme, Ocaml, Perl, Pike, PHP, Python, Ruby, -and Tcl. +In the late 1990's, the most stable version of SWIG was release +1.1p5. Versions 1.3.x were officially development versions and these were released +over a period of 10 years starting from the year 2000. The final version in the 1.3.x +series was 1.3.40, but in truth the 1.3.x series had been stable for many years. +An official stable version was released along with the decision to make SWIG +license changes and this gave rise to version 2.0.0 in 2010. The license was clarified +so that the code that SWIG generated could be distributed +under license terms of the user's choice/requirements and at the same time the SWIG +source was placed under the GNU General Public License version 3.

    -

    1.3 SWIG Versions

    - - -

    -For several years, the most stable version of SWIG has been release -1.1p5. Starting with version 1.3, a new version numbering scheme has -been adopted. Odd version numbers (1.3, 1.5, etc.) represent -development versions of SWIG. Even version numbers (1.4, 1.6, etc.) -represent stable releases. Currently, developers are working to -create a stable SWIG-2.0 release. Don't let the development status -of SWIG-1.3 scare you---it is much more stable (and capable) than SWIG-1.1p5. -

    - -

    1.4 SWIG resources

    +

    1.3 SWIG resources

    @@ -106,7 +93,7 @@ SWIG along with information about beta releases and future work.

    -SVN access to the latest version of SWIG is also available. More information +Subversion access to the latest version of SWIG is also available. More information about this can be obtained at:

    @@ -115,7 +102,7 @@ about this can be obtained at:
    -

    1.5 Prerequisites

    +

    1.4 Prerequisites

    @@ -132,7 +119,7 @@ writing a normal C program.

    -Recent SWIG releases have become significantly more capable in +Over time SWIG releases have become significantly more capable in their C++ handling--especially support for advanced features like namespaces, overloaded operators, and templates. Whenever possible, this manual tries to cover the technicalities of this interface. @@ -140,7 +127,7 @@ However, this isn't meant to be a tutorial on C++ programming. For many of the gory details, you will almost certainly want to consult a good C++ reference. If you don't program in C++, you may just want to skip those parts of the manual. -

    1.6 Organization of this manual

    +

    1.5 Organization of this manual

    @@ -149,11 +136,10 @@ provide an overview of its capabilities. The remaining chapters are devoted to specific SWIG language modules and are self contained. Thus, if you are using SWIG to build Python interfaces, you can probably skip to that chapter and find almost everything you need -to know. Caveat: we are currently working on a documentation rewrite and many -of the older language module chapters are still somewhat out of date. +to know.

    -

    1.7 How to avoid reading the manual

    +

    1.6 How to avoid reading the manual

    @@ -165,24 +151,19 @@ The SWIG distribution also comes with a large directory of examples that illustrate different topics.

    -

    1.8 Backwards Compatibility

    +

    1.7 Backwards compatibility

    -If you are a previous user of SWIG, don't expect recent versions of -SWIG to provide backwards compatibility. In fact, backwards -compatibility issues may arise even between successive 1.3.x releases. -Although these incompatibilities are regrettable, SWIG-1.3 is an active -development project. The primary goal of this effort is to make SWIG +If you are a previous user of SWIG, don't expect +SWIG to provide complete backwards compatibility. +Although the developers strive to the utmost to keep backwards compatibility, +this isn't always possible as the +primary goal over time is to make SWIG better---a process that would simply be impossible if the developers are constantly bogged down with backwards compatibility issues. -

    - -

    -On a positive note, a few incompatibilities are a small price to pay -for the large number of new features that have been -added---namespaces, templates, smart pointers, overloaded methods, -operators, and more. +Potential incompatibilities are clearly marked in the detailed release notes +(CHANGES files).

    @@ -206,33 +187,20 @@ Note: The version symbol is not defined in the generated SWIG wrapper file. The SWIG preprocessor has defined SWIG_VERSION since SWIG-1.3.11.

    -

    1.9 Credits

    +

    1.8 Credits

    SWIG is an unfunded project that would not be possible without the -contributions of many people. Most recent SWIG development has been -supported by Matthias Köppe, William Fulton, Lyle Johnson, -Richard Palmer, Thien-Thi Nguyen, Jason Stewart, Loic Dachary, Masaki -Fukushima, Luigi Ballabio, Sam Liddicott, Art Yerkes, Marcelo Matus, -Harco de Hilster, John Lenz, and Surendra Singhi. +contributions of many people working in their spare time. +If you have benefitted from using SWIG, please consider +Donating to SWIG to keep development going. +There have been a large varied number of people +who have made contributions at all levels over time. Contributors +are mentioned either in the COPYRIGHT file or CHANGES files shipped with SWIG or in submitted bugs.

    -

    -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. - -

    1.10 Bug reports

    +

    1.9 Bug reports

    diff --git a/Doc/Manual/Preprocessor.html b/Doc/Manual/Preprocessor.html index 2dd79dac5..8d41efccf 100644 --- a/Doc/Manual/Preprocessor.html +++ b/Doc/Manual/Preprocessor.html @@ -81,7 +81,7 @@ Such information generally includes type declarations (e.g., typedef) a C++ classes that might be used as base-classes for class declarations in the interface. The use of %import is also important when SWIG is used to generate extensions as a collection of related modules. This is an advanced topic and is described -in later in the Working with Modules chapter. +in later in the Working with Modules chapter.

    @@ -102,7 +102,7 @@ by SWIG when it is parsing the interface:

     SWIG                            Always defined when SWIG is processing a file
     SWIGIMPORTED                    Defined when SWIG is importing a file with %import
    -SWIG_VERSION                    Hexadecimal number containing SWIG version,
    +SWIG_VERSION                    Hexadecimal (binary-coded decimal) number containing SWIG version,
                                     such as 0x010311 (corresponding to SWIG-1.3.11).
     
     SWIGALLEGROCL                   Defined when using Allegro CL
    @@ -377,7 +377,7 @@ SWIG will strip the extra % and leave the preprocessor directive in the
     
     
     

    -Typemaps support a special attribute called noblock where the { ... } delimiters can be used, +Typemaps support a special attribute called noblock where the { ... } delimiters can be used, but the delimiters are not actually generated into the code. The effect is then similar to using "" or %{ %} delimiters but the code is run through the preprocessor. For example:

    diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index b22a7e30e..23271e649 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -6,7 +6,7 @@ -

    31 SWIG and Python

    +

    32 SWIG and Python

      @@ -128,7 +128,7 @@ very least, make sure you read the "SWIG Basics" chapter.

      -

      31.1 Overview

      +

      32.1 Overview

      @@ -155,10 +155,10 @@ described followed by a discussion of low-level implementation details.

      -

      31.2 Preliminaries

      +

      32.2 Preliminaries

      -

      31.2.1 Running SWIG

      +

      32.2.1 Running SWIG

      @@ -256,7 +256,7 @@ The following sections have further practical examples and details on how you might go about compiling and using the generated files.

      -

      31.2.2 Using distutils

      +

      32.2.2 Using distutils

      @@ -348,7 +348,7 @@ This same approach works on all platforms if the appropriate compiler is install can even build extensions to the standard Windows Python using MingGW)

      -

      31.2.3 Hand compiling a dynamic module

      +

      32.2.3 Hand compiling a dynamic module

      @@ -396,7 +396,7 @@ module actually consists of two files; socket.py and

      -

      31.2.4 Static linking

      +

      32.2.4 Static linking

      @@ -475,7 +475,7 @@ If using static linking, you might want to rely on a different approach (perhaps using distutils).

      -

      31.2.5 Using your module

      +

      32.2.5 Using your module

      @@ -632,7 +632,7 @@ system configuration (this requires root access and you will need to read the man pages).

      -

      31.2.6 Compilation of C++ extensions

      +

      32.2.6 Compilation of C++ extensions

      @@ -724,7 +724,7 @@ erratic program behavior. If working with lots of software components, you might want to investigate using a more formal standard such as COM.

      -

      31.2.7 Compiling for 64-bit platforms

      +

      32.2.7 Compiling for 64-bit platforms

      @@ -761,7 +761,7 @@ and -m64 allow you to choose the desired binary format for your python extension.

      -

      31.2.8 Building Python Extensions under Windows

      +

      32.2.8 Building Python Extensions under Windows

      @@ -870,7 +870,7 @@ SWIG Wiki.

      -

      31.3 A tour of basic C/C++ wrapping

      +

      32.3 A tour of basic C/C++ wrapping

      @@ -879,7 +879,7 @@ to your C/C++ code. Functions are wrapped as functions, classes are wrapped as This section briefly covers the essential aspects of this wrapping.

      -

      31.3.1 Modules

      +

      32.3.1 Modules

      @@ -892,7 +892,7 @@ module name, make sure you don't use the same name as a built-in Python command or standard module name.

      -

      31.3.2 Functions

      +

      32.3.2 Functions

      @@ -916,7 +916,7 @@ like you think it does: >>>

    -

    31.3.3 Global variables

    +

    32.3.3 Global variables

    @@ -1054,7 +1054,7 @@ that starts with a leading underscore. SWIG does not create cvar if there are no global variables in a module.

    -

    31.3.4 Constants and enums

    +

    32.3.4 Constants and enums

    @@ -1094,7 +1094,7 @@ other object. Unfortunately, there is no easy way for SWIG to generate code that prevents this. You will just have to be careful.

    -

    31.3.5 Pointers

    +

    32.3.5 Pointers

    @@ -1235,7 +1235,7 @@ C-style cast may return a bogus result whereas as the C++-style cast will return None if the conversion can't be performed.

    -

    31.3.6 Structures

    +

    32.3.6 Structures

    @@ -1282,7 +1282,7 @@ something like this:

    This object is actually a Python instance that has been wrapped around a pointer to the low-level C structure. This instance doesn't actually do anything--it just serves as a proxy. -The pointer to the C object can be found in the the .this +The pointer to the C object can be found in the .this attribute. For example:

    @@ -1424,7 +1424,7 @@ everything works just like you would expect. For example: -

    31.3.7 C++ classes

    +

    32.3.7 C++ classes

    @@ -1513,7 +1513,7 @@ they are accessed through cvar like this: -

    31.3.8 C++ inheritance

    +

    32.3.8 C++ inheritance

    @@ -1568,7 +1568,7 @@ then the function spam() accepts Foo * or a pointer to any cla It is safe to use multiple inheritance with SWIG.

    -

    31.3.9 Pointers, references, values, and arrays

    +

    32.3.9 Pointers, references, values, and arrays

    @@ -1629,7 +1629,7 @@ treated as a returning value, and it will follow the same allocation/deallocation process.

    -

    31.3.10 C++ overloaded functions

    +

    32.3.10 C++ overloaded functions

    @@ -1752,7 +1752,7 @@ first declaration takes precedence. Please refer to the "SWIG and C++" chapter for more information about overloading.

    -

    31.3.11 C++ operators

    +

    32.3.11 C++ operators

    @@ -1841,7 +1841,7 @@ Also, be aware that certain operators don't map cleanly to Python. For instance overloaded assignment operators don't map to Python semantics and will be ignored.

    -

    31.3.12 C++ namespaces

    +

    32.3.12 C++ namespaces

    @@ -1908,7 +1908,7 @@ utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve.

    -

    31.3.13 C++ templates

    +

    32.3.13 C++ templates

    @@ -1962,7 +1962,7 @@ Some more complicated examples will appear later.

    -

    31.3.14 C++ Smart Pointers

    +

    32.3.14 C++ Smart Pointers

    @@ -2047,7 +2047,7 @@ simply use the __deref__() method. For example: -

    31.3.15 C++ Reference Counted Objects (ref/unref)

    +

    32.3.15 C++ Reference Counted Objects (ref/unref)

    @@ -2124,8 +2124,8 @@ Object 'RCObj', which implements the ref/unref idiom.

    To tell SWIG that 'RCObj' and all its derived classes are reference -counted objects, you use the "ref" and "unref" features, or -%ref and %unref directives (since 1.3.28). For example: +counted objects, you use the "ref" and "unref" features. +For example:

    @@ -2143,25 +2143,6 @@ counted objects, you use the "ref" and "unref" features, or -or, using the directive form: - - -
    -
    -%module example
    -...
    -
    -%ref   RCObj "$this->ref();"
    -%unref RCObj "$this->unref();"
    -
    -%include "rcobj.h"
    -%include "A.h"
    -...
    -
    -
    - - -

    where the code passed to the "ref" and "unref" features will be executed as needed whenever a new object is passed to python, or when @@ -2209,7 +2190,7 @@ python releases the proxy instance.

    -

    31.4 Further details on the Python class interface

    +

    32.4 Further details on the Python class interface

    @@ -2222,7 +2203,7 @@ of low-level details were omitted. This section provides a brief overview of how the proxy classes work.

    -

    31.4.1 Proxy classes

    +

    32.4.1 Proxy classes

    @@ -2311,7 +2292,7 @@ you can attach new Python methods to the class and you can even inherit from it by Python built-in types until Python 2.2).

    -

    31.4.2 Memory management

    +

    32.4.2 Memory management

    @@ -2503,7 +2484,7 @@ It is also possible to deal with situations like this using typemaps--an advanced topic discussed later.

    -

    31.4.3 Python 2.2 and classic classes

    +

    32.4.3 Python 2.2 and classic classes

    @@ -2513,7 +2494,7 @@ in Python-2.2, an entirely new type of class system was introduced. This new-style class system offers many enhancements including static member functions, properties (managed attributes), and class methods. Details about all of these changes can be found on www.python.org and is not repeated here. +href="http://www.python.org">www.python.org and is not repeated here.

    @@ -2540,7 +2521,7 @@ class itself. In Python-2.1 and earlier, they have to be accessed as a global function or through an instance (see the earlier section).

    -

    31.5 Cross language polymorphism

    +

    32.5 Cross language polymorphism

    @@ -2574,7 +2555,7 @@ proxy classes, director classes, and C wrapper functions takes care of all the cross-language method routing transparently.

    -

    31.5.1 Enabling directors

    +

    32.5.1 Enabling directors

    @@ -2667,7 +2648,7 @@ class MyFoo(mymodule.Foo): -

    31.5.2 Director classes

    +

    32.5.2 Director classes

    @@ -2749,7 +2730,7 @@ so there is no need for the extra overhead involved with routing the calls through Python.

    -

    31.5.3 Ownership and object destruction

    +

    32.5.3 Ownership and object destruction

    @@ -2801,12 +2782,12 @@ public:

     >>> c = FooContainer()
    ->>> a = Foo().__disown()__
    +>>> a = Foo().__disown__()
     >>> c.addFoo(a)
     >>> b = Foo()
    ->>> b = b.__disown()__
    +>>> b = b.__disown__()
     >>> c.addFoo(b)
    ->>> c.addFoo(Foo().__disown()__)
    +>>> c.addFoo(Foo().__disown__())
     
    @@ -2816,7 +2797,7 @@ deleting all the Foo pointers it contains at some point. Note that no hard references to the Foo objects remain in Python.

    -

    31.5.4 Exception unrolling

    +

    32.5.4 Exception unrolling

    @@ -2875,7 +2856,7 @@ Swig::DirectorMethodException is thrown, Python will register the exception as soon as the C wrapper function returns.

    -

    31.5.5 Overhead and code bloat

    +

    32.5.5 Overhead and code bloat

    @@ -2909,7 +2890,7 @@ directive) for only those methods that are likely to be extended in Python.

    -

    31.5.6 Typemaps

    +

    32.5.6 Typemaps

    @@ -2923,7 +2904,7 @@ need to be supported.

    -

    31.5.7 Miscellaneous

    +

    32.5.7 Miscellaneous

    @@ -2970,7 +2951,7 @@ methods that return const references.

    -

    31.6 Common customization features

    +

    32.6 Common customization features

    @@ -2983,7 +2964,7 @@ This section describes some common SWIG features that are used to improve your the interface to an extension module.

    -

    31.6.1 C/C++ helper functions

    +

    32.6.1 C/C++ helper functions

    @@ -3064,7 +3045,7 @@ hard to implement. It is possible to clean this up using Python code, typemaps, customization features as covered in later sections.

    -

    31.6.2 Adding additional Python code

    +

    32.6.2 Adding additional Python code

    @@ -3120,7 +3101,7 @@ customization features.

    Sometimes you may want to replace or modify the wrapper function that SWIG creates in the proxy .py file. The Python module -in SWIG provides some features that enable you do do this. First, to +in SWIG provides some features that enable you to do this. First, to entirely replace a proxy function you can use %feature("shadow"). For example:

    @@ -3213,7 +3194,7 @@ public: -

    31.6.3 Class extension with %extend

    +

    32.6.3 Class extension with %extend

    @@ -3302,7 +3283,7 @@ Vector(12,14,16) in any way---the extensions only show up in the Python interface.

    -

    31.6.4 Exception handling with %exception

    +

    32.6.4 Exception handling with %exception

    @@ -3428,7 +3409,7 @@ The language-independent exception.i library file can also be used to raise exceptions. See the SWIG Library chapter.

    -

    31.7 Tips and techniques

    +

    32.7 Tips and techniques

    @@ -3438,7 +3419,7 @@ strings, binary data, and arrays. This chapter discusses the common techniques solving these problems.

    -

    31.7.1 Input and output parameters

    +

    32.7.1 Input and output parameters

    @@ -3651,7 +3632,7 @@ void foo(Bar *OUTPUT); may not have the intended effect since typemaps.i does not define an OUTPUT rule for Bar.

    -

    31.7.2 Simple pointers

    +

    32.7.2 Simple pointers

    @@ -3720,7 +3701,7 @@ If you replace %pointer_functions() by %pointer_class(type,name)SWIG Library chapter for further details.

    -

    31.7.3 Unbounded C Arrays

    +

    32.7.3 Unbounded C Arrays

    @@ -3782,7 +3763,7 @@ well suited for applications in which you need to create buffers, package binary data, etc.

    -

    31.7.4 String handling

    +

    32.7.4 String handling

    @@ -3851,7 +3832,7 @@ If you need to return binary data, you might use the also be used to extra binary data from arbitrary pointers.

    -

    31.8 Typemaps

    +

    32.8 Typemaps

    @@ -3868,7 +3849,7 @@ Typemaps are only used if you want to change some aspect of the primitive C-Python interface or if you want to elevate your guru status.

    -

    31.8.1 What is a typemap?

    +

    32.8.1 What is a typemap?

    @@ -3984,7 +3965,7 @@ parameter is omitted): -

    31.8.2 Python typemaps

    +

    32.8.2 Python typemaps

    @@ -4025,7 +4006,7 @@ a look at the SWIG library version 1.3.20 or so.

    -

    31.8.3 Typemap variables

    +

    32.8.3 Typemap variables

    @@ -4096,7 +4077,7 @@ properly assigned. The Python name of the wrapper function being created. -

    31.8.4 Useful Python Functions

    +

    32.8.4 Useful Python Functions

    @@ -4224,7 +4205,7 @@ write me -

    31.9 Typemap Examples

    +

    32.9 Typemap Examples

    @@ -4233,7 +4214,7 @@ might look at the files "python.swg" and "typemaps.i" in the SWIG library.

    -

    31.9.1 Converting Python list to a char **

    +

    32.9.1 Converting Python list to a char **

    @@ -4313,7 +4294,7 @@ memory allocation is used to allocate memory for the array, the the C function.

    -

    31.9.2 Expanding a Python object into multiple arguments

    +

    32.9.2 Expanding a Python object into multiple arguments

    @@ -4392,7 +4373,7 @@ to supply the argument count. This is automatically set by the typemap code. F -

    31.9.3 Using typemaps to return arguments

    +

    32.9.3 Using typemaps to return arguments

    @@ -4481,7 +4462,7 @@ function can now be used as follows: >>> -

    31.9.4 Mapping Python tuples into small arrays

    +

    32.9.4 Mapping Python tuples into small arrays

    @@ -4530,7 +4511,7 @@ array, such an approach would not be recommended for huge arrays, but for small structures, this approach works fine.

    -

    31.9.5 Mapping sequences to C arrays

    +

    32.9.5 Mapping sequences to C arrays

    @@ -4619,7 +4600,7 @@ static int convert_darray(PyObject *input, double *ptr, int size) { -

    31.9.6 Pointer handling

    +

    32.9.6 Pointer handling

    @@ -4716,7 +4697,7 @@ class object (if applicable). -

    31.10 Docstring Features

    +

    32.10 Docstring Features

    @@ -4744,7 +4725,7 @@ of your users much simpler.

    -

    31.10.1 Module docstring

    +

    32.10.1 Module docstring

    @@ -4778,7 +4759,7 @@ layout of controls on a panel, etc. to be loaded from an XML file." -

    31.10.2 %feature("autodoc")

    +

    32.10.2 %feature("autodoc")

    @@ -4805,7 +4786,7 @@ names, default values if any, and return type if any. There are also three options for autodoc controlled by the value given to the feature, described below. -

    31.10.2.1 %feature("autodoc", "0")

    +

    32.10.2.1 %feature("autodoc", "0")

    @@ -4834,7 +4815,7 @@ def function_name(*args, **kwargs): -

    31.10.2.2 %feature("autodoc", "1")

    +

    32.10.2.2 %feature("autodoc", "1")

    @@ -4859,7 +4840,7 @@ def function_name(*args, **kwargs): -

    31.10.2.3 %feature("autodoc", "docstring")

    +

    32.10.2.3 %feature("autodoc", "docstring")

    @@ -4878,7 +4859,7 @@ void GetPosition(int* OUTPUT, int* OUTPUT); -

    31.10.3 %feature("docstring")

    +

    32.10.3 %feature("docstring")

    @@ -4910,7 +4891,7 @@ with more than one line. -

    31.11 Python Packages

    +

    32.11 Python Packages

    @@ -4937,7 +4918,7 @@ and also in base class declarations, etc. if the package name is different than its own.

    -

    31.12 Python 3 Support

    +

    32.12 Python 3 Support

    @@ -4964,7 +4945,7 @@ The following are Python 3.0 new features that are currently supported by SWIG.

    -

    31.12.1 Function annotation

    +

    32.12.1 Function annotation

    @@ -4996,7 +4977,7 @@ all overloaded functions share the same function in SWIG generated proxy class. For detailed usage of function annotation, see PEP 3107.

    -

    31.12.2 Buffer interface

    +

    32.12.2 Buffer interface

    @@ -5148,7 +5129,7 @@ modify the buffer. -

    31.12.3 Abstract base classes

    +

    32.12.3 Abstract base classes

    diff --git a/Doc/Manual/R.html b/Doc/Manual/R.html index 0ed43fc52..ceea32146 100644 --- a/Doc/Manual/R.html +++ b/Doc/Manual/R.html @@ -6,7 +6,7 @@ -

    34 SWIG and R

    +

    35 SWIG and R

      @@ -33,7 +33,7 @@ compile and run an R interface to QuantLib running on Mandriva Linux with gcc. The R bindings also work on Microsoft Windows using Visual C++.

      -

      34.1 Bugs

      +

      35.1 Bugs

      @@ -45,7 +45,7 @@ Currently the following features are not implemented or broken:

    • C Array wrappings
    -

    34.2 Using R and SWIG

    +

    35.2 Using R and SWIG

    @@ -56,28 +56,48 @@ example.c is the name of the file with the functions in them

     swig -r example.i
    -PKG_LIBS="example.c" R CMD SHLIB example_wrap.c
    +R CMD SHLIB example_wrap.c example.c
     

    -The corresponding comments for C++ mode are +The corresponding options for C++ mode are

     swig -c++ -r -o example_wrap.cpp example.i
    -PKG_LIBS="example.cxx" R CMD SHLIB example_wrap.cpp
    +R CMD SHLIB example_wrap.cpp example.cpp
     

    -Note that R is sensitive to the name of the file and to the file -extension in C and C++ mode. The name of the wrapper file must be the -name of the library. Also in C++ mode, the file extension must be .cpp -rather than .cxx for the R compile command to recognize it. +Note that R is sensitive to the names of the files. +The name of the wrapper file must be the +name of the library unless you use the -o option to R when building the library, for example:

    +
    +
    +swig -c++ -r -o example_wrap.cpp example.i
    +R CMD SHLIB -o example.so example_wrap.cpp example.cpp
    +
    +
    + +

    +R is also sensitive to the name of the file +extension in C and C++ mode. In C++ mode, the file extension must be .cpp +rather than .cxx for the R compile command to recognize it. If your C++ code is +in a file using something other than a .cpp extension, then it may still work using PKG_LIBS: +

    + +
    +
    +swig -c++ -r -o example_wrap.cpp example.i
    +PKG_LIBS="example.cxx" R CMD SHLIB -o example example_wrap.cpp
    +
    +
    +

    The commands produces two files. A dynamic shared object file called example.so, or example.dll, and an R wrapper file called example.R. To load these @@ -99,7 +119,7 @@ Without it, inheritance of wrapped objects may fail. These two files can be loaded in any order

    -

    34.3 Precompiling large R files

    +

    35.3 Precompiling large R files

    In cases where the R file is large, one make save a lot of loading @@ -117,7 +137,7 @@ will save a large amount of loading time. -

    34.4 General policy

    +

    35.4 General policy

    @@ -126,7 +146,7 @@ wrapping over the underlying functions and rely on the R type system to provide R syntax.

    -

    34.5 Language conventions

    +

    35.5 Language conventions

    @@ -135,7 +155,7 @@ and [ are overloaded to allow for R syntax (one based indices and slices)

    -

    34.6 C++ classes

    +

    35.6 C++ classes

    @@ -147,7 +167,7 @@ keep track of the pointer object which removes the necessity for a lot of the proxy class baggage you see in other languages.

    -

    34.7 Enumerations

    +

    35.7 Enumerations

    diff --git a/Doc/Manual/Ruby.html b/Doc/Manual/Ruby.html index 3b1e5c45c..b61ded8e5 100644 --- a/Doc/Manual/Ruby.html +++ b/Doc/Manual/Ruby.html @@ -26,7 +26,7 @@ -

    32 SWIG and Ruby

    +

    33 SWIG and Ruby

  • Advanced Topics @@ -167,7 +167,7 @@ -

    32.1 Preliminaries

    +

    33.1 Preliminaries

    SWIG 1.3 is known to work with Ruby versions 1.6 and later. @@ -190,7 +190,7 @@ of Ruby.

    -

    32.1.1 Running SWIG

    +

    33.1.1 Running SWIG

    To build a Ruby module, run SWIG using the -ruby @@ -244,7 +244,7 @@ to compile this file and link it with the rest of your program.

    -

    32.1.2 Getting the right header files

    +

    33.1.2 Getting the right header files

    In order to compile the wrapper code, the compiler needs the ruby.h @@ -288,7 +288,7 @@ installed, you can run Ruby to find out. For example:

    -

    32.1.3 Compiling a dynamic module

    +

    33.1.3 Compiling a dynamic module

    Ruby extension modules are typically compiled into shared @@ -443,7 +443,7 @@ manual pages for your compiler and linker to determine the correct set of options. You might also check the SWIG Wiki for additional information.

    -

    32.1.4 Using your module

    +

    33.1.4 Using your module

    Ruby module names must be capitalized, @@ -498,7 +498,7 @@ begins with:

    -

    32.1.5 Static linking

    +

    33.1.5 Static linking

    An alternative approach to dynamic linking is to rebuild the @@ -519,7 +519,7 @@ finally rebuilding Ruby.

    -

    32.1.6 Compilation of C++ extensions

    +

    33.1.6 Compilation of C++ extensions

    On most machines, C++ extension modules should be linked @@ -571,7 +571,7 @@ extension, e.g.

    -

    32.2 Building Ruby Extensions under Windows 95/NT

    +

    33.2 Building Ruby Extensions under Windows 95/NT

    Building a SWIG extension to Ruby under Windows 95/NT is @@ -610,7 +610,7 @@ files.

    -

    32.2.1 Running SWIG from Developer Studio

    +

    33.2.1 Running SWIG from Developer Studio

    If you are developing your application within Microsoft @@ -752,7 +752,7 @@ directory, then run the Ruby script from the DOS/Command prompt:

    -

    32.3 The Ruby-to-C/C++ Mapping

    +

    33.3 The Ruby-to-C/C++ Mapping

    This section describes the basics of how SWIG maps C or C++ @@ -762,7 +762,7 @@ declarations in your SWIG interface files to Ruby constructs.

    -

    32.3.1 Modules

    +

    33.3.1 Modules

    The SWIG %module directive specifies @@ -931,7 +931,7 @@ Ruby's built-in names.

    -

    32.3.2 Functions

    +

    33.3.2 Functions

    Global functions are wrapped as Ruby module methods. For @@ -994,7 +994,7 @@ module that can be used like so:

    -

    32.3.3 Variable Linking

    +

    33.3.3 Variable Linking

    C/C++ global variables are wrapped as a pair of singleton @@ -1094,7 +1094,7 @@ effect until it is explicitly disabled using %mutable. -

    32.3.4 Constants

    +

    33.3.4 Constants

    C/C++ constants are wrapped as module constants initialized @@ -1138,7 +1138,7 @@ constant values, e.g.

    -

    32.3.5 Pointers

    +

    33.3.5 Pointers

    "Opaque" pointers to arbitrary C/C++ types (i.e. types that @@ -1190,7 +1190,7 @@ the Ruby nil object.

    -

    32.3.6 Structures

    +

    33.3.6 Structures

    C/C++ structs are wrapped as Ruby classes, with accessor @@ -1317,7 +1317,7 @@ this code:

    If you want to set an array member, you will need to supply a -"memberin" typemap described in the section on typemaps. +"memberin" typemap described in the section on typemaps. As a special case, SWIG does generate code to set array members of type char (allowing you to store a Ruby string in the structure).

    @@ -1365,7 +1365,7 @@ pointers. For example,

    -

    32.3.7 C++ classes

    +

    33.3.7 C++ classes

    Like structs, C++ classes are wrapped by creating a new Ruby @@ -1451,7 +1451,7 @@ class.

  • -

    32.3.8 C++ Inheritance

    +

    33.3.8 C++ Inheritance

    The SWIG type-checker is fully aware of C++ inheritance. @@ -1682,7 +1682,7 @@ Typing").

    -

    32.3.9 C++ Overloaded Functions

    +

    33.3.9 C++ Overloaded Functions

    C++ overloaded functions, methods, and constructors are @@ -1882,7 +1882,7 @@ and C++" chapter for more information about overloading.

    -

    32.3.10 C++ Operators

    +

    33.3.10 C++ Operators

    For the most part, overloaded operators are handled @@ -1956,14 +1956,14 @@ example:

    More details about wrapping C++ operators into Ruby operators -is discussed in the section +is discussed in the section on operator overloading.

    -

    32.3.11 C++ namespaces

    +

    33.3.11 C++ namespaces

    SWIG is aware of C++ namespaces, but namespace names do not @@ -2039,7 +2039,7 @@ identical symbol names, well, then you get what you deserve.

    -

    32.3.12 C++ templates

    +

    33.3.12 C++ templates

    C++ templates don't present a huge problem for SWIG. However, @@ -2083,7 +2083,7 @@ directive. For example:

    -

    32.3.13 C++ Standard Template Library (STL)

    +

    33.3.13 C++ Standard Template Library (STL)

    On a related note, the standard SWIG library contains a @@ -2336,7 +2336,7 @@ chapter.

    -

    32.3.14 C++ STL Functors

    +

    33.3.14 C++ STL Functors

    Some containers in the STL allow you to modify their default @@ -2536,7 +2536,7 @@ b
    -

    32.3.15 C++ STL Iterators

    +

    33.3.15 C++ STL Iterators

    The STL is well known for the use of iterators.  There @@ -2747,7 +2747,7 @@ i
    -

    32.3.16 C++ Smart Pointers

    +

    33.3.16 C++ Smart Pointers

    In certain C++ programs, it is common to use classes that @@ -2872,12 +2872,12 @@ method. For example:

    -

    32.3.17 Cross-Language Polymorphism

    +

    33.3.17 Cross-Language Polymorphism

    SWIG's Ruby module supports cross-language polymorphism (a.k.a. the "directors" feature) similar to that for SWIG's Python -module. Rather than duplicate the information presented in the Python chapter, this +module. Rather than duplicate the information presented in the Python chapter, this section just notes the differences that you need to be aware of when using this feature with Ruby.

    @@ -2885,7 +2885,7 @@ using this feature with Ruby.

    -

    32.3.17.1 Exception Unrolling

    +

    33.3.17.1 Exception Unrolling

    Whenever a C++ director class routes one of its virtual @@ -2923,7 +2923,7 @@ caught here and a C++ exception is raised in its place.

    -

    32.4 Naming

    +

    33.4 Naming

    Ruby has several common naming conventions. Constants are @@ -3019,7 +3019,7 @@ planned to become the default option in future releases.

    -

    32.4.1 Defining Aliases

    +

    33.4.1 Defining Aliases

    It's a fairly common practice in the Ruby built-ins and @@ -3111,7 +3111,7 @@ Features") for more details).

    -

    32.4.2 Predicate Methods

    +

    33.4.2 Predicate Methods

    Ruby methods that return a boolean value and end in a @@ -3200,7 +3200,7 @@ Features") for more details).

    -

    32.4.3 Bang Methods

    +

    33.4.3 Bang Methods

    Ruby methods that modify an object in-place and end in an @@ -3264,7 +3264,7 @@ Features") for more details).

    -

    32.4.4 Getters and Setters

    +

    33.4.4 Getters and Setters

    Often times a C++ library will expose properties through @@ -3334,7 +3334,7 @@ methods to be exposed in Ruby as value and value=. -

    32.5 Input and output parameters

    +

    33.5 Input and output parameters

    A common problem in some C programs is handling parameters @@ -3585,10 +3585,10 @@ of %apply

    -

    32.6 Exception handling

    +

    33.6 Exception handling

    -

    32.6.1 Using the %exception directive

    +

    33.6.1 Using the %exception directive

    The SWIG %exception directive can be @@ -3683,7 +3683,7 @@ Features for more examples.

    -

    32.6.2 Handling Ruby Blocks

    +

    33.6.2 Handling Ruby Blocks

    One of the highlights of Ruby and most of its standard library @@ -3864,7 +3864,7 @@ RUBY_YIELD_SELF );

    For more information on typemaps, see Typemaps.

    -

    32.6.3 Raising exceptions

    +

    33.6.3 Raising exceptions

    There are three ways to raise exceptions from C++ code to @@ -4625,7 +4625,7 @@ the built-in Ruby exception types.

    -

    32.6.4 Exception classes

    +

    33.6.4 Exception classes

    Starting with SWIG 1.3.28, the Ruby module supports the %exceptionclass @@ -4683,7 +4683,7 @@ providing for a more natural integration between C++ code and Ruby code.

    -

    32.7 Typemaps

    +

    33.7 Typemaps

    This section describes how you can modify SWIG's default @@ -4706,7 +4706,7 @@ of the primitive C-Ruby interface.

    -

    32.7.1 What is a typemap?

    +

    33.7.1 What is a typemap?

    A typemap is nothing more than a code generation rule that is @@ -4968,7 +4968,7 @@ to be used as follows (notice how the length parameter is omitted):

    -

    32.7.2 Typemap scope

    +

    33.7.2 Typemap scope

    Once defined, a typemap remains in effect for all of the @@ -5016,7 +5016,7 @@ where the class itself is defined. For example:

    -

    32.7.3 Copying a typemap

    +

    33.7.3 Copying a typemap

    A typemap is copied by using assignment. For example:

    @@ -5118,7 +5118,7 @@ rules as for -

    32.7.4 Deleting a typemap

    +

    33.7.4 Deleting a typemap

    A typemap can be deleted by simply defining no code. For @@ -5170,7 +5170,7 @@ typemaps immediately after the clear operation.

    -

    32.7.5 Placement of typemaps

    +

    33.7.5 Placement of typemaps

    Typemap declarations can be declared in the global scope, @@ -5254,7 +5254,7 @@ string -

    32.7.6 Ruby typemaps

    +

    33.7.6 Ruby typemaps

    The following list details all of the typemap methods that @@ -5264,7 +5264,7 @@ can be used by the Ruby module:

    -

    32.7.6.1  "in" typemap

    +

    33.7.6.1  "in" typemap

    Converts Ruby objects to input @@ -5507,7 +5507,7 @@ arguments to be specified. For example:

    -

    32.7.6.2 "typecheck" typemap

    +

    33.7.6.2 "typecheck" typemap

    The "typecheck" typemap is used to support overloaded @@ -5548,7 +5548,7 @@ on "Typemaps and Overloading."

    -

    32.7.6.3  "out" typemap

    +

    33.7.6.3  "out" typemap

    Converts return value of a C function @@ -5780,7 +5780,7 @@ version of the C datatype matched by the typemap. -

    32.7.6.4 "arginit" typemap

    +

    33.7.6.4 "arginit" typemap

    The "arginit" typemap is used to set the initial value of a @@ -5805,7 +5805,7 @@ applications. For example:

    -

    32.7.6.5 "default" typemap

    +

    33.7.6.5 "default" typemap

    The "default" typemap is used to turn an argument into a @@ -5847,7 +5847,7 @@ default argument wrapping.

    -

    32.7.6.6 "check" typemap

    +

    33.7.6.6 "check" typemap

    The "check" typemap is used to supply value checking code @@ -5871,7 +5871,7 @@ arguments have been converted. For example:

    -

    32.7.6.7 "argout" typemap

    +

    33.7.6.7 "argout" typemap

    The "argout" typemap is used to return values from arguments. @@ -6029,7 +6029,7 @@ some function like SWIG_Ruby_AppendOutput.

    -

    32.7.6.8 "freearg" typemap

    +

    33.7.6.8 "freearg" typemap

    The "freearg" typemap is used to cleanup argument data. It is @@ -6065,7 +6065,7 @@ abort prematurely.

    -

    32.7.6.9 "newfree" typemap

    +

    33.7.6.9 "newfree" typemap

    The "newfree" typemap is used in conjunction with the %newobject @@ -6089,14 +6089,14 @@ a function. For example:

    -

    See Object +

    See Object ownership and %newobject for further details.

    -

    32.7.6.10 "memberin" typemap

    +

    33.7.6.10 "memberin" typemap

    The "memberin" typemap is used to copy data from an @@ -6129,7 +6129,7 @@ other objects.

    -

    32.7.6.11 "varin" typemap

    +

    33.7.6.11 "varin" typemap

    The "varin" typemap is used to convert objects in the target @@ -6140,7 +6140,7 @@ This is implementation specific.

    -

    32.7.6.12 "varout" typemap

    +

    33.7.6.12 "varout" typemap

    The "varout" typemap is used to convert a C/C++ object to an @@ -6151,7 +6151,7 @@ This is implementation specific.

    -

    32.7.6.13 "throws" typemap

    +

    33.7.6.13 "throws" typemap

    The "throws" typemap is only used when SWIG parses a C++ @@ -6210,7 +6210,7 @@ handling with %exception section.

    -

    32.7.6.14 directorin typemap

    +

    33.7.6.14 directorin typemap

    Converts C++ objects in director @@ -6464,7 +6464,7 @@ referring to the class itself. -

    32.7.6.15 directorout typemap

    +

    33.7.6.15 directorout typemap

    Converts Ruby objects in director @@ -6724,7 +6724,7 @@ exception.
    -

    32.7.6.16 directorargout typemap

    +

    33.7.6.16 directorargout typemap

    Output argument processing in director @@ -6964,7 +6964,7 @@ referring to the instance of the class itself -

    32.7.6.17 ret typemap

    +

    33.7.6.17 ret typemap

    Cleanup of function return values @@ -6974,7 +6974,7 @@ referring to the instance of the class itself -

    32.7.6.18 globalin typemap

    +

    33.7.6.18 globalin typemap

    Setting of C global variables @@ -6984,7 +6984,7 @@ referring to the instance of the class itself -

    32.7.7 Typemap variables

    +

    33.7.7 Typemap variables

    @@ -7094,13 +7094,13 @@ being created.

    -

    32.7.8 Useful Functions

    +

    33.7.8 Useful Functions

    When you write a typemap, you usually have to work directly with Ruby objects. The following functions may prove to be useful. -(These functions plus many more can be found in Programming -Ruby, by David Thomas and Andrew Hunt.) 

    +(These functions plus many more can be found in Programming +Ruby book, by David Thomas and Andrew Hunt.) 

    In addition, we list equivalent functions that SWIG defines, which provide a language neutral conversion (these functions are defined for each swig language supported).  If you are trying to create a swig @@ -7118,7 +7118,7 @@ across multiple languages.

    -

    32.7.8.1 C Datatypes to Ruby Objects

    +

    33.7.8.1 C Datatypes to Ruby Objects

    @@ -7174,7 +7174,7 @@ SWIG_From_float(float) -

    32.7.8.2 Ruby Objects to C Datatypes

    +

    33.7.8.2 Ruby Objects to C Datatypes

    Here, while the Ruby versions return the value directly, the SWIG @@ -7263,7 +7263,7 @@ Ruby_Format_TypeError( "$1_name", "$1_type","$symname", $argnum, $input -

    32.7.8.3 Macros for VALUE

    +

    33.7.8.3 Macros for VALUE

    RSTRING_LEN(str)

    @@ -7326,7 +7326,7 @@ Ruby_Format_TypeError( "$1_name", "$1_type","$symname", $argnum, $input -

    32.7.8.4 Exceptions

    +

    33.7.8.4 Exceptions

    void rb_raise(VALUE exception, const char *fmt, @@ -7493,7 +7493,7 @@ arguments are interpreted as with printf().

    -

    32.7.8.5 Iterators

    +

    33.7.8.5 Iterators

    void rb_iter_break()

    @@ -7595,7 +7595,7 @@ VALUE), VALUE value)

    -

    32.7.9 Typemap Examples

    +

    33.7.9 Typemap Examples

    This section includes a few examples of typemaps. For more @@ -7606,7 +7606,7 @@ directory.

    -

    32.7.10 Converting a Ruby array to a char **

    +

    33.7.10 Converting a Ruby array to a char **

    A common problem in many C programs is the processing of @@ -7661,7 +7661,7 @@ after the execution of the C function.

    -

    32.7.11 Collecting arguments in a hash

    +

    33.7.11 Collecting arguments in a hash

    Ruby's solution to the "keyword arguments" capability of some @@ -7940,7 +7940,7 @@ directory of the SWIG distribution.

    -

    32.7.12 Pointer handling

    +

    33.7.12 Pointer handling

    Occasionally, it might be necessary to convert pointer values @@ -8039,7 +8039,7 @@ For example:

    -

    32.7.12.1 Ruby Datatype Wrapping

    +

    33.7.12.1 Ruby Datatype Wrapping

    VALUE Data_Wrap_Struct(VALUE class, void @@ -8090,7 +8090,7 @@ and assigns that pointer to ptr.

    -

    32.7.13 Example: STL Vector to Ruby Array

    +

    33.7.13 Example: STL Vector to Ruby Array

    Another use for macros and type maps is to create a Ruby array @@ -8199,7 +8199,7 @@ the C++ Standard Template Library.
    -

    32.8 Docstring Features

    +

    33.8 Docstring Features

    @@ -8260,7 +8260,7 @@ generate ri documentation from a c wrap file, you could do:

    -

    32.8.1 Module docstring

    +

    33.8.1 Module docstring

    @@ -8311,7 +8311,7 @@ macro. For example: -

    32.8.2 %feature("autodoc")

    +

    33.8.2 %feature("autodoc")

    Since SWIG does know everything about the function it wraps, @@ -8340,7 +8340,7 @@ feature, described below. -

    32.8.2.1 %feature("autodoc", "0")

    +

    33.8.2.1 %feature("autodoc", "0")

    @@ -8388,7 +8388,7 @@ Then Ruby code like this will be generated: -

    32.8.2.2 %feature("autodoc", "1")

    +

    33.8.2.2 %feature("autodoc", "1")

    @@ -8420,7 +8420,7 @@ this: -

    32.8.2.3 %feature("autodoc", "2")

    +

    33.8.2.3 %feature("autodoc", "2")

    @@ -8436,7 +8436,7 @@ this: -

    32.8.2.4 %feature("autodoc", "3")

    +

    33.8.2.4 %feature("autodoc", "3")

    @@ -8464,7 +8464,7 @@ this: -

    32.8.2.5 %feature("autodoc", "docstring")

    +

    33.8.2.5 %feature("autodoc", "docstring")

    @@ -8492,7 +8492,7 @@ generated string. For example: -

    32.8.3 %feature("docstring")

    +

    33.8.3 %feature("docstring")

    @@ -8507,10 +8507,10 @@ docstring and they are output together.

    -

    32.9 Advanced Topics

    +

    33.9 Advanced Topics

    -

    32.9.1 Operator overloading

    +

    33.9.1 Operator overloading

    SWIG allows operator overloading with, by using the %extend @@ -9527,10 +9527,10 @@ parses the expression a != b as !(a == b). -

    32.9.2 Creating Multi-Module Packages

    +

    33.9.2 Creating Multi-Module Packages

    -

    The chapter on Working +

    The chapter on Working with Modules discusses the basics of creating multi-module extensions with SWIG, and in particular the considerations for sharing runtime type information among the different modules.

    @@ -9708,7 +9708,7 @@ initialized:

    -

    32.9.3 Specifying Mixin Modules

    +

    33.9.3 Specifying Mixin Modules

    The Ruby language doesn't support multiple inheritance, but @@ -9806,7 +9806,7 @@ Features") for more details).

    -

    32.10 Memory Management

    +

    33.10 Memory Management

    One of the most common issues in generating SWIG bindings for @@ -9853,7 +9853,7 @@ understanding of how the underlying library manages memory.

    -

    32.10.1 Mark and Sweep Garbage Collector

    +

    33.10.1 Mark and Sweep Garbage Collector

    Ruby uses a mark and sweep garbage collector. When the garbage @@ -9901,7 +9901,7 @@ this memory.

    -

    32.10.2 Object Ownership

    +

    33.10.2 Object Ownership

    As described above, memory management depends on clearly @@ -10050,7 +10050,7 @@ above. For example:

    In this case, the default SWIG behavior for calling member functions is incorrect. The Ruby object should assume ownership of the returned object. This can be done by using the %newobject directive. -See +See Object ownership and %newobject for more information.

    @@ -10128,7 +10128,7 @@ classes is:

    -

    32.10.3 Object Tracking

    +

    33.10.3 Object Tracking

    The remaining parts of this section will use the class library @@ -10204,7 +10204,7 @@ the same underlying C++ object. This can cause problems. For example:
    -

    After the the garbage collector runs, as a result of our call +

    After the garbage collector runs, as a result of our call to GC.start, callingtiger2.get_name() causes a segmentation fault. The problem is that when tiger1 is garbage collected, it frees the underlying C++ object. Thus, when tiger2 @@ -10342,7 +10342,7 @@ methods.

    -

    32.10.4 Mark Functions

    +

    33.10.4 Mark Functions

    With a bit more testing, we see that our class library still @@ -10460,7 +10460,7 @@ test suite.

    -

    32.10.5 Free Functions

    +

    33.10.5 Free Functions

    By default, SWIG creates a "free" function that is called when @@ -10615,7 +10615,7 @@ been freed, and thus raises a runtime exception.

    -

    32.10.6 Embedded Ruby and the C++ Stack

    +

    33.10.6 Embedded Ruby and the C++ Stack

    As has been said, the Ruby GC runs and marks objects before @@ -10649,7 +10649,7 @@ initialization a normal Ruby interpreter will call the ruby_init() function which in turn will call a function called Init_stack or similar.  This function will store a pointer to the location where -the stack points at at that point in time.

    +the stack points at that point in time.

    diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html index 02d0ca3a4..d523bee77 100644 --- a/Doc/Manual/SWIG.html +++ b/Doc/Manual/SWIG.html @@ -13,7 +13,7 @@
  • Running SWIG
    • Input format -
    • SWIG Output +
    • SWIG Output
    • Comments
    • C Preprocessor
    • SWIG Directives @@ -92,7 +92,7 @@ chapters.

      -To run SWIG, use the swig command with options options and a filename like this: +To run SWIG, use the swig command with options and a filename like this:

      @@ -113,6 +113,7 @@ can be obtained by typing swig -help or swig
       -clisp                Generate CLISP wrappers
       -cffi                 Generate CFFI wrappers
       -csharp               Generate C# wrappers
      +-go                   Generate Go wrappers
       -guile                Generate Guile wrappers
       -java                 Generate Java wrappers
       -lua                  Generate Lua wrappers
      @@ -193,7 +194,7 @@ semantics in SWIG is analogous to that of the declarations section
       used in input files to parser generation tools such as yacc or bison.
       

      -

      5.1.2 SWIG Output

      +

      5.1.2 SWIG Output

      @@ -1618,7 +1619,7 @@ double y; // Read-write

      The %mutable and %immutable directives are actually -%feature directives defined like this: +%feature directives defined like this:

      @@ -1672,7 +1673,7 @@ directive as shown :

      // interface.i %rename(my_print) print; -extern void print(char *); +extern void print(const char *); %rename(foo) a_really_long_and_annoying_name; extern int a_really_long_and_annoying_name; @@ -1725,9 +1726,10 @@ to ignore declarations that match a given identifier. For example:
       %ignore print;         // Ignore all declarations named print
      -%ignore _HAVE_FOO_H;   // Ignore an include guard constant
      +%ignore MYMACRO;       // Ignore a macro
       ...
      -%include "foo.h"       // Grab a header file
      +#define MYMACRO 123
      +void print(const char *);
       ...
       
      @@ -1742,7 +1744,7 @@ declarations. If you need to remove a whole section of problematic code, the SW

      More powerful variants of %rename and %ignore directives can be used to help wrap C++ overloaded functions and methods or C++ methods which use default arguments. This is described in the -Ambiguity resolution and renaming section in the C++ chapter. +Ambiguity resolution and renaming section in the C++ chapter.

      @@ -1752,7 +1754,7 @@ For example:

      -%name(output) extern void print(char *);
      +%name(output) extern void print(const char *);
       
      diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index d1498224f..f9bfc8ec6 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -42,18 +42,21 @@
    • Wrapping overloaded operators
    • Class extension
    • Templates -
    • Namespaces +
    • Namespaces +
    • Renaming templated types in namespaces
    • Exception specifications
    • Exception handling with %catches
    • Pointers to Members -
    • Smart pointers and operator->() +
    • Smart pointers and operator->()
    • Using declarations and inheritance
    • Nested classes
    • A brief rant about const-correctness @@ -1125,7 +1128,7 @@ For example if a method has ten default arguments, then eleven wrapper methods a

      Please see the Features and default arguments section for more information on using %feature with functions with default arguments. -The Ambiguity resolution and renaming section +The Ambiguity resolution and renaming section also deals with using %rename and %ignore on methods with default arguments. If you are writing your own typemaps for types used in methods with default arguments, you may also need to write a typecheck typemap. See the Typemaps and overloading section for details or otherwise @@ -2124,7 +2127,7 @@ it means that the target language module has not yet implemented support for ove functions and methods. The only way to fix the problem is to read the next section.

      -

      6.15.3 Ambiguity resolution and renaming

      +

      6.15.3 Ambiguity resolution and renaming

      @@ -3647,12 +3650,16 @@ as the class name. For example: Similar changes apply to typemaps and other customization features.

      -

      6.19 Namespaces

      +

      6.19 Namespaces

      -Support for C++ namespaces is a relatively late addition to SWIG, -first appearing in SWIG-1.3.12. Before describing the implementation, +Support for C++ namespaces is comprehensive, but by default simple, however, +some target languages can turn on more advanced namespace support via the +nspace feature, described later. +Code within unnamed namespaces is ignored as there is no external +access to symbols declared within the unnamed namespace. +Before detailing the default implementation for named namespaces, it is worth noting that the semantics of C++ namespaces is extremely non-trivial--especially with regard to the C++ type system and class machinery. At a most basic level, namespaces are sometimes used to @@ -4092,6 +4099,87 @@ with any namespace awareness. In the future, language modules may or may not p more advanced namespace support.

      +

      6.19.1 The nspace feature for namespaces

      + + +

      +Some target languages provide support for the nspace feature. +The feature can be applied to any class, struct, union or enum declared within a named namespace. +The feature wraps the type within the target language specific concept of a namespace, +for example, a Java package or C# namespace. +Please see the language specific sections to see if the target language you are interested in supports the nspace feature. +

      + +

      +The feature is demonstrated below for C# using the following example: +

      + +
      +
      +%feature("nspace") MyWorld::Material::Color;
      +%nspace MyWorld::Wrapping::Color; // %nspace is a macro for %feature("nspace")
      +
      +namespace MyWorld {
      +  namespace Material {
      +    class Color {
      +    ...
      +    };
      +  }
      +  namespace Wrapping {
      +    class Color {
      +    ...
      +    };
      +  }
      +}
      +
      +
      + +

      +Without the nspace feature directives above or %rename, you would get the following warning resulting in just one of the Color classes being available for use from the target language: +

      + +
      +
      +example.i:9: Error: 'Color' is multiply defined in the generated target language module.
      +example.i:5: Error: Previous declaration of 'Color'
      +
      +
      + +

      +With the nspace feature the two Color classes are wrapped into the equivalent C# namespaces. +A fully qualified constructor call of each these two types in C# is then: +

      + +
      +
      +MyWorld.Material.Color materialColor = new MyWorld.Material.Color();
      +MyWorld.Wrapping.Color wrappingColor = new MyWorld.Wrapping.Color();
      +
      +
      + +

      +Note that the nspace feature does not apply to variables and functions simply declared in a namespace. For example, the following symbols cannot co-exist in the target language without renaming. This may change in a future version. +

      + +
      +
      +namespace MyWorld {
      +  namespace Material {
      +    int quantity;
      +    void dispatch();
      +  }
      +  namespace Wrapping {
      +    int quantity;
      +    void dispatch();
      +  }
      +}
      +
      +
      + +

      +Compatibility Note: The nspace feature was first introduced in SWIG-2.0.0. +

      +

      6.20 Renaming templated types in namespaces

      @@ -4216,7 +4304,7 @@ is outlined in the "throws" typemap s

      Since exception specifications are sometimes only used sparingly, this alone may not be enough to properly handle C++ exceptions. To do that, a different set of special SWIG directives are used. -Consult the "Exception handling with %exception" section for details. +Consult the "Exception handling with %exception" section for details. The next section details a way of simulating an exception specification or replacing an existing one.

      @@ -4320,7 +4408,7 @@ when checking types. However, no such support is currently provided for member pointers.

      -

      6.24 Smart pointers and operator->()

      +

      6.24 Smart pointers and operator->()

      diff --git a/Doc/Manual/Sections.html b/Doc/Manual/Sections.html index ab47ed8ee..8693adc07 100644 --- a/Doc/Manual/Sections.html +++ b/Doc/Manual/Sections.html @@ -1,23 +1,15 @@ -SWIG-1.3 Documentation +SWIG-2.0 Documentation -

      SWIG-1.3 Development Documentation

      +

      SWIG-2.0 Documentation

      -Last update : SWIG-2.0.0 (in progress) +Last update : SWIG-2.0.1 (in progress)

      Sections

      -

      -The SWIG documentation is being updated to reflect new SWIG -features and enhancements. However, this update process is not quite -finished--there is a lot of old SWIG-1.1 documentation and it is taking -some time to update all of it. Please pardon our dust (or volunteer -to help!). -

      -

      SWIG Core Documentation

      • Preface
      • @@ -41,13 +33,14 @@ to help!).

        Language Module Documentation

        -

        Documentation that has not yet been updated

        - -

        -This documentation has not been completely updated from SWIG-1.1, but most of the topics -still apply to the current release. Make sure you read the -SWIG Basics chapter before reading -any of these chapters. Also, SWIG-1.3.10 features extensive changes to the -implementation of typemaps. Make sure you read the Typemaps -chapter above if you are using this feature. -

        - - - diff --git a/Doc/Manual/Tcl.html b/Doc/Manual/Tcl.html index b37df2853..d47dae5de 100644 --- a/Doc/Manual/Tcl.html +++ b/Doc/Manual/Tcl.html @@ -6,7 +6,7 @@ -

        33 SWIG and Tcl

        +

        34 SWIG and Tcl

          @@ -83,7 +83,7 @@ Tcl 8.0 or a later release. Earlier releases of SWIG supported Tcl 7.x, but this is no longer supported.

          -

          33.1 Preliminaries

          +

          34.1 Preliminaries

          @@ -109,7 +109,7 @@ build a Tcl extension module. To finish building the module, you need to compile this file and link it with the rest of your program.

          -

          33.1.1 Getting the right header files

          +

          34.1.1 Getting the right header files

          @@ -127,7 +127,7 @@ this is the case, you should probably make a symbolic link so that tcl.h -

          33.1.2 Compiling a dynamic module

          +

          34.1.2 Compiling a dynamic module

          @@ -162,7 +162,7 @@ The name of the module is specified using the %module directive or the -module command line option.

          -

          33.1.3 Static linking

          +

          34.1.3 Static linking

          @@ -228,7 +228,7 @@ minimal in most situations (and quite frankly not worth the extra hassle in the opinion of this author).

          -

          33.1.4 Using your module

          +

          34.1.4 Using your module

          @@ -356,7 +356,7 @@ to the default system configuration (this requires root access and you will need the man pages).

          -

          33.1.5 Compilation of C++ extensions

          +

          34.1.5 Compilation of C++ extensions

          @@ -439,7 +439,7 @@ erratic program behavior. If working with lots of software components, you might want to investigate using a more formal standard such as COM.

          -

          33.1.6 Compiling for 64-bit platforms

          +

          34.1.6 Compiling for 64-bit platforms

          @@ -466,7 +466,7 @@ also introduce problems on platforms that support more than one linking standard (e.g., -o32 and -n32 on Irix).

          -

          33.1.7 Setting a package prefix

          +

          34.1.7 Setting a package prefix

          @@ -485,7 +485,7 @@ option will append the prefix to the name when creating a command and call it "Foo_bar".

          -

          33.1.8 Using namespaces

          +

          34.1.8 Using namespaces

          @@ -507,7 +507,7 @@ When the -namespace option is used, objects in the module are always accessed with the namespace name such as Foo::bar.

          -

          33.2 Building Tcl/Tk Extensions under Windows 95/NT

          +

          34.2 Building Tcl/Tk Extensions under Windows 95/NT

          @@ -518,7 +518,7 @@ covers the process of using SWIG with Microsoft Visual C++. although the procedure may be similar with other compilers.

          -

          33.2.1 Running SWIG from Developer Studio

          +

          34.2.1 Running SWIG from Developer Studio

          @@ -576,7 +576,7 @@ MSDOS > tclsh80 %

    • -

      33.2.2 Using NMAKE

      +

      34.2.2 Using NMAKE

      @@ -639,7 +639,7 @@ to get you started. With a little practice, you'll be making lots of Tcl extensions.

      -

      33.3 A tour of basic C/C++ wrapping

      +

      34.3 A tour of basic C/C++ wrapping

      @@ -650,7 +650,7 @@ classes. This section briefly covers the essential aspects of this wrapping.

      -

      33.3.1 Modules

      +

      34.3.1 Modules

      @@ -684,7 +684,7 @@ To fix this, supply an extra argument to load like this:

      -

      33.3.2 Functions

      +

      34.3.2 Functions

      @@ -709,7 +709,7 @@ like you think it does: % -

      33.3.3 Global variables

      +

      34.3.3 Global variables

      @@ -789,7 +789,7 @@ extern char *path; // Read-only (due to %immutable) -

      33.3.4 Constants and enums

      +

      34.3.4 Constants and enums

      @@ -873,7 +873,7 @@ When an identifier name is given, it is used to perform an implicit hash-table l conversion. This allows the global statement to be omitted.

      -

      33.3.5 Pointers

      +

      34.3.5 Pointers

      @@ -969,7 +969,7 @@ C-style cast may return a bogus result whereas as the C++-style cast will return None if the conversion can't be performed.

      -

      33.3.6 Structures

      +

      34.3.6 Structures

      @@ -1251,7 +1251,7 @@ Note: Tcl only destroys the underlying object if it has ownership. See the memory management section that appears shortly.

      -

      33.3.7 C++ classes

      +

      34.3.7 C++ classes

      @@ -1318,7 +1318,7 @@ In Tcl, the static member is accessed as follows: -

      33.3.8 C++ inheritance

      +

      34.3.8 C++ inheritance

      @@ -1367,7 +1367,7 @@ For instance: It is safe to use multiple inheritance with SWIG.

      -

      33.3.9 Pointers, references, values, and arrays

      +

      34.3.9 Pointers, references, values, and arrays

      @@ -1421,7 +1421,7 @@ to hold the result and a pointer is returned (Tcl will release this memory when the return value is garbage collected).

      -

      33.3.10 C++ overloaded functions

      +

      34.3.10 C++ overloaded functions

      @@ -1544,7 +1544,7 @@ first declaration takes precedence. Please refer to the "SWIG and C++" chapter for more information about overloading.

      -

      33.3.11 C++ operators

      +

      34.3.11 C++ operators

      @@ -1646,7 +1646,7 @@ There are ways to make this operator appear as part of the class using the % Keep reading.

      -

      33.3.12 C++ namespaces

      +

      34.3.12 C++ namespaces

      @@ -1710,7 +1710,7 @@ utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve.

      -

      33.3.13 C++ templates

      +

      34.3.13 C++ templates

      @@ -1762,7 +1762,7 @@ More details can be found in the SWIG and C++ -

      33.3.14 C++ Smart Pointers

      +

      34.3.14 C++ Smart Pointers

      @@ -1846,7 +1846,7 @@ simply use the __deref__() method. For example: -

      33.4 Further details on the Tcl class interface

      +

      34.4 Further details on the Tcl class interface

      @@ -1859,7 +1859,7 @@ of low-level details were omitted. This section provides a brief overview of how the proxy classes work.

      -

      33.4.1 Proxy classes

      +

      34.4.1 Proxy classes

      @@ -1924,7 +1924,7 @@ function. This allows objects to be encapsulated objects that look a lot like as shown in the last section.

      -

      33.4.2 Memory management

      +

      34.4.2 Memory management

      @@ -2112,7 +2112,7 @@ typemaps--an advanced topic discussed later.

      -

      33.5 Input and output parameters

      +

      34.5 Input and output parameters

      @@ -2300,7 +2300,7 @@ set c [lindex $dim 1] -

      33.6 Exception handling

      +

      34.6 Exception handling

      @@ -2434,7 +2434,7 @@ Since SWIG's exception handling is user-definable, you are not limited to C++ ex See the chapter on "Customization Features" for more examples.

      -

      33.7 Typemaps

      +

      34.7 Typemaps

      @@ -2451,7 +2451,7 @@ Typemaps are only used if you want to change some aspect of the primitive C-Tcl interface.

      -

      33.7.1 What is a typemap?

      +

      34.7.1 What is a typemap?

      @@ -2568,7 +2568,7 @@ parameter is omitted): -

      33.7.2 Tcl typemaps

      +

      34.7.2 Tcl typemaps

      @@ -2706,7 +2706,7 @@ Initialize an argument to a value before any conversions occur. Examples of these methods will appear shortly.

      -

      33.7.3 Typemap variables

      +

      34.7.3 Typemap variables

      @@ -2777,7 +2777,7 @@ properly assigned. The Tcl name of the wrapper function being created. -

      33.7.4 Converting a Tcl list to a char **

      +

      34.7.4 Converting a Tcl list to a char **

      @@ -2839,7 +2839,7 @@ argv[2] = Larry 3 -

      33.7.5 Returning values in arguments

      +

      34.7.5 Returning values in arguments

      @@ -2881,7 +2881,7 @@ result, a Tcl function using these typemaps will work like this : % -

      33.7.6 Useful functions

      +

      34.7.6 Useful functions

      @@ -2958,7 +2958,7 @@ int Tcl_IsShared(Tcl_Obj *obj); -

      33.7.7 Standard typemaps

      +

      34.7.7 Standard typemaps

      @@ -3042,7 +3042,7 @@ work) -

      33.7.8 Pointer handling

      +

      34.7.8 Pointer handling

      @@ -3118,7 +3118,7 @@ For example: -

      33.8 Turning a SWIG module into a Tcl Package.

      +

      34.8 Turning a SWIG module into a Tcl Package.

      @@ -3190,7 +3190,7 @@ As a final note, most SWIG examples do not yet use the to use the load command instead.

      -

      33.9 Building new kinds of Tcl interfaces (in Tcl)

      +

      34.9 Building new kinds of Tcl interfaces (in Tcl)

      @@ -3289,7 +3289,7 @@ danger of blowing something up (although it is easily accomplished with an out of bounds array access).

      -

      33.9.1 Proxy classes

      +

      34.9.1 Proxy classes

      @@ -3410,7 +3410,7 @@ short, but clever Tcl script can be combined with SWIG to do many interesting things.

      -

      33.10 Tcl/Tk Stubs

      +

      34.10 Tcl/Tk Stubs

      diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index 14623b37d..1568c082e 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -18,6 +18,7 @@

    • Reusing typemaps
    • What can be done with typemaps?
    • What can't be done with typemaps? +
    • Similarities to Aspect Oriented Programming
    • The rest of this chapter
  • Typemap specifications @@ -31,10 +32,10 @@
  • Pattern matching rules
  • Code generation rules @@ -72,14 +73,18 @@
  • Typemaps for multiple target languages
  • Optimal code generation when returning by value
  • Multi-argument typemaps -
  • The run-time type checker +
  • Typemap fragments + +
  • The run-time type checker
  • Typemaps and overloading
  • More about %apply and %clear -
  • Reducing wrapper code size
  • Passing data between typemaps
  • C++ "this" pointer
  • Where to go for more information? @@ -111,7 +116,7 @@ chapter with only a vague idea of what SWIG already does by default.

    One of the most important problems in wrapper code generation is the -conversion of datatypes between programming languages. Specifically, +conversion or marshalling of datatypes between programming languages. Specifically, for every C/C++ declaration, SWIG must somehow generate wrapper code that allows values to be passed back and forth between languages. Since every programming language represents data differently, this is @@ -580,14 +585,14 @@ suppose you had a declaration like this,

    -Foo *make_Foo();
    +Foo *make_Foo(int n);
     

    -and you wanted to tell SWIG that make_Foo() returned a newly +and you wanted to tell SWIG that make_Foo(int n) returned a newly allocated object (for the purposes of providing better memory -management). Clearly, this property of make_Foo() is +management). Clearly, this property of make_Foo(int n) is not a property that would be associated with the datatype Foo * by itself. Therefore, a completely different SWIG customization mechanism (%feature) is used for this purpose. Consult the -

    10.1.7 The rest of this chapter

    +

    10.1.7 Similarities to Aspect Oriented Programming

    + + +

    +SWIG has parallels to Aspect Oriented Software Development (AOP). +The AOP terminology with respect to SWIG typemaps can be viewed as follows: +

    +
      +
    • Cross-cutting concerns: The cross-cutting concerns are the modularization of the functionality that the typemaps implement, which is primarily marshalling of types from/to the target language and C/C++. +
    • Advice: The typemap body contains code which is executed whenever the marshalling is required. +
    • Pointcut: The pointcuts are the positions in the wrapper code that the typemap code is generated into. +
    • Aspect: Aspects are the combination of the pointcut and the advice, hence each typemap is an aspect. +
    +

    +SWIG can also be viewed as has having a second set of aspects based around %feature. +Features such as %exception are also cross-cutting concerns as they encapsulate code that can be used to add logging or exception handling to any function. +

    + +

    10.1.8 The rest of this chapter

    @@ -991,7 +1014,7 @@ types (std::string and Foo::string).

    It should be noted that for scoping to work, SWIG has to know that string is a typename defined -within a particular namespace. In this example, this is done using the class declaration class string. +within a particular namespace. In this example, this is done using the forward class declaration class string.

    10.3 Pattern matching rules

    @@ -1023,8 +1046,10 @@ is used.

    -If TYPE includes qualifiers (const, volatile, etc.), they are stripped to form a new stripped type +If TYPE includes qualifiers (const, volatile, etc.), each qualifier is stripped one at a time to form a new stripped type and the matching rules above are repeated on the stripped type. +The left-most qualifier is stripped first, resulting in the right-most (or top-level) qualifier being stripped last. +For example int const*const is first stripped to int *const then int *.

    @@ -1053,8 +1078,8 @@ To find a typemap for the argument const char *s, SWIG will search for

     const char *s           Exact type and name match
     const char *            Exact type match
    -char *s                 Type and name match (stripped qualifiers)
    -char *                  Type match (stripped qualifiers)
    +char *s                 Type and name match (qualifier stripped)
    +char *                  Type match (qualifier stripped)
     
    @@ -1085,16 +1110,21 @@ shows how some of the basic rules are applied: ... typemap 5 } -void A(int *x); // int *x rule (typemap 1) -void B(int *y); // int * rule (typemap 2) -void C(const int *x); // int *x rule (typemap 1) -void D(const int *z); // int * rule (typemap 3) -void E(int x[4]); // int [4] rule (typemap 4) -void F(int x[1000]); // int [ANY] rule (typemap 5) +void A(int *x); // int *x rule (typemap 1) +void B(int *y); // int * rule (typemap 2) +void C(const int *x); // int *x rule (typemap 1) +void D(const int *z); // const int *z rule (typemap 3) +void E(int x[4]); // int [4] rule (typemap 4) +void F(int x[1000]); // int [ANY] rule (typemap 5) -

    10.3.2 Typedef reductions

    +

    +Compatibility note: SWIG-2.0.0 introduced stripping the qualifiers one step at a time. Prior versions +stripped all qualifiers in one step. +

    + +

    10.3.2 Typedef reductions matching

    @@ -1269,58 +1299,77 @@ void go(Struct aStruct); -

    10.3.3 Default typemaps

    +

    10.3.3 Default typemap matching rules

    +

    +If the basic pattern matching rules result in no match being made, even after typedef reductions, +the default typemap matching rules are used to look for a suitable typemap match. +These rules match a generic typemap based on the reserved SWIGTYPE base type. +For example pointers will use SWIGTYPE * and references will use SWIGTYPE &. +More precisely, the rules are based on the C++ class template partial specialization matching rules used +by C++ compilers when looking for an appropriate partial template specialization. +This means that a match is chosen from the most specialized set of generic typemap types available. For example, +when looking for a match to int const *, the rules will prefer to match SWIGTYPE const * +if available before matching SWIGTYPE *, before matching SWIGTYPE. +

    +

    Most SWIG language modules use typemaps to define the default behavior of the C primitive types. This -is entirely straightforward. For example, a set of typemaps are written like this: +is entirely straightforward. For example, a set of typemaps for primitives marshalled by value or +const reference are written like this:

    -%typemap(in) int   "convert an int";
    -%typemap(in) short "convert a short";
    -%typemap(in) float "convert a float";
    +%typemap(in) int           "... convert to int ...";
    +%typemap(in) short         "... convert to short ...";
    +%typemap(in) float         "... convert to float ...";
    +...
    +%typemap(in) const int &   "... convert ...";
    +%typemap(in) const short & "... convert ...";
    +%typemap(in) const float & "... convert ...";
     ...
     

    Since typemap matching follows all typedef declarations, any sort of type that is -mapped to a primitive type through typedef will be picked up by one of these primitive typemaps. +mapped to a primitive type by value or const reference through typedef will be picked +up by one of these primitive typemaps. +Most language modules also define typemaps for char pointers and char arrays to handle strings, +so these non-default types will also be used in preference as the basic typemap matching rules +provide a better match than the default typemap matching rules.

    -The default behavior for pointers, arrays, references, and other kinds of types are handled by -specifying rules for variations of the reserved SWIGTYPE type. For example: +Below is a list of the typical default types supplied by language modules, showing what the "in" typemap would look like:

    -%typemap(in) SWIGTYPE *            { ... default pointer handling ...         }
    -%typemap(in) SWIGTYPE &            { ... default reference handling ...       }
    -%typemap(in) SWIGTYPE []           { ... default array handling ...           }
    -%typemap(in) enum SWIGTYPE         { ... default handling for enum values ... }
    -%typemap(in) SWIGTYPE (CLASS::*)   { ... default pointer member handling ...  } 
    +%typemap(in) SWIGTYPE &            { ... default reference handling ...                       };
    +%typemap(in) SWIGTYPE *            { ... default pointer handling ...                         };
    +%typemap(in) SWIGTYPE *const       { ... default pointer const handling ...                   };
    +%typemap(in) SWIGTYPE *const&      { ... default pointer const reference handling ...         };
    +%typemap(in) SWIGTYPE[ANY]         { ... 1D fixed size arrays handlling ...                   };
    +%typemap(in) SWIGTYPE []           { ... unknown sized array handling ...                     };
    +%typemap(in) enum SWIGTYPE         { ... default handling for enum values ...                 };
    +%typemap(in) const enum SWIGTYPE & { ... default handling for const enum reference values ... };
    +%typemap(in) SWIGTYPE (CLASS::*)   { ... default pointer member handling ...                  };
    +%typemap(in) SWIGTYPE              { ... simple default handling ...                          };
     

    -These rules match any kind of pointer, reference, or array--even when -multiple levels of indirection or multiple array dimensions are used. -Therefore, if you wanted to change SWIG's default handling for all -types of pointers, you would simply redefine the rule for SWIGTYPE -*. -

    - -

    -Finally, the following typemap rule is used to match against simple types that don't match any other rules: +If you wanted to change SWIG's default handling for +simple pointers, you would simply redefine the rule for SWIGTYPE *. +Note, the simple default typemap rule is used to match against simple types that don't match any other rules:

    -%typemap(in) SWIGTYPE   { ... handle an unknown type ... }
    +%typemap(in) SWIGTYPE              { ... simple default handling ...                          } 
     
    @@ -1339,7 +1388,7 @@ double dot_product(Vector a, Vector b);

    The Vector type will usually just get matched against SWIGTYPE. The default implementation of SWIGTYPE is -to convert the value into pointers (as described in chapter 3). +to convert the value into pointers (as described in this earlier section).

    @@ -1351,34 +1400,7 @@ objects into strings instead of converting them to pointers.

    -The best way to explore the default typemaps is to look at the ones -already defined for a particular language module. Typemaps -definitions are usually found in the SWIG library in a file such as -python.swg, tcl8.swg, etc. -

    - -

    10.3.4 Mixed default typemaps

    - - -

    -The default typemaps described above can be mixed with const and with each other. -For example the SWIGTYPE * typemap is for default pointer handling, but if a const SWIGTYPE * typemap -is defined it will be used instead for constant pointers. Some further examples follow: -

    - -
    -
    -%typemap(in) enum SWIGTYPE &        { ... enum references ...                       }
    -%typemap(in) const enum SWIGTYPE &  { ... const enum references ...                 }
    -%typemap(in) SWIGTYPE *&            { ... pointers passed by reference ...          }
    -%typemap(in) SWIGTYPE * const &     { ... constant pointers passed by reference ... }
    -%typemap(in) SWIGTYPE[ANY][ANY]     { ... 2D arrays ...                             }
    -
    -
    - -

    -Note that the the typedef reduction described earlier is also used with these mixed default typemaps. -For example, say the following typemaps are defined and SWIG is looking for the best match for the enum shown below: +Let's consider an example where the following typemaps are defined and SWIG is looking for the best match for the enum shown below:

    @@ -1397,16 +1419,25 @@ const Hello &hi;

    The typemap at the top of the list will be chosen, not because it is defined first, but because it is the closest match for the type being wrapped. If any of the typemaps in the above list were not defined, then the next one on the list would have precedence. -In other words the typemap chosen is the closest explicit match.

    -Compatibility note: The mixed default typemaps were introduced in SWIG-1.3.23, but were not used much in this version. -Expect to see them being used more and more within the various libraries in later versions of SWIG. +The best way to explore the default typemaps is to look at the ones +already defined for a particular language module. Typemap +definitions are usually found in the SWIG library in a file such as +java.swg, csharp.swg etc. +However, for many of the target languages the typemaps are hidden behind complicated macros, +so the best way to view the default typemaps, or any typemaps for that matter, +is to look at the preprocessed output by running swig -E on any interface file. +Finally the best way to view the typemap matching rules in action is via the debugging typemap pattern matching options covered later on.

    +

    +Compatibility note: The default typemap matching rules were modified in SWIG-2.0.0 from a slightly +simpler scheme to match the current C++ class template partial specialization matching rules. +

    -

    10.3.5 Multi-arguments typemaps

    +

    10.3.4 Multi-arguments typemaps

    @@ -1436,6 +1467,165 @@ but all subsequent arguments must match exactly.

    +

    10.3.5 Matching rules compared to C++ templates

    + + +

    +For those intimately familiar with C++ templates, a comparison of the typemap matching rules and template type deduction is interesting. +The two areas considered are firstly the default typemaps and their similarities to partial template specialization and secondly, non-default typemaps and their similarities to full template specialization. +

    + +

    +For default (SWIGTYPE) typemaps the rules are inspired by C++ class template +partial specialization. For example, given partial specialization for T const& : +

    + +
    +
    +template <typename T> struct X             { void a(); };
    +template <typename T> struct X< T const& > { void b(); };
    +
    +
    + +

    +The full (unspecialized) template is matched with most types, such as: +

    + +
    +
    +X< int & >            x1;  x1.a();
    +
    +
    + +

    +and the following all match the T const& partial specialization: +

    + +
    +
    +X< int *const& >      x2;  x2.b();
    +X< int const*const& > x3;  x3.b();
    +X< int const& >       x4;  x4.b();
    +
    +
    + +

    +Now, given just these two default typemaps, where T is analogous to SWIGTYPE: +

    + +
    +
    +%typemap(...) SWIGTYPE        { ... }
    +%typemap(...) SWIGTYPE const& { ... }
    +
    +
    + +

    +The generic default typemap SWIGTYPE is used with most types, such as +

    + +
    +
    +int &
    +
    +
    + +

    +and the following all match the SWIGTYPE const& typemap, just like the partial template matching: +

    + +
    +
    +int *const&
    +int const*const&
    +int const&
    +
    +
    + +

    +Note that the template and typemap matching rules are not identical for all default typemaps though, for example, with arrays. +

    + +

    +For non-default typemaps, one might expect SWIG to follow the fully specialized template rules. +This is nearly the case, but not quite. +Consider a very similar example to the earlier partially specialized template but this time there is a fully specialized template: +

    + +
    +
    +template <typename T> struct Y       { void a(); };
    +template <> struct Y< int const & >  { void b(); };
    +
    +
    + +

    +Only the one type matches the specialized template exactly: +

    + +
    +
    +Y< int & >             y1;  y1.a();
    +Y< int *const& >       y2;  y2.a();
    +Y< int const *const& > y3;  y3.a();
    +Y< int const& >        y4;  y4.b(); // fully specialized match
    +
    +
    + +

    +Given typemaps with the same types used for the template declared above, where T is again analogous to SWIGTYPE: +

    + +
    +
    +%typemap(...) SWIGTYPE        { ... }
    +%typemap(...) int const&      { ... }
    +
    +
    + +

    +The comparison between non-default typemaps and fully specialized single parameter templates turns out to be the same, as just the one type will match the non-default typemap: +

    + +
    +
    +int &
    +int *const&
    +int const*const&
    +int const&        // matches non-default typemap int const&
    +
    +
    + +

    +However, if a non-const type is used instead: +

    + +
    +
    +%typemap(...) SWIGTYPE        { ... }
    +%typemap(...) int &           { ... }
    +
    +
    + +

    +then there is a clear difference to template matching as both the const and non-const types match the typemap: +

    + +
    +
    +int &             // matches non-default typemap int &
    +int *const&
    +int const*const&
    +int const&        // matches non-default typemap int &
    +
    +
    + +

    +There are other subtle differences such as typedef handling, but at least it should be clear that the typemap matching rules +are similar to those for specialized template handling. +

    + +

    10.3.6 Debugging typemap pattern matching

    @@ -1501,9 +1691,18 @@ example.h:3: Searching for a suitable 'in' typemap for: Row4 rows[10]

    showing that the best default match supplied by SWIG is the SWIGTYPE [] typemap. -As the example shows, the successful match displays just the typemap method name and type in this format: %typemap(method) type. +As the example shows, the successful match displays the used typemap source including typemap method, type and optional name in one of these simplified formats: +

    + +
      +
    • Using: %typemap(method) type name +
    • Using: %typemap(method) type name = type2 name2 +
    • Using: %apply type2 name2 { type name } +
    + +

    This information might meet your debugging needs, however, you might want to analyze further. -If you next invoke SWIG with the -E option to display the preprocessed output, and search for this particular typemap, +If you next invoke SWIG with the -E option to display the preprocessed output, and search for the particular typemap used, you'll find the full typemap contents (example shown below for Python):

    @@ -1543,7 +1742,7 @@ SWIGINTERN PyObject *_wrap_foo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {

    Searches for multi-argument typemaps are not mentioned unless a matching multi-argument typemap does actually exist. -For example, the output for the code in the previous section is as follows: +For example, the output for the code in the earlier multi-arguments section is as follows:

    @@ -1560,7 +1759,7 @@ example.h:39: Searching for a suitable 'in' typemap for: char *buffer

    The second option for debugging is -debug-tmused and this displays the typemaps used. This option is a less verbose version of the -debug-tmsearch option as it only displays each successfully found typemap on a separate single line. -The output displays the type, and name if present, the typemap method in brackets and then the actual typemap used. +The output displays the type, and name if present, the typemap method in brackets and then the actual typemap used in the same simplified format output by the -debug-tmsearch option. Below is the output for the example code at the start of this section on debugging.

    @@ -1623,6 +1822,8 @@ example.i:21: Typemap for void set_value (out) : %typemap(out) void

    The following observations about what is displayed can be noted (the same applies for -debug-tmsearch): +

    +
    • The relevant typemap is shown, but for typemap copying, the appropriate %typemap or %apply is displayed, for example, the "check" and "in" typemaps.
    • @@ -1633,7 +1834,7 @@ The typemap modifiers are not shown, eg the noblock=1 modifier in the " The exact %apply statement might look different to what is in the actual code. For example, the const char* another_value is not shown as it is not relevant here. Also the types may be displayed slightly differently - char const * and not const char*. -

      +

    10.4 Code generation rules

    @@ -1709,12 +1910,16 @@ Occasionally, typemap code will be specified using a few alternative forms. For %typemap(in) int %{ $1 = PyInt_AsLong($input); %} +%typemap(in, noblock=1) int { +$1 = PyInt_AsLong($input); +}

    -These two forms are mainly used for cosmetics--the specified code is not enclosed inside +These three forms are mainly used for cosmetics--the specified code is not enclosed inside a block scope when it is emitted. This sometimes results in a less complicated looking wrapper function. +Note that only the third of the three typemaps have the typemap code passed through the SWIG preprocessor.

    10.4.2 Declaring new local variables

    @@ -1843,7 +2048,7 @@ wrap_foo() {

    Some typemaps do not recognize local variables (or they may simply not -apply). At this time, only typemaps that apply to argument conversion support this. +apply). At this time, only typemaps that apply to argument conversion support this (input typemaps such as the "in" typemap).

    @@ -2260,7 +2465,7 @@ When numinputs is set to 0, the argument is effectively ignored and can The argument is still required when making the C/C++ call and the above typemap shows the value used is instead obtained from a locally declared variable called temp. Usually numinputs is not specified, whereupon the default value is 1, that is, there is a one to one mapping of the number of arguments when used from the target language to the C/C++ call. -Multi-argument typemaps provide a similar concept where the number of arguments mapped from the target language to C/C++ can be changed for more tha multiple adjacent C/C++ arguments. +Multi-argument typemaps provide a similar concept where the number of arguments mapped from the target language to C/C++ can be changed for multiple adjacent C/C++ arguments.

    @@ -2291,7 +2496,7 @@ the input argument is the correct type.

    If you define new "in" typemaps and your program uses overloaded methods, you should also define a collection of -"typecheck" typemaps. More details about this follow in a later section on "Typemaps and Overloading." +"typecheck" typemaps. More details about this follow in the Typemaps and overloading section.

    10.5.3 "out" typemap

    @@ -2439,7 +2644,7 @@ return values are often appended to return value of the function.

    -See the typemaps.i library for examples. +See the typemaps.i library file for examples.

    10.5.8 "freearg" typemap

    @@ -2501,7 +2706,7 @@ string *foo();

    -See Object ownership and %newobject for further details. +See Object ownership and %newobject for further details.

    10.5.10 "memberin" typemap

    @@ -2585,7 +2790,7 @@ catch(char const *_e) {

    Note that if your methods do not have an exception specification yet they do throw exceptions, SWIG cannot know how to deal with them. -For a neat way to handle these, see the Exception handling with %exception section. +For a neat way to handle these, see the Exception handling with %exception section.

    10.6 Some typemap examples

    @@ -2764,9 +2969,8 @@ You may even get a warning message like this:

    -swig -python  example.i
    -Generating wrappers for Python
    -example.i:10.  Warning. Array member value will be read-only.
    +$ swig -python  example.i
    +example.i:10: Warning 462: Unable to set variable of type float [4].
     

    @@ -2863,7 +3067,7 @@ useless and has since been eliminated. To return structure members, simply use One particularly interesting application of typemaps is the implementation of argument constraints. This can be done with the "check" typemap. When used, this allows you to provide code for -checking the values of function arguments. For example :

    +checking the values of function arguments. For example:

     %module math
    @@ -2886,7 +3090,7 @@ your program terminated with an error message.

    This kind of checking can be particularly useful when working with -pointers. For example :

    +pointers. For example:

     %typemap(check) Vector * {
    @@ -2904,10 +3108,6 @@ a NULL pointer. As a result, SWIG can often prevent a potential
     segmentation faults or other run-time problems by raising an exception
     rather than blindly passing values to the underlying C/C++ program.

    -

    -Note: A more advanced constraint checking system is in development. Stay tuned. -

    -

    10.7 Typemaps for multiple target languages

    @@ -2984,7 +3184,7 @@ struct XX {

    -The "out" typemap shown is the default typemap for C# when returning by objects by value. +The "out" typemap shown is the default typemap for C# when returning objects by value. When making a call to XX::create() from C#, the output is as follows:

    @@ -3073,7 +3273,7 @@ what the "optimal" attribute is telling SWIG to do.

    The "optimal" attribute optimisation is not turned on by default as it has a number of restrictions. Firstly, some code cannot be condensed into a simple call for passing into the copy constructor. -One common occurrence is when %exception is used. +One common occurrence is when %exception is used. Consider adding the following %exception to the example:

    @@ -3106,7 +3306,7 @@ try {

    -It should be clear that the above code cannot be used as the argument to the copy constructor call, ie for the $1 substitution. +It should be clear that the above code cannot be used as the argument to the copy constructor call, that is, for the $1 substitution.

    @@ -3157,14 +3357,14 @@ list of strings like this:

    To do this, you not only need to map a list of strings to char *argv[], but the value of int argc is implicitly determined by the length of the list. Using only simple -typemaps, this type of conversion is possible, but extremely painful. Therefore, SWIG1.3 -introduces the notion of multi-argument typemaps. +typemaps, this type of conversion is possible, but extremely painful. +Multi-argument typemaps help in this situation.

    A multi-argument typemap is a conversion rule that specifies how to -convert a single object in the target language to set of -consecutive function arguments in C/C++. For example, the following multi-argument +convert a single object in the target language to a set of +consecutive function arguments in C/C++. For example, the following multi-argument maps perform the conversion described for the above example:

    @@ -3388,10 +3588,340 @@ this, you could write a multi-argument typemap like this: This kind of technique can be used to hook into scripting-language matrix packages such as Numeric Python. However, it should also be stressed that some care is in order. For example, when crossing languages you may need to worry about issues such as row-major vs. column-major -ordering (and perform conversions if needed). +ordering (and perform conversions if needed). Note that multi-argument typemaps cannot deal +with non-consecutive C/C++ arguments; a workaround such as a helper function re-ordering +the arguments to make them consecutive will need to be written.

    -

    10.10 The run-time type checker

    +

    10.10 Typemap fragments

    + + +

    +The primary purpose of fragments is to reduce code bloat that repeated use of typemap code can lead to. +Fragments are snippets of code that can be thought of as code dependencies of a typemap. +If a fragment is used by more than one typemap, then the snippet of code within the fragment is only generated once. +Code bloat is typically reduced by moving typemap code into a support function +and then placing the support function into a fragment. +

    + +

    +For example, if you have a very long typemap +

    + +
    +
    +%typemap(in) MyClass * {
    +  MyClass *value = 0;
    +
    +  ... many lines of marshalling code  ...
    +
    +  $result = value;
    +}
    +
    +
    + +

    +the same marshalling code is often repeated in several typemaps, such as "in", "varin", "directorout", etc. +SWIG copies the code for each argument that requires the typemap code, easily leading to code bloat +in the generated code. +To eliminate this, define a fragment that includes the common marshalling code: +

    + +
    +
    +%fragment("AsMyClass", "header") {
    +  MyClass *AsMyClass(PyObject *obj) {
    +    MyClass *value = 0;
    +
    +    ... many lines of marshalling code  ...
    +
    +    return value;
    +  }
    +}
    +
    +%typemap(in, fragment="AsMyClass") MyClass * {
    +  $result = AsMyClass($input);
    +}
    +
    +%typemap(varin, fragment="AsMyClass") MyClass * {
    +  $result = AsMyClass($input);
    +}
    +
    +
    + +

    +When the "in" or "varin" typemaps for MyClass are required, the +contents of the fragment called "AsMyClass" is added to the "header" section within the generated code, and then the +typemap code is emitted. Hence, the method AsMyClass will be +generated into the wrapper code before any typemap code that calls it. +

    + +

    +To define a fragment you need a fragment name, a section name for generating the fragment code into, and the code itself. +See Code insertion blocks for a full list of section names. +Usually the section name used is "header". Both string and curly braces can be used: +

    + +
    +
    +%fragment("my_name", "header") { ... }
    +%fragment("my_name", "header") " ... "
    +
    +
    + +

    +The following are some rules and guidelines for using fragments: +

    + +
      +
    1. +

      +A fragment is added to the wrapping code only once. When using the MyClass * typemaps above and wrapping the method: +

      + +
      +
      +void foo(MyClass *a, MyClass *b);
      +
      +
      + +

      +the generated code will look something like: +

      + +
      +
      +MyClass *AsMyClass(PyObject *obj) {
      +  ...
      +}
      +
      +void _wrap_foo(...) {
      +  ....
      +  arg1 = AsMyClass(obj1);
      +  arg2 = AsMyClass(obj2);
      +  ...
      +  foo(arg1, arg2);
      +}
      +
      +
      + +

      +even as there is duplicated typemap code to process both a and +b, the AsMyClass method will be defined only once. +

      + +
    2. +

      +A fragment should only be defined once. If there is more than +one definition, the first definition is the one used. +All other definitions are silently ignored. For example, if you have +

      + + +
      +
      +%fragment("AsMyClass", "header") { ...definition 1... }
      +....
      +%fragment("AsMyClass", "header") { ...definition 2... }
      +
      +
      + +

      +only the first definition is used. In this way +you can override the default fragments in a SWIG library by defining your fragment before the library %include. +Note that this behavior is the opposite to typemaps, where the last typemap defined/applied prevails. +Fragments follow the first-in-first-out convention since they are intended to be global, +while typemaps are intended to be locally specialized. +

      + +
    3. +

      +Fragment names cannot contain commas. +

      + + +
    4. +

      +A fragment can use one or more additional fragments, for example: +

      + +
      +
      +%fragment("<limits.h>", "header")  {
      +  #include <limits.h>
      +}
      +
      +
      +%fragment("AsMyClass", "header", fragment="<limits.h>") {
      +  MyClass *AsMyClass(PyObject *obj) {
      +    MyClass *value = 0;
      +
      +    ... some marshalling code  ...
      +
      +    if  (ival < CHAR_MIN /*defined in <limits.h>*/) {
      +       ...
      +    } else {
      +       ...
      +    }
      +    ...
      +    return value;
      +  }
      +}
      +
      +
      + +

      +in this case, when the "AsMyClass" fragment is emitted, it also +triggers the inclusion of the "<limits.h>" fragment. +

      + +
    5. +

      +A fragment can have dependencies on a number of other fragments, for example: +

      + +
      +
      +%fragment("bigfragment", "header", fragment="frag1", fragment="frag2", fragment="frag3") "";
      +
      +
      + +

      +When the "bigfragment" is used, the three dependent fragments "frag1", +"frag2" and "frag3" are also pulled in. Note that as "bigframent" is +empty (the empty string - ""), it does not add any code itself, but merely triggers the +inclusion of the other fragments. +

      + +
    6. +

      +A typemap can also use more than one fragment, but since the +syntax is different, you need to specify the dependent fragments in a comma separated +list. Consider: +

      + +
      +
      +%typemap(in, fragment="frag1,frag2,frag3") {...}
      +
      +
      + +

      +which is equivalent to: +

      + +
      +
      +%typemap(in, fragment="bigfragment") {...}
      +
      +
      + +

      +when used with the "bigfragment" defined above. +

      + +
    7. +

      +Finally, you can force the inclusion of a fragment at any point in the generated code as follows: +

      + +
      +
      +%fragment("bigfragment");
      +
      +
      + +

      +which is very useful inside a template class, for example. +

      +
    + +

    +Most readers will probably want to skip the next two sub-sections on advanced +fragment usage unless a desire to really get to grips +with some powerful but tricky macro and fragment usage that is used in parts of the SWIG typemap library. +

    + +

    10.10.1 Fragment type specialization

    + + +

    +Fragments can be type specialized. The syntax is as follows: +

    + +
    +
    +%fragment("name", "header") { ...a type independent fragment... }
    +%fragment("name"{type}, "header") { ...a type dependent fragment...  }
    +
    +
    + +

    +where type is a C/C++ type. Like typemaps, fragments can also be used inside templates, for example: +

    + +
    +
    +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>} ...
    +  }
    +};
    +
    +
    + +

    10.10.2 Fragments and automatic typemap specialization

    + + +

    +Since fragments can be type specialized, they can be elegantly used +to specialize typemaps. For example, if you have something like: +

    + +
    +
    +%fragment("incode"{float}, "header") {
    +  float in_method_float(PyObject *obj) {
    +    ...
    +  }
    +}
    +
    +%fragment("incode"{long}, "header") {
    +  float in_method_long(PyObject *obj) {
    +    ...
    +  }
    +}
    +
    +// %my_typemaps macro definition
    +%define %my_typemaps(Type) 
    +%typemap(in, fragment="incode"{Type}) Type {
    +  value = in_method_##Type(obj);
    +}
    +%enddef
    +
    +%my_typemaps(float);
    +%my_typemaps(long);
    +
    +
    + +

    +then the proper "incode"{float} or "incode"{long} fragment will be used, +and the in_method_float and in_method_long methods will be called whenever +the float or long types are used as input parameters. +

    + +

    +This feature is used a lot in the typemaps shipped in the SWIG library for some scripting languages. +The interested (or very brave) reader can take a look at the fragments.swg file shipped with SWIG to see this in action. +

    + + +

    10.11 The run-time type checker

    @@ -3417,7 +3947,7 @@ language modules.

  • Modules can be unloaded from the type system.
  • -

    10.10.1 Implementation

    +

    10.11.1 Implementation

    @@ -3603,12 +4133,12 @@ structures rather than creating new ones. These swig_module_info structures are chained together in a circularly linked list.

    -

    10.10.2 Usage

    +

    10.11.2 Usage

    This section covers how to use these functions from typemaps. To learn how to call these functions from external files (not the generated _wrap.c file), see -the External access to the run-time system +the External access to the run-time system section.

    When pointers are converted in a typemap, the typemap code often looks @@ -3691,17 +4221,19 @@ interface file.

    Further details about the run-time type checking can be found in the documentation for individual language modules. Reading the source code may also help. The file -Lib/swigrun.swg in the SWIG library contains all of the source code for +Lib/swigrun.swg in the SWIG library contains all of the source of the generated code for type-checking. This code is also included in every generated wrapped file so you probably just look at the output of SWIG to get a better sense for how types are managed.

    -

    10.11 Typemaps and overloading

    +

    10.12 Typemaps and overloading

    -In many target languages, SWIG fully supports C++ overloaded methods and functions. For example, +This section does not apply to the statically typed languages like Java and C#, where overloading +of the types is handled much like C++ by generating overloaded methods in the target language. +In many of the other target languages, SWIG still fully supports C++ overloaded methods and functions. For example, if you have a collection of functions like this:

    @@ -4006,7 +4538,7 @@ Subsequent "in" typemaps would then perform more extensive type-checking. -

    10.12 More about %apply and %clear

    +

    10.13 More about %apply and %clear

    @@ -4091,86 +4623,6 @@ example: -

    10.13 Reducing wrapper code size

    - - -

    -Since the code supplied to a typemap is inlined directly into wrapper functions, typemaps can result -in a tremendous amount of code bloat. For example, consider this typemap for an array: -

    - -
    -
    -%typemap(in) float [ANY] {
    -  int i;
    -  if (!PySequence_Check($input)) {
    -    PyErr_SetString(PyExc_ValueError,"Expected a sequence");
    -    return NULL;
    -  }
    -  if (PySequence_Length($input) != $1_dim0) {
    -    PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements");
    -    return NULL;
    -  }
    -  $1 = (float) malloc($1_dim0*sizeof(float));
    -  for (i = 0; i < $1_dim0; i++) {
    -    PyObject *o = PySequence_GetItem($input,i);
    -    if (PyNumber_Check(o)) {
    -      $1[i] = (float) PyFloat_AsDouble(o);
    -    } else {
    -      PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");      
    -      free(result);
    -      return NULL;
    -    }
    -  }
    -}
    -
    -
    - -

    -If you had a large interface with hundreds of functions all accepting -array parameters, this typemap would be replicated -repeatedly--generating a huge amount of code. A better approach might -be to consolidate some of the typemap into a function. For example: -

    - -
    -
    -%{
    -/* Define a helper function */
    -static float *
    -convert_float_array(PyObject *input, int size) {
    -  int i;
    -  float *result;
    -  if (!PySequence_Check(input)) {
    -    PyErr_SetString(PyExc_ValueError,"Expected a sequence");
    -    return NULL;
    -  }
    -  if (PySequence_Length(input) != size) {
    -    PyErr_SetString(PyExc_ValueError,"Size mismatch. ");
    -    return NULL;
    -  }
    -  result = (float) malloc(size*sizeof(float));
    -  for (i = 0; i < size; i++) {
    -    PyObject *o = PySequence_GetItem(input,i);
    -    if (PyNumber_Check(o)) {
    -      result[i] = (float) PyFloat_AsDouble(o);
    -    } else {
    -      PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");
    -      free(result);       
    -      return NULL;
    -    }
    -  }
    -  return result;
    -}
    -%}
    -
    -%typemap(in) float [ANY] {
    -    $1 = convert_float_array($input, $1_dim0);
    -    if (!$1) return NULL;
    -}
    -%}
    -
    -

    10.14 Passing data between typemaps

    @@ -4213,7 +4665,7 @@ sure that the typemaps sharing information have exactly the same types and names

    -All the rules discussed for Typemaps apply to C++ as well as C. +All the rules discussed for typemaps apply to C++ as well as C. However in addition C++ passes an extra parameter into every non-static class method -- the this pointer. Occasionally it can be useful to apply a typemap to this pointer (for example to check @@ -4233,7 +4685,8 @@ For example, if wrapping for Java generation:

     %typemap(check) SWIGTYPE *self %{
     if (!$1) {
    -  SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "swigCPtr null");
    +  SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException,
    +    "invalid native object; delete() likely already called");
       return $null;
     }
     %}
    @@ -4258,14 +4711,14 @@ The generated code will look something like:
           "invalid native object; delete() likely already called");
         return ;
       }
    -  (arg1)->wrappedFunction(...);
    +  (arg1)->wrappedFunction(...);
     

    Note that if you have a parameter named self then it will also match the typemap. One work around is to create an interface file that wraps -the method, but give the argument a name other than self. +the method, but gives the argument a name other than self.

    10.16 Where to go for more information?

    diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html index 5409248c9..96e35902a 100644 --- a/Doc/Manual/Warnings.html +++ b/Doc/Manual/Warnings.html @@ -102,7 +102,7 @@ int foo(double); // Silently ignored.

    The %warnfilter directive has the same semantics as other declaration modifiers like %rename, %ignore and %feature, see the -%feature directive section. For example, if you wanted to +%feature directive section. For example, if you wanted to suppress a warning for a method in a class hierarchy, you could do this:

    diff --git a/Doc/Manual/Windows.html b/Doc/Manual/Windows.html index 5d16a8b9f..da8a5d6bf 100644 --- a/Doc/Manual/Windows.html +++ b/Doc/Manual/Windows.html @@ -67,7 +67,7 @@ SWIG does not come with the usual Windows type installation program, however it

    -The swigwin distribution contains the SWIG Windows executable, swig.exe, which will run on 32 bit versions of Windows, ie Windows 95/98/ME/NT/2000/XP. +The swigwin distribution contains the SWIG Windows executable, swig.exe, which will run on 32 bit versions of Windows, ie Windows 95 and later. If you want to build your own swig.exe have a look at Building swig.exe on Windows.

    @@ -78,7 +78,7 @@ If you want to build your own swig.exe have a look at
  • Answer y to the "do you have MinGW installed?"
  • -
  • Type in the the folder in which you installed MinGW (C:/MinGW is default)
  • +
  • Type in the folder in which you installed MinGW (C:/MinGW is default)
  • diff --git a/Doc/Manual/chapters b/Doc/Manual/chapters index af1c07773..cdd4ef635 100644 --- a/Doc/Manual/chapters +++ b/Doc/Manual/chapters @@ -18,6 +18,7 @@ CCache.html Allegrocl.html CSharp.html Chicken.html +Go.html Guile.html Java.html Lisp.html diff --git a/Doc/Manual/index.html b/Doc/Manual/index.html index 8560a9199..30c69578f 100644 --- a/Doc/Manual/index.html +++ b/Doc/Manual/index.html @@ -1,10 +1,10 @@ -SWIG-1.3 Documentation +SWIG-2.0 Documentation -

    SWIG-1.3 Development Documentation

    +

    SWIG-2.0 Documentation

    The SWIG documentation is available in one of the following formats.
      diff --git a/Examples/Makefile.in b/Examples/Makefile.in index daee3d220..7fe78f359 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -85,6 +85,11 @@ CXXSHARED= @CXXSHARED@ OBJS = $(SRCS:.c=.@OBJEXT@) $(CXXSRCS:.cxx=.@OBJEXT@) +distclean: + rm -f Makefile + rm -f guile/Makefile + rm -f xml/Makefile + ################################################################## ##### Tcl/Tk ###### ################################################################## @@ -342,7 +347,7 @@ OCTAVE_SO = @OCTAVE_SO@ octave: $(SRCS) $(SWIG) -octave $(SWIGOPT) $(INTERFACEPATH) $(CXX) -g -c $(CCSHARED) $(CXXFLAGS) $(ICXXSRCS) $(CXXSRCS) $(INCLUDES) -I$(OCTAVE_INCLUDE) - $(CC) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(INCLUDES) + $(CC) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(CSRCS) $(INCLUDES) $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO) # ----------------------------------------------------------------- @@ -1125,11 +1130,11 @@ RRSRC = $(INTERFACE:.i=.R) r: $(SRCS) $(SWIG) -r $(SWIGOPT) $(INTERFACEPATH) - +( PKG_LIBS="$(SRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -fPIC -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) ) + +( PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) $(SRCS) ) r_cpp: $(CXXSRCS) $(SWIG) -c++ -r $(SWIGOPT) -o $(RCXXSRCS) $(INTERFACEPATH) - +( PKG_LIBS="$(CXXSRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -fPIC -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) ) + +( PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) $(SRCS) $(CXXSRCS)) r_clean: rm -f *_wrap* *~ .~* @@ -1137,3 +1142,74 @@ r_clean: rm -f *.@OBJEXT@ *@SO@ NAMESPACE rm -f $(RRSRC) runme.Rout .RData +################################################################## +##### Go ###### +################################################################## + +GO = @GO@ +GOGCC = @GOGCC@ + +GOSWIGARG = `if $(GOGCC) ; then echo -gccgo; fi` +GOCOMPILEARG = `if $(GOGCC) ; then echo -c -g; fi` + +GOSRCS = $(INTERFACE:.i=.go) +GOCSRCS = $(INTERFACE:.i=_gc.c) + +GOC = $(GO:g=c) +GOLD = $(GO:g=l) + +GOPACKAGE = $(INTERFACE:.i=.a) + +GOOBJEXT = $(GO:g=) +GOGCOBJS = $(GOSRCS:.go=.$(GOOBJEXT)) +GOGCCOBJS = $(GOSRCS:.go=.@OBJEXT@) + +# ---------------------------------------------------------------- +# Build a Go dynamically loadable module (C) +# ---------------------------------------------------------------- + +go: $(SRCS) + $(SWIG) -go $(GOSWIGARG) $(SWIGOPT) $(INTERFACEPATH) + $(CC) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) + $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + $(COMPILETOOL) $(GO) -I . $(GOCOMPILEARG) $(GOSRCS) + if ! $(GOGCC) ; then \ + $(COMPILETOOL) $(GOC) -I $${GOROOT}/pkg/$${GOOS}_$${GOARCH} $(GOCSRCS) && \ + $(COMPILETOOL) gopack grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)); \ + fi + +# ---------------------------------------------------------------- +# Build a Go dynamically loadable module (C++) +# ---------------------------------------------------------------- + +go_cpp: $(SRCS) + $(SWIG) -go -c++ $(GOSWIGARG) $(SWIGOPT) $(INTERFACEPATH) + $(CXX) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) + $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + $(COMPILETOOL) $(GO) -I . $(GOCOMPILEARG) $(GOSRCS) + if ! $(GOGCC) ; then \ + $(COMPILETOOL) $(GOC) -I $${GOROOT}/pkg/$${GOOS}_$${GOARCH} $(GOCSRCS) && \ + $(COMPILETOOL) gopack grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)); \ + fi + +# ----------------------------------------------------------------- +# Running a Go example +# ----------------------------------------------------------------- + +go_run: runme.go + $(GO) $(GOCOMPILEARG) runme.go + if $(GOGCC) ; then \ + $(COMPILETOOL) $(GO) -o runme runme.@OBJEXT@ $(GOGCCOBJS) $(LIBPREFIX)$(TARGET)$(SO); \ + else \ + $(COMPILETOOL) $(GOLD) -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o runme runme.$(GOOBJEXT); \ + fi + env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) ./runme + +# ----------------------------------------------------------------- +# Cleaning the Go examples +# ----------------------------------------------------------------- + +go_clean: + rm -f *_wrap* *_gc* .~* runme + rm -f core @EXTRA_CLEAN@ + rm -f *.@OBJEXT@ *.[568] *.a *@SO@ diff --git a/Examples/README b/Examples/README index 0747547cb..4dda3222d 100644 --- a/Examples/README +++ b/Examples/README @@ -2,9 +2,7 @@ SWIG Examples The "perl5", "python", "tcl", "guile", "java", "mzscheme", "ruby", and "chicken" directories contain a number of simple examples that are -primarily used for testing. The "GIFPlot" directory contains a more -complicated example that illustrates some of SWIG's more advanced -capabilities. +primarily used for testing. The file 'index.html' is the top of a hyperlinked document that contains information about all of the examples along with various diff --git a/Examples/go/callback/Makefile b/Examples/go/callback/Makefile new file mode 100644 index 000000000..9dc8b8851 --- /dev/null +++ b/Examples/go/callback/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: go + +go:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/callback/example.cxx b/Examples/go/callback/example.cxx new file mode 100644 index 000000000..450d75608 --- /dev/null +++ b/Examples/go/callback/example.cxx @@ -0,0 +1,4 @@ +/* File : example.cxx */ + +#include "example.h" + diff --git a/Examples/go/callback/example.go b/Examples/go/callback/example.go new file mode 100644 index 000000000..5c0cfb051 --- /dev/null +++ b/Examples/go/callback/example.go @@ -0,0 +1,188 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +type _swig_DirectorCallback struct { + SwigcptrCallback + v interface{} +} + +func (p *_swig_DirectorCallback) Swigcptr() uintptr { + return p.SwigcptrCallback.Swigcptr() +} + +func (p *_swig_DirectorCallback) SwigIsCallback() { +} + +func (p *_swig_DirectorCallback) DirectorInterface() interface{} { + return p.v +} + +func _swig_NewDirectorCallbackCallback(*_swig_DirectorCallback) SwigcptrCallback + +func NewDirectorCallback(v interface{}) Callback { + p := &_swig_DirectorCallback{0, v} + p.SwigcptrCallback = _swig_NewDirectorCallbackCallback(p) + return p +} + +func _swig_wrap_DeleteDirectorCallback(uintptr) + +func DeleteDirectorCallback(arg1 Callback) { + _swig_wrap_DeleteDirectorCallback(arg1.Swigcptr()) +} + +func Swiggo_DeleteDirector_Callback(p *_swig_DirectorCallback) { + p.SwigcptrCallback = 0 +} + +type _swig_DirectorInterfaceCallbackRun interface { + Run() +} + +func _swig_wrap__swig_DirectorCallback_upcall_Run(SwigcptrCallback) +func (swig_p *_swig_DirectorCallback) Run() { + if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceCallbackRun); swig_ok { + swig_g.Run() + return + } + _swig_wrap__swig_DirectorCallback_upcall_Run(swig_p.SwigcptrCallback) +} + +func DirectorCallbackRun(p Callback) { + _swig_wrap__swig_DirectorCallback_upcall_Run(p.(*_swig_DirectorCallback).SwigcptrCallback) +} + +func Swig_DirectorCallback_callback_run(p *_swig_DirectorCallback) { + p.Run() +} + +type SwigcptrCallback uintptr + +func (p SwigcptrCallback) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrCallback) SwigIsCallback() { +} + +func (p SwigcptrCallback) DirectorInterface() interface{} { + return nil +} + +func _swig_wrap_delete_Callback(uintptr) + +func DeleteCallback(arg1 Callback) { + _swig_wrap_delete_Callback(arg1.Swigcptr()) +} + +func _swig_wrap_Callback_run(SwigcptrCallback) + +func (arg1 SwigcptrCallback) Run() { + _swig_wrap_Callback_run(arg1) +} + +func _swig_wrap_new_Callback() SwigcptrCallback + +func NewCallback() Callback { + return _swig_wrap_new_Callback() +} + +type Callback interface { + Swigcptr() uintptr + SwigIsCallback() + DirectorInterface() interface{} + Run() +} + +type SwigcptrCaller uintptr + +func (p SwigcptrCaller) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrCaller) SwigIsCaller() { +} + +func _swig_wrap_new_Caller() SwigcptrCaller + +func NewCaller() Caller { + return _swig_wrap_new_Caller() +} + +func _swig_wrap_delete_Caller(uintptr) + +func DeleteCaller(arg1 Caller) { + _swig_wrap_delete_Caller(arg1.Swigcptr()) +} + +func _swig_wrap_Caller_delCallback(SwigcptrCaller) + +func (arg1 SwigcptrCaller) DelCallback() { + _swig_wrap_Caller_delCallback(arg1) +} + +func _swig_wrap_Caller_setCallback(SwigcptrCaller, uintptr) + +func (arg1 SwigcptrCaller) SetCallback(arg2 Callback) { + _swig_wrap_Caller_setCallback(arg1, arg2.Swigcptr()) +} + +func _swig_wrap_Caller_call(SwigcptrCaller) + +func (arg1 SwigcptrCaller) Call() { + _swig_wrap_Caller_call(arg1) +} + +type Caller interface { + Swigcptr() uintptr + SwigIsCaller() + DelCallback() + SetCallback(arg2 Callback) + Call() +} + + +type SwigcptrSwigDirector_Callback uintptr +type SwigDirector_Callback interface { + Swigcptr() uintptr; +} +func (p SwigcptrSwigDirector_Callback) Swigcptr() uintptr { + return uintptr(p) +} + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/callback/example.h b/Examples/go/callback/example.h new file mode 100644 index 000000000..1a0e8c432 --- /dev/null +++ b/Examples/go/callback/example.h @@ -0,0 +1,23 @@ +/* File : example.h */ + +#include +#include + +class Callback { +public: + virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; } + virtual void run() { std::cout << "Callback::run()" << std::endl; } +}; + + +class Caller { +private: + Callback *_callback; +public: + Caller(): _callback(0) {} + ~Caller() { delCallback(); } + void delCallback() { delete _callback; _callback = 0; } + void setCallback(Callback *cb) { delCallback(); _callback = cb; } + void call() { if (_callback) _callback->run(); } +}; + diff --git a/Examples/go/callback/example.i b/Examples/go/callback/example.i new file mode 100644 index 000000000..90beda01a --- /dev/null +++ b/Examples/go/callback/example.i @@ -0,0 +1,13 @@ +/* File : example.i */ +%module(directors="1") example +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* turn on director wrapping Callback */ +%feature("director") Callback; + +%include "example.h" + diff --git a/Examples/go/callback/index.html b/Examples/go/callback/index.html new file mode 100644 index 000000000..b053cf547 --- /dev/null +++ b/Examples/go/callback/index.html @@ -0,0 +1,81 @@ + + +SWIG:Examples:go:callback + + + + + +SWIG/Examples/go/callback/ +
      + +

      Implementing C++ callbacks in Go

      + +

      +This example illustrates how to use directors to implement C++ +callbacks in Go. +

      + +

      +Because Go and C++ use inheritance differently, you must call a +different function to create a class which uses callbacks. Instead of +calling the usual constructor function whose name is New +followed by the capitalized name of the class, you call a function +named NewDirector followed by the capitalized name of the +class. +

      + +

      +The first argument to the NewDirector function is an instance +of a type. The NewDirector function will return an interface +value as usual. However, when calling any method on the returned +value, the program will first check whether the value passed +to NewDirector implements that method. If it does, the +method will be called in Go. This is true whether the method is +called from Go code or C++ code. +

      + +

      +Note that the Go code will be called with just the Go value, not the +C++ value. If the Go code needs to call a C++ method on itself, you +need to get a copy of the C++ object. This is typically done as +follows: + +

      +
      +type Child struct { abi Parent }
      +func (p *Child) ChildMethod() {
      +	p.abi.ParentMethod()
      +}
      +func f() {
      +	p := &Child{nil}
      +	d := NewDirectorParent(p)
      +	p.abi = d
      +	...
      +}
      +
      +
      + +In other words, we first create the Go value. We pass that to +the NewDirector function to create the C++ value; this C++ +value will be created with an association to the Go value. We then +store the C++ value in the Go value, giving us the reverse +association. That permits us to call parent methods from the child. + +

      + +

      +To delete a director object, use the function DeleteDirector +followed by the capitalized name of the class. +

      + +

      +

      + +
      + + diff --git a/Examples/go/callback/runme.go b/Examples/go/callback/runme.go new file mode 100644 index 000000000..ffa4b3874 --- /dev/null +++ b/Examples/go/callback/runme.go @@ -0,0 +1,41 @@ +package main + +import ( + "fmt" + . "./example" +) + +func main() { + fmt.Println("Adding and calling a normal C++ callback") + fmt.Println("----------------------------------------") + + caller := NewCaller() + callback := NewCallback() + + caller.SetCallback(callback) + caller.Call() + caller.DelCallback() + + callback = NewDirectorCallback(new(GoCallback)) + + fmt.Println() + fmt.Println("Adding and calling a Go callback") + fmt.Println("------------------------------------") + + caller.SetCallback(callback) + caller.Call() + caller.DelCallback() + + // Test that a double delete does not occur as the object has + // already been deleted from the C++ layer. + DeleteDirectorCallback(callback) + + fmt.Println() + fmt.Println("Go exit") +} + +type GoCallback struct{} + +func (p *GoCallback) Run() { + fmt.Println("GoCallback.Run") +} diff --git a/Examples/go/check.list b/Examples/go/check.list new file mode 100644 index 000000000..5399b8979 --- /dev/null +++ b/Examples/go/check.list @@ -0,0 +1,13 @@ +# see top-level Makefile.in +callback +class +constants +enum +extend +funcptr +multimap +pointer +reference +simple +template +variables diff --git a/Examples/go/class/Makefile b/Examples/go/class/Makefile new file mode 100644 index 000000000..53d31d1a4 --- /dev/null +++ b/Examples/go/class/Makefile @@ -0,0 +1,16 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/class/example.cxx b/Examples/go/class/example.cxx new file mode 100644 index 000000000..1e8e203dd --- /dev/null +++ b/Examples/go/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/go/class/example.go b/Examples/go/class/example.go new file mode 100644 index 000000000..ec8113ad4 --- /dev/null +++ b/Examples/go/class/example.go @@ -0,0 +1,284 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +type SwigcptrShape uintptr + +func (p SwigcptrShape) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrShape) SwigIsShape() { +} + +func _swig_wrap_delete_Shape(uintptr) + +func DeleteShape(arg1 Shape) { + _swig_wrap_delete_Shape(arg1.Swigcptr()) +} + +func _swig_wrap_Shape_x_set(SwigcptrShape, float64) + +func (arg1 SwigcptrShape) SetX(arg2 float64) { + _swig_wrap_Shape_x_set(arg1, arg2) +} + +func _swig_wrap_Shape_x_get(SwigcptrShape) float64 + +func (arg1 SwigcptrShape) GetX() float64 { + return _swig_wrap_Shape_x_get(arg1) +} + +func _swig_wrap_Shape_y_set(SwigcptrShape, float64) + +func (arg1 SwigcptrShape) SetY(arg2 float64) { + _swig_wrap_Shape_y_set(arg1, arg2) +} + +func _swig_wrap_Shape_y_get(SwigcptrShape) float64 + +func (arg1 SwigcptrShape) GetY() float64 { + return _swig_wrap_Shape_y_get(arg1) +} + +func _swig_wrap_Shape_move(SwigcptrShape, float64, float64) + +func (arg1 SwigcptrShape) Move(arg2 float64, arg3 float64) { + _swig_wrap_Shape_move(arg1, arg2, arg3) +} + +func _swig_wrap_Shape_area(SwigcptrShape) float64 + +func (arg1 SwigcptrShape) Area() float64 { + return _swig_wrap_Shape_area(arg1) +} + +func _swig_wrap_Shape_perimeter(SwigcptrShape) float64 + +func (arg1 SwigcptrShape) Perimeter() float64 { + return _swig_wrap_Shape_perimeter(arg1) +} + +func _swig_wrap_Shape_nshapes_set(int) + +func SetShapeNshapes(arg1 int) { + _swig_wrap_Shape_nshapes_set(arg1) +} + +func GetShapeNshapes() int +type Shape interface { + Swigcptr() uintptr + SwigIsShape() + SetX(arg2 float64) + GetX() float64 + SetY(arg2 float64) + GetY() float64 + Move(arg2 float64, arg3 float64) + Area() float64 + Perimeter() float64 +} + +type SwigcptrCircle uintptr + +func (p SwigcptrCircle) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrCircle) SwigIsCircle() { +} + +func _swig_wrap_new_Circle(float64) SwigcptrCircle + +func NewCircle(arg1 float64) Circle { + return _swig_wrap_new_Circle(arg1) +} + +func _swig_wrap_Circle_area(SwigcptrCircle) float64 + +func (arg1 SwigcptrCircle) Area() float64 { + return _swig_wrap_Circle_area(arg1) +} + +func _swig_wrap_Circle_perimeter(SwigcptrCircle) float64 + +func (arg1 SwigcptrCircle) Perimeter() float64 { + return _swig_wrap_Circle_perimeter(arg1) +} + +func _swig_wrap_delete_Circle(uintptr) + +func DeleteCircle(arg1 Circle) { + _swig_wrap_delete_Circle(arg1.Swigcptr()) +} + +func _swig_wrap_SetCircle_X(SwigcptrCircle, float64) + +func (_swig_base SwigcptrCircle) SetX(arg1 float64) { + _swig_wrap_SetCircle_X(_swig_base, arg1) +} + +func _swig_wrap_GetCircle_X(SwigcptrCircle) float64 + +func (_swig_base SwigcptrCircle) GetX() float64 { + return _swig_wrap_GetCircle_X(_swig_base) +} + +func _swig_wrap_SetCircle_Y(SwigcptrCircle, float64) + +func (_swig_base SwigcptrCircle) SetY(arg1 float64) { + _swig_wrap_SetCircle_Y(_swig_base, arg1) +} + +func _swig_wrap_GetCircle_Y(SwigcptrCircle) float64 + +func (_swig_base SwigcptrCircle) GetY() float64 { + return _swig_wrap_GetCircle_Y(_swig_base) +} + +func _swig_wrap_Circle_move(SwigcptrCircle, float64, float64) + +func (_swig_base SwigcptrCircle) Move(arg1 float64, arg2 float64) { + _swig_wrap_Circle_move(_swig_base, arg1, arg2) +} + +func (p SwigcptrCircle) SwigIsShape() { +} + +func (p SwigcptrCircle) SwigGetShape() Shape { + return SwigcptrShape(p.Swigcptr()) +} + +type Circle interface { + Swigcptr() uintptr + SwigIsCircle() + Area() float64 + Perimeter() float64 + SetX(arg1 float64) + GetX() float64 + SetY(arg1 float64) + GetY() float64 + Move(arg1 float64, arg2 float64) + SwigIsShape() + SwigGetShape() Shape +} + +type SwigcptrSquare uintptr + +func (p SwigcptrSquare) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrSquare) SwigIsSquare() { +} + +func _swig_wrap_new_Square(float64) SwigcptrSquare + +func NewSquare(arg1 float64) Square { + return _swig_wrap_new_Square(arg1) +} + +func _swig_wrap_Square_area(SwigcptrSquare) float64 + +func (arg1 SwigcptrSquare) Area() float64 { + return _swig_wrap_Square_area(arg1) +} + +func _swig_wrap_Square_perimeter(SwigcptrSquare) float64 + +func (arg1 SwigcptrSquare) Perimeter() float64 { + return _swig_wrap_Square_perimeter(arg1) +} + +func _swig_wrap_delete_Square(uintptr) + +func DeleteSquare(arg1 Square) { + _swig_wrap_delete_Square(arg1.Swigcptr()) +} + +func _swig_wrap_SetSquare_X(SwigcptrSquare, float64) + +func (_swig_base SwigcptrSquare) SetX(arg1 float64) { + _swig_wrap_SetSquare_X(_swig_base, arg1) +} + +func _swig_wrap_GetSquare_X(SwigcptrSquare) float64 + +func (_swig_base SwigcptrSquare) GetX() float64 { + return _swig_wrap_GetSquare_X(_swig_base) +} + +func _swig_wrap_SetSquare_Y(SwigcptrSquare, float64) + +func (_swig_base SwigcptrSquare) SetY(arg1 float64) { + _swig_wrap_SetSquare_Y(_swig_base, arg1) +} + +func _swig_wrap_GetSquare_Y(SwigcptrSquare) float64 + +func (_swig_base SwigcptrSquare) GetY() float64 { + return _swig_wrap_GetSquare_Y(_swig_base) +} + +func _swig_wrap_Square_move(SwigcptrSquare, float64, float64) + +func (_swig_base SwigcptrSquare) Move(arg1 float64, arg2 float64) { + _swig_wrap_Square_move(_swig_base, arg1, arg2) +} + +func (p SwigcptrSquare) SwigIsShape() { +} + +func (p SwigcptrSquare) SwigGetShape() Shape { + return SwigcptrShape(p.Swigcptr()) +} + +type Square interface { + Swigcptr() uintptr + SwigIsSquare() + Area() float64 + Perimeter() float64 + SetX(arg1 float64) + GetX() float64 + SetY(arg1 float64) + GetY() float64 + Move(arg1 float64, arg2 float64) + SwigIsShape() + SwigGetShape() Shape +} + + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/class/example.h b/Examples/go/class/example.h new file mode 100644 index 000000000..46d901361 --- /dev/null +++ b/Examples/go/class/example.h @@ -0,0 +1,39 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; + + + + + diff --git a/Examples/go/class/example.i b/Examples/go/class/example.i new file mode 100644 index 000000000..75700b305 --- /dev/null +++ b/Examples/go/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/go/class/index.html b/Examples/go/class/index.html new file mode 100644 index 000000000..b39119d12 --- /dev/null +++ b/Examples/go/class/index.html @@ -0,0 +1,203 @@ + + +SWIG:Examples:go:class + + + + + +SWIG/Examples/go/class/ +
      + +

      Wrapping a simple C++ class

      + +

      +This example illustrates the most primitive form of C++ class wrapping +performed by SWIG. In this case, C++ classes are simply transformed +into a collection of C-style functions that provide access to class +members. + +

      The C++ Code

      + +Suppose you have some C++ classes described by the following (and +admittedly lame) header file: + +
      +
      +/* File : example.h */
      +
      +class Shape {
      +public:
      +  Shape() {
      +    nshapes++;
      +  }
      +  virtual ~Shape() {
      +    nshapes--;
      +  };
      +  double  x, y;   
      +  void    move(double dx, double dy);
      +  virtual double area() = 0;
      +  virtual double perimeter() = 0;
      +  static  int nshapes;
      +};
      +
      +class Circle : public Shape {
      +private:
      +  double radius;
      +public:
      +  Circle(double r) : radius(r) { };
      +  virtual double area();
      +  virtual double perimeter();
      +};
      +
      +class Square : public Shape {
      +private:
      +  double width;
      +public:
      +  Square(double w) : width(w) { };
      +  virtual double area();
      +  virtual double perimeter();
      +};
      +
      +
      + +

      The SWIG interface

      + +A simple SWIG interface for this can be built by simply grabbing the +header file like this: + +
      +
      +/* File : example.i */
      +%module example
      +
      +%{
      +#include "example.h"
      +%}
      +
      +/* Let's just grab the original header file here */
      +%include "example.h"
      +
      +
      + +Note: when creating a C++ extension, you must run SWIG with +the -c++ option like this: +
      +
      +% swig -c++ -go example.i
      +
      +
      + +

      A sample Go script

      + +See example.go for a program that calls the +C++ functions from Go. + +

      Key points

      + +
        +
      • To create a new object, you call a constructor like this: + +
        +
        +c := example.NewCircle(10.0)
        +
        +
        + +The name of the constructor is New followed by the name of +the class, capitalized. + +

        +

      • +The constructor returns a value of interface type. The methods of the +interface will be the methods of the C++ class, plus member accessor +functions. + +

        +

      • To access member data, a pair of accessor methods are used. For +example: + +
        +
        +c.SetX(15)          # Set member data
        +x := c.GetX()       # Get member data.
        +
        +
        + +These are methods on the type returned by the constructor. The getter +is named Get followed by the name of the member, +capitalized. The setter is similar but uses Set. + +

        +

      • To invoke a member function, you simply do this + +
        +
        +fmt.Println("The area is", example.c.Area())
        +
        +
        + +
      • To invoke a destructor, simply do this + +
        +
        +example.DeleteShape(c)     # Deletes a shape
        +
        +
        + +The name of the destructor is Delete followed by the name of +the class, capitalized. (Note: destructors are currently not +inherited. This might change later). + +

        +

      • Static member variables are wrapped much like C global variables. +For example: + +
        +
        +n := GetShapeNshapes()     # Get a static data member
        +SetShapeNshapes(13)        # Set a static data member
        +
        +
        + +The name is Get or Set, followed by the name of the +class, capitalized, followed by the name of the member, capitalized. + +
      + +

      General Comments

      + +
        +
      • This low-level interface is not the only way to handle C++ code. +Director classes provide a much higher-level interface. + +

        +

      • Because C++ and Go implement inheritance quite differently, you +can not simply upcast an object in Go code when using multiple +inheritance. When using only single inheritance, you can simply pass +a class to a function expecting a parent class. When using multiple +inheritance, you have to call an automatically generated getter +function named Get followed by the capitalized name of the +immediate parent. This will return the same object converted to the + parent class. + +

        +

      • +Overloaded methods should normally work. However, when calling an +overloaded method you must explicitly convert constants to the +expected type when it is not int or float. In +particular, a floating point constant will default to +type float, but C++ functions typically expect the C++ +type double which is equivalent to the Go +type float64 So calling an overloaded method with a floating +point constant typically requires an explicit conversion +to float64. + +

        +

      • Namespaces are not supported in any very coherent way. + +
      + +
      + + diff --git a/Examples/go/class/runme.go b/Examples/go/class/runme.go new file mode 100644 index 000000000..ff64bb4be --- /dev/null +++ b/Examples/go/class/runme.go @@ -0,0 +1,63 @@ +// This example illustrates how C++ classes can be used from Go using SWIG. + +package main + +import ( + "fmt" + . "./example" +) + +func main() { + // ----- Object creation ----- + + fmt.Println("Creating some objects:") + c := NewCircle(10) + fmt.Println(" Created circle", c) + s := NewSquare(10) + fmt.Println(" Created square", s) + + // ----- Access a static member ----- + + fmt.Println("\nA total of", GetShapeNshapes(), "shapes were created") + + // ----- Member data access ----- + + // Notice how we can do this using functions specific to + // the 'Circle' class. + c.SetX(20) + c.SetY(30) + + // Now use the same functions in the base class + var shape Shape = s + shape.SetX(-10) + shape.SetY(5) + + fmt.Println("\nHere is their current position:") + fmt.Println(" Circle = (", c.GetX(), " ", c.GetY(), ")") + fmt.Println(" Square = (", s.GetX(), " ", s.GetY(), ")") + + // ----- Call some methods ----- + + fmt.Println("\nHere are some properties of the shapes:") + shapes := []Shape{c, s} + for i := 0; i < len(shapes); i++ { + fmt.Println(" ", shapes[i]) + fmt.Println(" area = ", shapes[i].Area()) + fmt.Println(" perimeter = ", shapes[i].Perimeter()) + } + + // Notice how the area() and perimeter() functions really + // invoke the appropriate virtual method on each object. + + // ----- Delete everything ----- + + fmt.Println("\nGuess I'll clean up now") + + // Note: this invokes the virtual destructor + // You could leave this to the garbage collector + DeleteCircle(c) + DeleteSquare(s) + + fmt.Println(GetShapeNshapes(), " shapes remain") + fmt.Println("Goodbye") +} diff --git a/Examples/go/constants/Makefile b/Examples/go/constants/Makefile new file mode 100644 index 000000000..71d4d73a4 --- /dev/null +++ b/Examples/go/constants/Makefile @@ -0,0 +1,16 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/constants/example.go b/Examples/go/constants/example.go new file mode 100644 index 000000000..0e5e66418 --- /dev/null +++ b/Examples/go/constants/example.go @@ -0,0 +1,44 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +const ICONST int = 42 +const FCONST float64 = 2.1828 +const CCONST byte = 'x' +func _swig_getCCONST2() byte +var CCONST2 byte = _swig_getCCONST2() +const SCONST string = "Hello World" +func _swig_getSCONST2() string +var SCONST2 string = _swig_getSCONST2() +func _swig_getEXPR() float64 +var EXPR float64 = _swig_getEXPR() +const Iconst int = 37 +const Fconst float64 = 3.14 + diff --git a/Examples/go/constants/example.i b/Examples/go/constants/example.i new file mode 100644 index 000000000..daca042df --- /dev/null +++ b/Examples/go/constants/example.i @@ -0,0 +1,25 @@ +/* File : example.i */ +%module example + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + +/* The following directives also produce constants */ + +%constant int iconst = 37; +%constant double fconst = 3.14; diff --git a/Examples/go/constants/index.html b/Examples/go/constants/index.html new file mode 100644 index 000000000..b1397ab2d --- /dev/null +++ b/Examples/go/constants/index.html @@ -0,0 +1,55 @@ + + +SWIG:Examples:go:constants + + + + +SWIG/Examples/go/constants/ +
      + +

      Wrapping C Constants

      + +

      +When SWIG encounters C preprocessor macros and C declarations that +look like constants, it creates a Go constant with an identical value. +Click here to see a SWIG interface with some +constant declarations in it. + + +

      Accessing Constants from Go

      +Click here for +the section on constants in the SWIG and Go documentation. +

      + +Click here to see a Go program that prints out +the values of the constants contained in the above file.

      +

      Key points

      +
        +
      • All names are capitalized to make them visible. +
      • The values of preprocessor macros are converted into Go constants. +
      • C string literals such as "Hello World" are converted into Go strings. +
      • Macros that are not fully defined are simply ignored. For example: +
        +
        +#define EXTERN extern
        +
        +
        +is ignored because SWIG has no idea what type of variable this would be. + +

        +

      • Expressions are allowed provided that all of their components are +defined. Otherwise, the constant is ignored. + +
      • Certain C declarations involving 'const' are also turned into Go +constants. +
      • The constants that appear in a SWIG interface file do not have to +appear in any sort of matching C source file since the creation of a +constant does not require linkage to a stored value (i.e., a value +held in a C global variable or memory location). +
      + +
      + + + diff --git a/Examples/go/constants/runme.go b/Examples/go/constants/runme.go new file mode 100644 index 000000000..78a047e20 --- /dev/null +++ b/Examples/go/constants/runme.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" + "./example" +) + +func main() { + fmt.Println("ICONST = ", example.ICONST, " (should be 42)") + fmt.Println("FCONST = ", example.FCONST, " (should be 2.1828)") + fmt.Printf("CCONST = %c (should be 'x')\n", example.CCONST) + fmt.Printf("CCONST2 = %c(this should be on a new line)\n", example.CCONST2) + fmt.Println("SCONST = ", example.SCONST, " (should be 'Hello World')") + fmt.Println("SCONST2 = ", example.SCONST2, " (should be '\"Hello World\"')") + fmt.Println("EXPR = ", example.EXPR, " (should be 48.5484)") + fmt.Println("iconst = ", example.Iconst, " (should be 37)") + fmt.Println("fconst = ", example.Fconst, " (should be 3.14)") +} diff --git a/Examples/go/enum/Makefile b/Examples/go/enum/Makefile new file mode 100644 index 000000000..9dc8b8851 --- /dev/null +++ b/Examples/go/enum/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: go + +go:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/enum/example.cxx b/Examples/go/enum/example.cxx new file mode 100644 index 000000000..df7bb6328 --- /dev/null +++ b/Examples/go/enum/example.cxx @@ -0,0 +1,37 @@ +/* File : example.cxx */ + +#include "example.h" +#include + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + if (s == Foo::IMPULSE) { + printf("speed = IMPULSE speed\n"); + } else if (s == Foo::WARP) { + printf("speed = WARP speed\n"); + } else if (s == Foo::LUDICROUS) { + printf("speed = LUDICROUS speed\n"); + } else { + printf("speed = Unknown speed!\n"); + } +} diff --git a/Examples/go/enum/example.go b/Examples/go/enum/example.go new file mode 100644 index 000000000..4653ab57a --- /dev/null +++ b/Examples/go/enum/example.go @@ -0,0 +1,93 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +type Color int +func _swig_getRED() Color +var RED Color = _swig_getRED() +func _swig_getBLUE() Color +var BLUE Color = _swig_getBLUE() +func _swig_getGREEN() Color +var GREEN Color = _swig_getGREEN() +type SwigcptrFoo uintptr + +func (p SwigcptrFoo) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrFoo) SwigIsFoo() { +} + +func _swig_wrap_new_Foo() SwigcptrFoo + +func NewFoo() Foo { + return _swig_wrap_new_Foo() +} + +type FooSpeed int +func _swig_getFoo_IMPULSE_Foo() FooSpeed +var FooIMPULSE FooSpeed = _swig_getFoo_IMPULSE_Foo() +func _swig_getFoo_WARP_Foo() FooSpeed +var FooWARP FooSpeed = _swig_getFoo_WARP_Foo() +func _swig_getFoo_LUDICROUS_Foo() FooSpeed +var FooLUDICROUS FooSpeed = _swig_getFoo_LUDICROUS_Foo() +func _swig_wrap_Foo_enum_test(SwigcptrFoo, FooSpeed) + +func (arg1 SwigcptrFoo) Enum_test(arg2 FooSpeed) { + _swig_wrap_Foo_enum_test(arg1, arg2) +} + +func _swig_wrap_delete_Foo(uintptr) + +func DeleteFoo(arg1 Foo) { + _swig_wrap_delete_Foo(arg1.Swigcptr()) +} + +type Foo interface { + Swigcptr() uintptr + SwigIsFoo() + Enum_test(arg2 FooSpeed) +} + +func _swig_wrap_enum_test(Color, FooSpeed) + +func Enum_test(arg1 Color, arg2 FooSpeed) { + _swig_wrap_enum_test(arg1, arg2) +} + + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/enum/example.h b/Examples/go/enum/example.h new file mode 100644 index 000000000..9119cd9fc --- /dev/null +++ b/Examples/go/enum/example.h @@ -0,0 +1,13 @@ +/* File : example.h */ + +enum color { RED, BLUE, GREEN }; + +class Foo { + public: + Foo() { } + enum speed { IMPULSE=10, WARP=20, LUDICROUS=30 }; + void enum_test(speed s); +}; + +void enum_test(color c, Foo::speed s); + diff --git a/Examples/go/enum/example.i b/Examples/go/enum/example.i new file mode 100644 index 000000000..23ee8a822 --- /dev/null +++ b/Examples/go/enum/example.i @@ -0,0 +1,11 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/go/enum/index.html b/Examples/go/enum/index.html new file mode 100644 index 000000000..868efe6ad --- /dev/null +++ b/Examples/go/enum/index.html @@ -0,0 +1,42 @@ + + +SWIG:Examples:go:enum + + + + + +SWIG/Examples/go/enum/ +
      + +

      Wrapping enumerations

      + +

      +This example tests SWIG's ability to wrap enumerations. +

        +
      • +Enum values are expressed as constants or variables in GO. +
      • +If the enum is named, then that name, capitalized, as defined as a new +type name for int. All the enum values will be defined to +have that type. +
      • +If the enum is declared at global level, then the name in Go is simply +the enum value, capitalized. +
      • +If the enum is declared within a C++ class or struct, then the name in +Go is the capitalized name of the class or struct followed by the +capitalized name of the enum value. +
      • +
      + +

      +

      + +
      + + diff --git a/Examples/go/enum/runme.go b/Examples/go/enum/runme.go new file mode 100644 index 000000000..419df5f93 --- /dev/null +++ b/Examples/go/enum/runme.go @@ -0,0 +1,32 @@ +package main + +import ( + "fmt" + . "./example" +) + +func main() { + // Print out the value of some enums + fmt.Println("*** color ***") + fmt.Println(" RED = ", RED) + fmt.Println(" BLUE = ", BLUE) + fmt.Println(" GREEN = ", GREEN) + + fmt.Println("\n*** Foo::speed ***") + fmt.Println(" Foo::IMPULSE = ", FooIMPULSE) + fmt.Println(" Foo::WARP = ", FooWARP) + fmt.Println(" Foo::LUDICROUS = ", FooLUDICROUS) + + fmt.Println("\nTesting use of enums with functions\n") + + Enum_test(RED, FooIMPULSE) + Enum_test(BLUE, FooWARP) + Enum_test(GREEN, FooLUDICROUS) + + fmt.Println("\nTesting use of enum with class method") + f := NewFoo() + + f.Enum_test(FooIMPULSE) + f.Enum_test(FooWARP) + f.Enum_test(FooLUDICROUS) +} diff --git a/Examples/go/extend/Makefile b/Examples/go/extend/Makefile new file mode 100644 index 000000000..9dc8b8851 --- /dev/null +++ b/Examples/go/extend/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: go + +go:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/extend/example.cxx b/Examples/go/extend/example.cxx new file mode 100644 index 000000000..450d75608 --- /dev/null +++ b/Examples/go/extend/example.cxx @@ -0,0 +1,4 @@ +/* File : example.cxx */ + +#include "example.h" + diff --git a/Examples/go/extend/example.go b/Examples/go/extend/example.go new file mode 100644 index 000000000..08f21e6ab --- /dev/null +++ b/Examples/go/extend/example.go @@ -0,0 +1,397 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +type _swig_DirectorEmployee struct { + SwigcptrEmployee + v interface{} +} + +func (p *_swig_DirectorEmployee) Swigcptr() uintptr { + return p.SwigcptrEmployee.Swigcptr() +} + +func (p *_swig_DirectorEmployee) SwigIsEmployee() { +} + +func (p *_swig_DirectorEmployee) DirectorInterface() interface{} { + return p.v +} + +func _swig_NewDirectorEmployeeEmployee(*_swig_DirectorEmployee, string) SwigcptrEmployee + +func NewDirectorEmployee(v interface{}, arg1 string) Employee { + p := &_swig_DirectorEmployee{0, v} + p.SwigcptrEmployee = _swig_NewDirectorEmployeeEmployee(p, arg1) + return p +} + +type _swig_DirectorInterfaceEmployeeGetTitle interface { + GetTitle() string +} + +func _swig_wrap__swig_DirectorEmployee_upcall_GetTitle(SwigcptrEmployee) string +func (swig_p *_swig_DirectorEmployee) GetTitle() string { + if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceEmployeeGetTitle); swig_ok { + return swig_g.GetTitle() + } + return _swig_wrap__swig_DirectorEmployee_upcall_GetTitle(swig_p.SwigcptrEmployee) +} + +func DirectorEmployeeGetTitle(p Employee) string { + return _swig_wrap__swig_DirectorEmployee_upcall_GetTitle(p.(*_swig_DirectorEmployee).SwigcptrEmployee) +} + +func Swig_DirectorEmployee_callback_getTitle(p *_swig_DirectorEmployee) (swig_result string) { + return p.GetTitle() +} + +type _swig_DirectorInterfaceEmployeeGetName interface { + GetName() string +} + +func _swig_wrap__swig_DirectorEmployee_upcall_GetName(SwigcptrEmployee) string +func (swig_p *_swig_DirectorEmployee) GetName() string { + if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceEmployeeGetName); swig_ok { + return swig_g.GetName() + } + return _swig_wrap__swig_DirectorEmployee_upcall_GetName(swig_p.SwigcptrEmployee) +} + +func DirectorEmployeeGetName(p Employee) string { + return _swig_wrap__swig_DirectorEmployee_upcall_GetName(p.(*_swig_DirectorEmployee).SwigcptrEmployee) +} + +func Swig_DirectorEmployee_callback_getName(p *_swig_DirectorEmployee) (swig_result string) { + return p.GetName() +} + +type _swig_DirectorInterfaceEmployeeGetPosition interface { + GetPosition() string +} + +func _swig_wrap__swig_DirectorEmployee_upcall_GetPosition(SwigcptrEmployee) string +func (swig_p *_swig_DirectorEmployee) GetPosition() string { + if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceEmployeeGetPosition); swig_ok { + return swig_g.GetPosition() + } + return _swig_wrap__swig_DirectorEmployee_upcall_GetPosition(swig_p.SwigcptrEmployee) +} + +func DirectorEmployeeGetPosition(p Employee) string { + return _swig_wrap__swig_DirectorEmployee_upcall_GetPosition(p.(*_swig_DirectorEmployee).SwigcptrEmployee) +} + +func Swig_DirectorEmployee_callback_getPosition(p *_swig_DirectorEmployee) (swig_result string) { + return p.GetPosition() +} + +func _swig_wrap_DeleteDirectorEmployee(uintptr) + +func DeleteDirectorEmployee(arg1 Employee) { + _swig_wrap_DeleteDirectorEmployee(arg1.Swigcptr()) +} + +func Swiggo_DeleteDirector_Employee(p *_swig_DirectorEmployee) { + p.SwigcptrEmployee = 0 +} + +type SwigcptrEmployee uintptr + +func (p SwigcptrEmployee) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrEmployee) SwigIsEmployee() { +} + +func (p SwigcptrEmployee) DirectorInterface() interface{} { + return nil +} + +func _swig_wrap_new_Employee(string) SwigcptrEmployee + +func NewEmployee(arg1 string) Employee { + return _swig_wrap_new_Employee(arg1) +} + +func _swig_wrap_Employee_getTitle(SwigcptrEmployee) string + +func (arg1 SwigcptrEmployee) GetTitle() string { + return _swig_wrap_Employee_getTitle(arg1) +} + +func _swig_wrap_Employee_getName(SwigcptrEmployee) string + +func (arg1 SwigcptrEmployee) GetName() string { + return _swig_wrap_Employee_getName(arg1) +} + +func _swig_wrap_Employee_getPosition(SwigcptrEmployee) string + +func (arg1 SwigcptrEmployee) GetPosition() string { + return _swig_wrap_Employee_getPosition(arg1) +} + +func _swig_wrap_delete_Employee(uintptr) + +func DeleteEmployee(arg1 Employee) { + _swig_wrap_delete_Employee(arg1.Swigcptr()) +} + +type Employee interface { + Swigcptr() uintptr + SwigIsEmployee() + DirectorInterface() interface{} + GetTitle() string + GetName() string + GetPosition() string +} + +type _swig_DirectorManager struct { + SwigcptrManager + v interface{} +} + +func (p *_swig_DirectorManager) Swigcptr() uintptr { + return p.SwigcptrManager.Swigcptr() +} + +func (p *_swig_DirectorManager) SwigIsManager() { +} + +func (p *_swig_DirectorManager) DirectorInterface() interface{} { + return p.v +} + +func _swig_NewDirectorManagerManager(*_swig_DirectorManager, string) SwigcptrManager + +func NewDirectorManager(v interface{}, arg1 string) Manager { + p := &_swig_DirectorManager{0, v} + p.SwigcptrManager = _swig_NewDirectorManagerManager(p, arg1) + return p +} + +type _swig_DirectorInterfaceManagerGetTitle interface { + GetTitle() string +} + +func _swig_wrap__swig_DirectorManager_upcall_GetTitle(SwigcptrManager) string +func (swig_p *_swig_DirectorManager) GetTitle() string { + if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceManagerGetTitle); swig_ok { + return swig_g.GetTitle() + } + return _swig_wrap__swig_DirectorManager_upcall_GetTitle(swig_p.SwigcptrManager) +} + +func DirectorManagerGetTitle(p Manager) string { + return _swig_wrap__swig_DirectorManager_upcall_GetTitle(p.(*_swig_DirectorManager).SwigcptrManager) +} + +func Swig_DirectorManager_callback_getTitle(p *_swig_DirectorManager) (swig_result string) { + return p.GetTitle() +} + +type _swig_DirectorInterfaceManagerGetName interface { + GetName() string +} + +func _swig_wrap__swig_DirectorManager_upcall_GetName(SwigcptrManager) string +func (swig_p *_swig_DirectorManager) GetName() string { + if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceManagerGetName); swig_ok { + return swig_g.GetName() + } + return _swig_wrap__swig_DirectorManager_upcall_GetName(swig_p.SwigcptrManager) +} + +func DirectorManagerGetName(p Manager) string { + return _swig_wrap__swig_DirectorManager_upcall_GetName(p.(*_swig_DirectorManager).SwigcptrManager) +} + +func Swig_DirectorManager_callback_getName(p *_swig_DirectorManager) (swig_result string) { + return p.GetName() +} + +type _swig_DirectorInterfaceManagerGetPosition interface { + GetPosition() string +} + +func _swig_wrap__swig_DirectorManager_upcall_GetPosition(SwigcptrManager) string +func (swig_p *_swig_DirectorManager) GetPosition() string { + if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceManagerGetPosition); swig_ok { + return swig_g.GetPosition() + } + return _swig_wrap__swig_DirectorManager_upcall_GetPosition(swig_p.SwigcptrManager) +} + +func DirectorManagerGetPosition(p Manager) string { + return _swig_wrap__swig_DirectorManager_upcall_GetPosition(p.(*_swig_DirectorManager).SwigcptrManager) +} + +func Swig_DirectorManager_callback_getPosition(p *_swig_DirectorManager) (swig_result string) { + return p.GetPosition() +} + +func _swig_wrap_DeleteDirectorManager(uintptr) + +func DeleteDirectorManager(arg1 Manager) { + _swig_wrap_DeleteDirectorManager(arg1.Swigcptr()) +} + +func Swiggo_DeleteDirector_Manager(p *_swig_DirectorManager) { + p.SwigcptrManager = 0 +} + +type SwigcptrManager uintptr + +func (p SwigcptrManager) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrManager) SwigIsManager() { +} + +func (p SwigcptrManager) DirectorInterface() interface{} { + return nil +} + +func _swig_wrap_new_Manager(string) SwigcptrManager + +func NewManager(arg1 string) Manager { + return _swig_wrap_new_Manager(arg1) +} + +func _swig_wrap_Manager_getPosition(SwigcptrManager) string + +func (arg1 SwigcptrManager) GetPosition() string { + return _swig_wrap_Manager_getPosition(arg1) +} + +func _swig_wrap_delete_Manager(uintptr) + +func DeleteManager(arg1 Manager) { + _swig_wrap_delete_Manager(arg1.Swigcptr()) +} + +func _swig_wrap_Manager_getTitle(SwigcptrManager) string + +func (_swig_base SwigcptrManager) GetTitle() string { + return _swig_wrap_Manager_getTitle(_swig_base) +} + +func _swig_wrap_Manager_getName(SwigcptrManager) string + +func (_swig_base SwigcptrManager) GetName() string { + return _swig_wrap_Manager_getName(_swig_base) +} + +func (p SwigcptrManager) SwigIsEmployee() { +} + +func (p SwigcptrManager) SwigGetEmployee() Employee { + return SwigcptrEmployee(p.Swigcptr()) +} + +type Manager interface { + Swigcptr() uintptr + SwigIsManager() + DirectorInterface() interface{} + GetPosition() string + GetTitle() string + GetName() string + SwigIsEmployee() + SwigGetEmployee() Employee +} + +type SwigcptrEmployeeList uintptr + +func (p SwigcptrEmployeeList) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrEmployeeList) SwigIsEmployeeList() { +} + +func _swig_wrap_new_EmployeeList() SwigcptrEmployeeList + +func NewEmployeeList() EmployeeList { + return _swig_wrap_new_EmployeeList() +} + +func _swig_wrap_EmployeeList_addEmployee(SwigcptrEmployeeList, uintptr) + +func (arg1 SwigcptrEmployeeList) AddEmployee(arg2 Employee) { + _swig_wrap_EmployeeList_addEmployee(arg1, arg2.Swigcptr()) +} + +func _swig_wrap_EmployeeList_get_item(SwigcptrEmployeeList, int) SwigcptrEmployee + +func (arg1 SwigcptrEmployeeList) Get_item(arg2 int) Employee { + return _swig_wrap_EmployeeList_get_item(arg1, arg2) +} + +func _swig_wrap_delete_EmployeeList(uintptr) + +func DeleteEmployeeList(arg1 EmployeeList) { + _swig_wrap_delete_EmployeeList(arg1.Swigcptr()) +} + +type EmployeeList interface { + Swigcptr() uintptr + SwigIsEmployeeList() + AddEmployee(arg2 Employee) + Get_item(arg2 int) Employee +} + + +type SwigcptrSwigDirector_Manager uintptr +type SwigDirector_Manager interface { + Swigcptr() uintptr; +} +func (p SwigcptrSwigDirector_Manager) Swigcptr() uintptr { + return uintptr(p) +} + +type SwigcptrSwigDirector_Employee uintptr +type SwigDirector_Employee interface { + Swigcptr() uintptr; +} +func (p SwigcptrSwigDirector_Employee) Swigcptr() uintptr { + return uintptr(p) +} + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/extend/example.h b/Examples/go/extend/example.h new file mode 100644 index 000000000..b27ab9711 --- /dev/null +++ b/Examples/go/extend/example.h @@ -0,0 +1,56 @@ +/* File : example.h */ + +#include +#include +#include +#include +#include + +class Employee { +private: + std::string name; +public: + Employee(const char* n): name(n) {} + virtual std::string getTitle() { return getPosition() + " " + getName(); } + virtual std::string getName() { return name; } + virtual std::string getPosition() const { return "Employee"; } + virtual ~Employee() { printf("~Employee() @ %p\n", this); } +}; + + +class Manager: public Employee { +public: + Manager(const char* n): Employee(n) {} + virtual std::string getPosition() const { return "Manager"; } +}; + + +class EmployeeList { + std::vector list; +public: + EmployeeList() { + list.push_back(new Employee("Bob")); + list.push_back(new Employee("Jane")); + list.push_back(new Manager("Ted")); + } + void addEmployee(Employee *p) { + list.push_back(p); + std::cout << "New employee added. Current employees are:" << std::endl; + std::vector::iterator i; + for (i=list.begin(); i!=list.end(); i++) { + std::cout << " " << (*i)->getTitle() << std::endl; + } + } + const Employee *get_item(int i) { + return list[i]; + } + ~EmployeeList() { + std::vector::iterator i; + std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl; + for (i=list.begin(); i!=list.end(); i++) { + delete *i; + } + std::cout << "~EmployeeList empty." << std::endl; + } +}; + diff --git a/Examples/go/extend/example.i b/Examples/go/extend/example.i new file mode 100644 index 000000000..c8ec32e09 --- /dev/null +++ b/Examples/go/extend/example.i @@ -0,0 +1,15 @@ +/* File : example.i */ +%module(directors="1") example +%{ +#include "example.h" +%} + +%include "std_vector.i" +%include "std_string.i" + +/* turn on director wrapping for Manager */ +%feature("director") Employee; +%feature("director") Manager; + +%include "example.h" + diff --git a/Examples/go/extend/index.html b/Examples/go/extend/index.html new file mode 100644 index 000000000..471fa9cdc --- /dev/null +++ b/Examples/go/extend/index.html @@ -0,0 +1,27 @@ + + +SWIG:Examples:go:extend + + + + + +SWIG/Examples/go/extend/ +
      + +

      Extending a simple C++ class in Go

      + +

      +This example illustrates the extending of a C++ class with cross +language polymorphism. + +

      +

      + +
      + + diff --git a/Examples/go/extend/runme.go b/Examples/go/extend/runme.go new file mode 100644 index 000000000..796c5ce68 --- /dev/null +++ b/Examples/go/extend/runme.go @@ -0,0 +1,77 @@ +// This file illustrates the cross language polymorphism using directors. + +package main + +import ( + "fmt" + . "./example" +) + +type CEO struct{} + +func (p *CEO) GetPosition() string { + return "CEO" +} + +func main() { + // Create an instance of CEO, a class derived from the Go + // proxy of the underlying C++ class. The calls to getName() + // and getPosition() are standard, the call to getTitle() uses + // the director wrappers to call CEO.getPosition(). + + e := NewDirectorManager(new(CEO), "Alice") + fmt.Println(e.GetName(), " is a ", e.GetPosition()) + fmt.Println("Just call her \"", e.GetTitle(), "\"") + fmt.Println("----------------------") + + + // Create a new EmployeeList instance. This class does not + // have a C++ director wrapper, but can be used freely with + // other classes that do. + + list := NewEmployeeList() + + // EmployeeList owns its items, so we must surrender ownership + // of objects we add. + // e.DisownMemory() + list.AddEmployee(e) + fmt.Println("----------------------") + + // Now we access the first four items in list (three are C++ + // objects that EmployeeList's constructor adds, the last is + // our CEO). The virtual methods of all these instances are + // treated the same. For items 0, 1, and 2, all methods + // resolve in C++. For item 3, our CEO, GetTitle calls + // GetPosition which resolves in Go. The call to GetPosition + // is slightly different, however, because of the overidden + // GetPosition() call, since now the object reference has been + // "laundered" by passing through EmployeeList as an + // Employee*. Previously, Go resolved the call immediately in + // CEO, but now Go thinks the object is an instance of class + // Employee. So the call passes through the Employee proxy + // class and on to the C wrappers and C++ director, eventually + // ending up back at the Java CEO implementation of + // getPosition(). The call to GetTitle() for item 3 runs the + // C++ Employee::getTitle() method, which in turn calls + // GetPosition(). This virtual method call passes down + // through the C++ director class to the Java implementation + // in CEO. All this routing takes place transparently. + + fmt.Println("(position, title) for items 0-3:") + + fmt.Println(" ", list.Get_item(0).GetPosition(), ", \"", list.Get_item(0).GetTitle(), "\"") + fmt.Println(" ", list.Get_item(1).GetPosition(), ", \"", list.Get_item(1).GetTitle(), "\"") + fmt.Println(" ", list.Get_item(2).GetPosition(), ", \"", list.Get_item(2).GetTitle(), "\"") + fmt.Println(" ", list.Get_item(3).GetPosition(), ", \"", list.Get_item(3).GetTitle(), "\"") + fmt.Println("----------------------") + + // Time to delete the EmployeeList, which will delete all the + // Employee* items it contains. The last item is our CEO, + // which gets destroyed as well. + DeleteEmployeeList(list) + fmt.Println("----------------------") + + // All done. + + fmt.Println("Go exit") +} diff --git a/Examples/go/funcptr/Makefile b/Examples/go/funcptr/Makefile new file mode 100644 index 000000000..b0aa9c970 --- /dev/null +++ b/Examples/go/funcptr/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: go + +go:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/funcptr/example.c b/Examples/go/funcptr/example.c new file mode 100644 index 000000000..5c4a3dabf --- /dev/null +++ b/Examples/go/funcptr/example.c @@ -0,0 +1,19 @@ +/* File : example.c */ + +int do_op(int a, int b, int (*op)(int,int)) { + return (*op)(a,b); +} + +int add(int a, int b) { + return a+b; +} + +int sub(int a, int b) { + return a-b; +} + +int mul(int a, int b) { + return a*b; +} + +int (*funcvar)(int,int) = add; diff --git a/Examples/go/funcptr/example.go b/Examples/go/funcptr/example.go new file mode 100644 index 000000000..b059bae8d --- /dev/null +++ b/Examples/go/funcptr/example.go @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +func Do_op(int, int, _swig_fnptr) int +func _swig_getADD() _swig_fnptr +var ADD _swig_fnptr = _swig_getADD() +func _swig_getSUB() _swig_fnptr +var SUB _swig_fnptr = _swig_getSUB() +func _swig_getMUL() _swig_fnptr +var MUL _swig_fnptr = _swig_getMUL() +func _swig_wrap_funcvar_set(_swig_fnptr) + +func SetFuncvar(arg1 _swig_fnptr) { + _swig_wrap_funcvar_set(arg1) +} + +func GetFuncvar() _swig_fnptr + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/funcptr/example.h b/Examples/go/funcptr/example.h new file mode 100644 index 000000000..9936e24fc --- /dev/null +++ b/Examples/go/funcptr/example.h @@ -0,0 +1,9 @@ +/* file: example.h */ + +extern int do_op(int,int, int (*op)(int,int)); +extern int add(int,int); +extern int sub(int,int); +extern int mul(int,int); + +extern int (*funcvar)(int,int); + diff --git a/Examples/go/funcptr/example.i b/Examples/go/funcptr/example.i new file mode 100644 index 000000000..8b3bef678 --- /dev/null +++ b/Examples/go/funcptr/example.i @@ -0,0 +1,16 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Wrap a function taking a pointer to a function */ +extern int do_op(int a, int b, int (*op)(int, int)); + +/* Now install a bunch of "ops" as constants */ +%constant int (*ADD)(int,int) = add; +%constant int (*SUB)(int,int) = sub; +%constant int (*MUL)(int,int) = mul; + +extern int (*funcvar)(int,int); + diff --git a/Examples/go/funcptr/index.html b/Examples/go/funcptr/index.html new file mode 100644 index 000000000..4212260a9 --- /dev/null +++ b/Examples/go/funcptr/index.html @@ -0,0 +1,89 @@ + + +SWIG:Examples:go:funcptr + + + + + +SWIG/Examples/go/funcptr/ +
      + +

      Pointers to Functions

      + +

      +Okay, just what in the heck does SWIG do with a declaration like this? + +

      +
      +int do_op(int a, int b, int (*op)(int, int));
      +
      +
      + +Well, it creates a wrapper as usual. Of course, that does raise some +questions about the third argument (the pointer to a function). + +

      +In this case, SWIG will wrap the function pointer as it does for all +other pointers. However, in order to actually call this function from +a Go program, you will need to pass some kind of C function pointer +object. In C, this is easy, you just supply a function name as an +argument like this: + +

      +
      +/* Some callback function */
      +int add(int a, int b) {
      +   return a+b;
      +} 
      +...
      +int r = do_op(x,y,add);
      +
      +
      + +To make this work with SWIG, you will need to do a little extra work. +Specifically, you need to create some function pointer objects using +the %constant directive like this: + +
      +
      +%constant(int (*)(int,int)) ADD = add;
      +
      +
      + +Now, in a Go program, you would do this: + +
      +
      +int r = do_op(x,y, example.ADD)
      +
      +
      +where example is the module name. + +

      An Example

      + +Here are some files that illustrate this with a simple example: + + + +

      Notes

      + +
        +
      • The value of a function pointer must correspond to a function +written in C or C++. It is not possible to pass an arbitrary Go +function in as a substitute for a C function pointer. + +
      + +
      + + + + + + diff --git a/Examples/go/funcptr/runme.go b/Examples/go/funcptr/runme.go new file mode 100644 index 000000000..73ecbb805 --- /dev/null +++ b/Examples/go/funcptr/runme.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + . "./example" +) + +func main() { + a := 37 + b := 42 + + // Now call our C function with a bunch of callbacks + + fmt.Println("Trying some C callback functions") + fmt.Println(" a = ", a) + fmt.Println(" b = ", b) + fmt.Println(" ADD(a,b) = ", Do_op(a, b, ADD)) + fmt.Println(" SUB(a,b) = ", Do_op(a, b, SUB)) + fmt.Println(" MUL(a,b) = ", Do_op(a, b, MUL)) + + fmt.Println("Here is what the C callback function classes are called in Go") + fmt.Println(" ADD = ", ADD) + fmt.Println(" SUB = ", SUB) + fmt.Println(" MUL = ", MUL) +} diff --git a/Examples/go/index.html b/Examples/go/index.html new file mode 100644 index 000000000..21dda21b5 --- /dev/null +++ b/Examples/go/index.html @@ -0,0 +1,89 @@ + + +SWIG:Examples:Go + + + +

      SWIG Go Examples

      + +

      +The following examples illustrate the use of SWIG with Go. + +

        +
      • simple. A minimal example showing how SWIG can +be used to wrap a C function, a global variable, and a constant. +
      • constants. This shows how preprocessor macros and +certain C declarations are turned into constants. +
      • variables. An example showing how to access C global variables from Go. +
      • enum. Wrapping enumerations. +
      • class. Wrapping a simple C++ class. +
      • reference. C++ references. +
      • pointer. Simple pointer handling. +
      • funcptr. Pointers to functions. +
      • template. C++ templates. +
      • callback. C++ callbacks using directors. +
      • extend. Polymorphism using directors. +
      + +

      Compilation Issues

      + +
        +
      • To create a Go extension, SWIG is run with the following options: + +
        +
        +% swig -go interface.i
        +
        +
        + +
      • On Unix the compilation of examples is done using the +file Example/Makefile. This makefile performs a manual +module compilation which is platform specific. When using +the 6g or 8g compiler, the steps look like this +(GNU/Linux): + +
        +
        +% swig -go interface.i
        +% gcc -fpic -c interface_wrap.c
        +% gcc -shared interface_wrap.o $(OBJS) -o interfacemodule.so 
        +% 6g interface.go
        +% 6c interface_gc.c
        +% gopack grc interface.a interface.6 interface_gc.6
        +% 6l program.6
        +
        +
        + +
      • When using the gccgo compiler, the steps look like this: + +
        +
        +% swig -go interface.i
        +% gcc -c interface_wrap.c
        +% gccgo -c interface.go
        +% gccgo program.o interface.o interface_wrap.o
        +
        +
        + +

        Compatibility

        + +The examples have been extensively tested on the following platforms: + +
          +
        • GNU/Linux +
        + +All of the examples were last tested with the following configuration +(10 May 2010): + +
          +
        • Ubuntu Hardy +
        • gcc-4.2.4 +
        + +Your mileage may vary. If you experience a problem, please let us know by +contacting us on the mailing lists. + + diff --git a/Examples/go/multimap/Makefile b/Examples/go/multimap/Makefile new file mode 100644 index 000000000..b0aa9c970 --- /dev/null +++ b/Examples/go/multimap/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: go + +go:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/multimap/example.c b/Examples/go/multimap/example.c new file mode 100644 index 000000000..b8360fa8a --- /dev/null +++ b/Examples/go/multimap/example.c @@ -0,0 +1,53 @@ +/* File : example.c */ +#include +#include +#include + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +int gcdmain(int argc, char *argv[]) { + int x,y; + if (argc != 3) { + printf("usage: gcd x y\n"); + return -1; + } + x = atoi(argv[1]); + y = atoi(argv[2]); + printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y)); + return 0; +} + +int count(char *bytes, int len, char c) { + int i; + int count = 0; + for (i = 0; i < len; i++) { + if (bytes[i] == c) count++; + } + return count; +} + +void capitalize(char *str, int len) { + int i; + for (i = 0; i < len; i++) { + str[i] = (char)toupper(str[i]); + } +} + +void circle(double x, double y) { + double a = x*x + y*y; + if (a > 1.0) { + printf("Bad points %g, %g\n", x,y); + } else { + printf("Good points %g, %g\n", x,y); + } +} diff --git a/Examples/go/multimap/example.go b/Examples/go/multimap/example.go new file mode 100644 index 000000000..59ed9eaad --- /dev/null +++ b/Examples/go/multimap/example.go @@ -0,0 +1,55 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +func Gcd(int, int) int +func Gcdmain([]string) int +func Count(string, byte) int +func _swig_wrap_capitalize([]string) + +func Capitalize(arg1 []string) { + _swig_wrap_capitalize(arg1) +} + +func _swig_wrap_circle(float64, float64) + +func Circle(arg1 float64, arg2 float64) { + _swig_wrap_circle(arg1, arg2) +} + + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/multimap/example.i b/Examples/go/multimap/example.i new file mode 100644 index 000000000..8de6b0dc3 --- /dev/null +++ b/Examples/go/multimap/example.i @@ -0,0 +1,110 @@ +/* File : example.i */ +%module example + +%{ +extern int gcd(int x, int y); +extern int gcdmain(int argc, char *argv[]); +extern int count(char *bytes, int len, char c); +extern void capitalize (char *str, int len); +extern void circle (double cx, double cy); +extern int squareCubed (int n, int *OUTPUT); +%} + +extern int gcd(int x, int y); + +%typemap(gotype) (int argc, char *argv[]) "[]string" + +%typemap(in) (int argc, char *argv[]) +%{ + { + int i; + _gostring_* a; + + $1 = $input.len; + a = (_gostring_*) $input.array; + $2 = (char **) malloc (($1 + 1) * sizeof (char *)); + for (i = 0; i < $1; i++) { + _gostring_ *ps = &a[i]; + $2[i] = (char *) ps->p; + } + $2[i] = NULL; + } +%} + +%typemap(argout) (int argc, char *argv[]) "" /* override char *[] default */ + +%typemap(freearg) (int argc, char *argv[]) +%{ + free($2); +%} + +extern int gcdmain(int argc, char *argv[]); + +%typemap(gotype) (char *bytes, int len) "string" + +%typemap(in) (char *bytes, int len) +%{ + $1 = $input.p; + $2 = $input.n; +%} + +extern int count(char *bytes, int len, char c); + +/* This example shows how to wrap a function that mutates a c string. A one + * element Go string slice is used so that the string can be returned + * modified. + */ + +%typemap(gotype) (char *str, int len) "[]string" + +%typemap(in) (char *str, int len) +%{ + { + _gostring_ *a; + char *p; + int n; + + a = (_gostring_*) $input.array; + p = a[0].p; + n = a[0].n; + $1 = malloc(n + 1); + $2 = n; + memcpy($1, p, n); + } +%} + +/* Return the mutated string as a modified element in the array. */ +%typemap(argout) (char *str, int len) +%{ + { + _gostring_ *a; + + a = (_gostring_*) $input.array; + a[0] = _swig_makegostring($1, $2); + } +%} + +%typemap(freearg) (char *str, int len) +%{ + free($1); +%} + +extern void capitalize(char *str, int len); + +/* A multi-valued constraint. Force two arguments to lie + inside the unit circle */ + +%typemap(check) (double cx, double cy) +%{ + { + double a = $1*$1 + $2*$2; + if (a > 1.0) { + _swig_gopanic("$1_name and $2_name must be in unit circle"); + return; + } + } +%} + +extern void circle(double cx, double cy); + + diff --git a/Examples/go/multimap/runme.go b/Examples/go/multimap/runme.go new file mode 100644 index 000000000..94c29127c --- /dev/null +++ b/Examples/go/multimap/runme.go @@ -0,0 +1,26 @@ +package main + +import ( + "fmt" + . "./example" +) + +func main() { + // Call our gcd() function + x := 42 + y := 105 + g := Gcd(x, y) + fmt.Println("The gcd of ", x, " and ", y, " is ", g) + + // Call the gcdmain() function + args := []string{"gcdmain", "42", "105"} + Gcdmain(args) + + // Call the count function + fmt.Println(Count("Hello World", 'l')) + + // Call the capitalize function + capitalizeMe := []string{"hello world"} + Capitalize(capitalizeMe) + fmt.Println(capitalizeMe[0]) +} diff --git a/Examples/go/pointer/Makefile b/Examples/go/pointer/Makefile new file mode 100644 index 000000000..b0aa9c970 --- /dev/null +++ b/Examples/go/pointer/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: go + +go:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/pointer/example.c b/Examples/go/pointer/example.c new file mode 100644 index 000000000..b877d9a5b --- /dev/null +++ b/Examples/go/pointer/example.c @@ -0,0 +1,16 @@ +/* File : example.c */ + +void add(int *x, int *y, int *result) { + *result = *x + *y; +} + +void sub(int *x, int *y, int *result) { + *result = *x - *y; +} + +int divide(int n, int d, int *r) { + int q; + q = n/d; + *r = n - q*d; + return q; +} diff --git a/Examples/go/pointer/example.go b/Examples/go/pointer/example.go new file mode 100644 index 000000000..567c41c32 --- /dev/null +++ b/Examples/go/pointer/example.go @@ -0,0 +1,68 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +func _swig_wrap_add(*int, *int, *int) + +func Add(arg1 *int, arg2 *int, arg3 *int) { + _swig_wrap_add(arg1, arg2, arg3) +} + +func New_intp() *int +func Copy_intp(int) *int +func _swig_wrap_delete_intp(*int) + +func Delete_intp(arg1 *int) { + _swig_wrap_delete_intp(arg1) +} + +func _swig_wrap_intp_assign(*int, int) + +func Intp_assign(arg1 *int, arg2 int) { + _swig_wrap_intp_assign(arg1, arg2) +} + +func Intp_value(*int) int +func _swig_wrap_sub(int, int, []int) + +func Sub(arg1 int, arg2 int, arg3 []int) { + _swig_wrap_sub(arg1, arg2, arg3) +} + +func Divide(int, int, []int) int + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/pointer/example.i b/Examples/go/pointer/example.i new file mode 100644 index 000000000..a8ac79499 --- /dev/null +++ b/Examples/go/pointer/example.i @@ -0,0 +1,30 @@ +/* File : example.i */ +%module example + +%{ +extern void add(int *, int *, int *); +extern void sub(int *, int *, int *); +extern int divide(int, int, int *); +%} + +/* This example illustrates a couple of different techniques + for manipulating C pointers */ + +/* First we'll use the pointer library */ +extern void add(int *x, int *y, int *result); +%include cpointer.i +%pointer_functions(int, intp); + +/* Next we'll use some typemaps */ + +%include typemaps.i +extern void sub(int *INPUT, int *INPUT, int *OUTPUT); + +/* Next we'll use typemaps and the %apply directive */ + +%apply int *OUTPUT { int *r }; +extern int divide(int n, int d, int *r); + + + + diff --git a/Examples/go/pointer/index.html b/Examples/go/pointer/index.html new file mode 100644 index 000000000..cfa8a3acc --- /dev/null +++ b/Examples/go/pointer/index.html @@ -0,0 +1,143 @@ + + +SWIG:Examples:go:pointer + + + + +SWIG/Examples/go/pointer/ +
        + +

        Simple Pointer Handling

        + +

        +This example illustrates a couple of techniques for handling simple +pointers in SWIG. The prototypical example is a C function that +operates on pointers such as this: + +

        +
        +void add(int *x, int *y, int *r) { 
        +    *r = *x + *y;
        +}
        +
        +
        + +By default, SWIG wraps this function exactly as specified and creates +an interface that expects pointer objects for arguments. This only +works when there is a precise correspondence between the C type and +some Go type. +

        + +

        Other approaches

        + +

        +

      • The SWIG pointer library provides a different, safer, way to + handle pointers. For example, in the interface file you would do + this: + +
        +
        +%include cpointer.i
        +%pointer_functions(int, intp);
        +
        +
        + +and from Go you would use pointers like this: + +
        +
        +a := example.New_intp()
        +b := example.New_intp()
        +c := example.New_intp()
        +Intp_Assign(a, 37)
        +Intp_Assign(b, 42)
        +
        +fmt.Println("     a =", a)
        +fmt.Println("     b =", b)
        +fmt.Println("     c =", c)
        +
        +// Call the add() function with some pointers
        +example.Add(a,b,c)
        +
        +// Now get the result
        +res := example.Intp_value(c)
        +fmt.Println("     37 + 42 =", res)
        +
        +// Clean up the pointers
        +example.Delete_intp(a)
        +example.Delete_intp(b)
        +example.Delete_intp(c)
        +
        +
        + +

        +

      • Use the SWIG typemap library. This library allows you to +completely change the way arguments are processed by SWIG. For +example: + +
        +
        +%include "typemaps.i"
        +void add(int *INPUT, int *INPUT, int *OUTPUT);
        +
        +
        + +And in a Go program: + +
        +
        +r := []int{0}
        +example.Sub(37,42,r)
        +fmt.Println("Result =", r[0])
        +
        +
        +Needless to say, this is substantially easier although a bit unusual. + +

        +

      • A final alternative is to use the typemaps library in combination +with the %apply directive. This allows you to change the names of parameters +that behave as input or output parameters. For example: + +
        +
        +%include "typemaps.i"
        +%apply int *INPUT {int *x, int *y};
        +%apply int *OUTPUT {int *r};
        +
        +void add(int *x, int *y, int *r);
        +void sub(int *x, int *y, int *r);
        +void mul(int *x, int *y, int *r);
        +... etc ...
        +
        +
        + +
      + +

      Example

      + +The following example illustrates the use of these features for pointer +extraction. + + + +

      Notes

      + +
        +
      • Since pointers are used for so many different things (arrays, output values, +etc...) the complexity of pointer handling can be as complicated as you want to +make it. + +

        +

      • More documentation on the typemaps.i and cpointer.i library files can be +found in the SWIG user manual. The files also contain documentation. + +
      + +
      + + diff --git a/Examples/go/pointer/runme.go b/Examples/go/pointer/runme.go new file mode 100644 index 000000000..9cbcda489 --- /dev/null +++ b/Examples/go/pointer/runme.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + . "./example" +) + +func main() { + // First create some objects using the pointer library. + fmt.Println("Testing the pointer library") + a := New_intp() + b := New_intp() + c := New_intp() + Intp_assign(a, 37) + Intp_assign(b, 42) + + fmt.Println(" a =", a) + fmt.Println(" b =", b) + fmt.Println(" c =", c) + + // Call the add() function with some pointers + Add(a, b, c) + + // Now get the result + res := Intp_value(c) + fmt.Println(" 37 + 42 =", res) + + // Clean up the pointers + Delete_intp(a) + Delete_intp(b) + Delete_intp(c) + + // Now try the typemap library + // Now it is no longer necessary to manufacture pointers. + // Instead we use a single element array which in Java is modifiable. + + fmt.Println("Trying the typemap library") + r := []int{0} + Sub(37, 42, r) + fmt.Println(" 37 - 42 = ", r[0]) + + // Now try the version with return value + + fmt.Println("Testing return value") + q := Divide(42, 37, r) + fmt.Println(" 42/37 = ", q, " remainder ", r[0]) +} diff --git a/Examples/go/reference/Makefile b/Examples/go/reference/Makefile new file mode 100644 index 000000000..9dc8b8851 --- /dev/null +++ b/Examples/go/reference/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: go + +go:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/reference/example.cxx b/Examples/go/reference/example.cxx new file mode 100644 index 000000000..8a513bf49 --- /dev/null +++ b/Examples/go/reference/example.cxx @@ -0,0 +1,46 @@ +/* File : example.cxx */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include "example.h" +#include +#include + +Vector operator+(const Vector &a, const Vector &b) { + Vector r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} + +char *Vector::print() { + static char temp[512]; + sprintf(temp,"Vector %p (%g,%g,%g)", this, x,y,z); + return temp; +} + +VectorArray::VectorArray(int size) { + items = new Vector[size]; + maxsize = size; +} + +VectorArray::~VectorArray() { + delete [] items; +} + +Vector &VectorArray::operator[](int index) { + if ((index < 0) || (index >= maxsize)) { + printf("Panic! Array index out of bounds.\n"); + exit(1); + } + return items[index]; +} + +int VectorArray::size() { + return maxsize; +} + diff --git a/Examples/go/reference/example.go b/Examples/go/reference/example.go new file mode 100644 index 000000000..fb98f8a18 --- /dev/null +++ b/Examples/go/reference/example.go @@ -0,0 +1,126 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +type SwigcptrVector uintptr + +func (p SwigcptrVector) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrVector) SwigIsVector() { +} + +func _swig_wrap_new_Vector(float64, float64, float64) SwigcptrVector + +func NewVector(arg1 float64, arg2 float64, arg3 float64) Vector { + return _swig_wrap_new_Vector(arg1, arg2, arg3) +} + +func _swig_wrap_delete_Vector(uintptr) + +func DeleteVector(arg1 Vector) { + _swig_wrap_delete_Vector(arg1.Swigcptr()) +} + +func _swig_wrap_Vector_print(SwigcptrVector) string + +func (arg1 SwigcptrVector) Print() string { + return _swig_wrap_Vector_print(arg1) +} + +type Vector interface { + Swigcptr() uintptr + SwigIsVector() + Print() string +} + +func _swig_wrap_addv(uintptr, uintptr) SwigcptrVector + +func Addv(arg1 Vector, arg2 Vector) Vector { + return _swig_wrap_addv(arg1.Swigcptr(), arg2.Swigcptr()) +} + +type SwigcptrVectorArray uintptr + +func (p SwigcptrVectorArray) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrVectorArray) SwigIsVectorArray() { +} + +func _swig_wrap_new_VectorArray(int) SwigcptrVectorArray + +func NewVectorArray(arg1 int) VectorArray { + return _swig_wrap_new_VectorArray(arg1) +} + +func _swig_wrap_delete_VectorArray(uintptr) + +func DeleteVectorArray(arg1 VectorArray) { + _swig_wrap_delete_VectorArray(arg1.Swigcptr()) +} + +func _swig_wrap_VectorArray_size(SwigcptrVectorArray) int + +func (arg1 SwigcptrVectorArray) Size() int { + return _swig_wrap_VectorArray_size(arg1) +} + +func _swig_wrap_VectorArray_get(SwigcptrVectorArray, int) SwigcptrVector + +func (arg1 SwigcptrVectorArray) Get(arg2 int) Vector { + return _swig_wrap_VectorArray_get(arg1, arg2) +} + +func _swig_wrap_VectorArray_set(SwigcptrVectorArray, int, uintptr) + +func (arg1 SwigcptrVectorArray) Set(arg2 int, arg3 Vector) { + _swig_wrap_VectorArray_set(arg1, arg2, arg3.Swigcptr()) +} + +type VectorArray interface { + Swigcptr() uintptr + SwigIsVectorArray() + Size() int + Get(arg2 int) Vector + Set(arg2 int, arg3 Vector) +} + + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/reference/example.h b/Examples/go/reference/example.h new file mode 100644 index 000000000..4915adb1b --- /dev/null +++ b/Examples/go/reference/example.h @@ -0,0 +1,26 @@ +/* File : example.h */ + +class Vector { +private: + double x,y,z; +public: + Vector() : x(0), y(0), z(0) { }; + Vector(double x, double y, double z) : x(x), y(y), z(z) { }; + friend Vector operator+(const Vector &a, const Vector &b); + char *print(); +}; + +class VectorArray { +private: + Vector *items; + int maxsize; +public: + VectorArray(int maxsize); + ~VectorArray(); + Vector &operator[](int); + int size(); +}; + + + + diff --git a/Examples/go/reference/example.i b/Examples/go/reference/example.i new file mode 100644 index 000000000..1cf19c82c --- /dev/null +++ b/Examples/go/reference/example.i @@ -0,0 +1,42 @@ +/* File : example.i */ + +/* This file has a few "typical" uses of C++ references. */ + +%module example + +%{ +#include "example.h" +%} + +class Vector { +public: + Vector(double x, double y, double z); + ~Vector(); + char *print(); +}; + +/* This helper function calls an overloaded operator */ +%inline %{ +Vector addv(Vector &a, Vector &b) { + return a+b; +} +%} + +/* Wrapper around an array of vectors class */ + +class VectorArray { +public: + VectorArray(int maxsize); + ~VectorArray(); + int size(); + + /* This wrapper provides an alternative to the [] operator */ + %extend { + Vector &get(int index) { + return (*$self)[index]; + } + void set(int index, Vector &a) { + (*$self)[index] = a; + } + } +}; diff --git a/Examples/go/reference/index.html b/Examples/go/reference/index.html new file mode 100644 index 000000000..5e8589349 --- /dev/null +++ b/Examples/go/reference/index.html @@ -0,0 +1,143 @@ + + +SWIG:Examples:go:reference + + + + + +SWIG/Examples/go/reference/ +
      + +

      C++ Reference Handling

      + +

      +This example tests SWIG's handling of C++ references. A reference in +C++ is much like a pointer. Go represents C++ classes as pointers +which are stored in interface values. Therefore, a reference to a +class in C++ simply becomes an object of the class type in Go. For +types which are not classes, a reference in C++ is represented as a +pointer in Go. + +

      Some examples

      + +References are most commonly used as function parameters. For +example, you might have a function like this: + +
      +
      +Vector addv(const Vector &a, const Vector &b) {
      +   Vector result;
      +   result.x = a.x + b.x;
      +   result.y = a.y + b.y;
      +   result.z = a.z + b.z;
      +   return result;
      +}
      +
      +
      + +In these cases, SWIG transforms everything into a pointer and creates +a wrapper that looks like this in C++. + +
      +
      +Vector wrap_addv(Vector *a, Vector *b);
      +
      +
      + +or like this in Go: + +
      +
      +func Addv(arg1 Vector, arg2 Vector) Vector
      +
      +
      + +Occasionally, a reference is used as a return value of a function +when the return result is to be used as an lvalue in an expression. +The prototypical example is an operator like this: + +
      +
      +Vector &operator[](int index);
      +
      +
      + +or a method: + +
      +
      +Vector &get(int index);
      +
      +
      + +For functions returning references, a wrapper like this is created: + +
      +
      +Vector *wrap_Object_get(Object *self, int index) {
      +    Vector &result = self->get(index);
      +    return &result;
      +}
      +
      +
      + +The following header file contains some class +definitions with some operators and use of references. + +

      SWIG Interface

      + +SWIG does NOT support overloaded operators so it can not directly +build an interface to the classes in the above file. However, a +number of workarounds can be made. For example, an overloaded +operator can be stuck behind a function call such as the addv +function above. Array access can be handled with a pair of set/get +functions like this: + +
      +
      +class VectorArray {
      +public:
      + ...
      +   %addmethods {
      +    Vector &get(int index) {
      +      return (*self)[index];
      +    }
      +    void set(int index, Vector &a) {
      +      (*self)[index] = a;
      +    }
      +   }
      +   ...
      +}
      +
      +
      + +Click here to see a SWIG interface file with +these additions. + +

      Sample Go program

      + +Click here to see a Go program that manipulates +some C++ references. + +

      Notes:

      + +
        +
      • C++ references primarily provide notational convenience for C++ +source code. However, Go only supports the 'x.a' notation so it +doesn't much matter. + +

        +

      • When a program returns a reference, a pointer is returned. Unlike +return by value, memory is not allocated to hold the return result. + +

        +

      • SWIG has particular trouble handling various combinations of +references and pointers. This is side effect of an old parsing scheme +and type representation that will be replaced in future versions. + +
      + +
      + + diff --git a/Examples/go/reference/runme.go b/Examples/go/reference/runme.go new file mode 100644 index 000000000..3683d6144 --- /dev/null +++ b/Examples/go/reference/runme.go @@ -0,0 +1,71 @@ +// This example illustrates the manipulation of C++ references in Java. + +package main + +import ( + "fmt" + . "./example" +) + +func main() { + fmt.Println("Creating some objects:") + a := NewVector(3, 4, 5) + b := NewVector(10, 11, 12) + + fmt.Println(" Created ", a.Print()) + fmt.Println(" Created ", b.Print()) + + // ----- Call an overloaded operator ----- + + // This calls the wrapper we placed around + // + // operator+(const Vector &a, const Vector &) + // + // It returns a new allocated object. + + fmt.Println("Adding a+b") + c := Addv(a, b) + fmt.Println(" a+b = " + c.Print()) + + // Because addv returns a reference, Addv will return a + // pointer allocated using Go's memory allocator. That means + // that it will be freed by Go's garbage collector, and we can + // not use DeleteVector to release it. + + c = nil + + // ----- Create a vector array ----- + + fmt.Println("Creating an array of vectors") + va := NewVectorArray(10) + fmt.Println(" va = ", va) + + // ----- Set some values in the array ----- + + // These operators copy the value of Vector a and Vector b to + // the vector array + va.Set(0, a) + va.Set(1, b) + + va.Set(2, Addv(a, b)) + + // Get some values from the array + + fmt.Println("Getting some array values") + for i := 0; i < 5; i++ { + fmt.Println(" va(", i, ") = ", va.Get(i).Print()) + } + + // Watch under resource meter to check on this + fmt.Println("Making sure we don't leak memory.") + for i := 0; i < 1000000; i++ { + c = va.Get(i % 10) + } + + // ----- Clean up ----- This could be omitted. The garbage + // collector would then clean up for us. + fmt.Println("Cleaning up") + DeleteVectorArray(va) + DeleteVector(a) + DeleteVector(b) +} diff --git a/Examples/go/simple/Makefile b/Examples/go/simple/Makefile new file mode 100644 index 000000000..e67fa8bb6 --- /dev/null +++ b/Examples/go/simple/Makefile @@ -0,0 +1,15 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/simple/example.c b/Examples/go/simple/example.c new file mode 100644 index 000000000..1c2af789c --- /dev/null +++ b/Examples/go/simple/example.c @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/Examples/go/simple/example.go b/Examples/go/simple/example.go new file mode 100644 index 000000000..df0e70564 --- /dev/null +++ b/Examples/go/simple/example.go @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +func Gcd(int, int) int +func _swig_wrap_Foo_set(float64) + +func SetFoo(arg1 float64) { + _swig_wrap_Foo_set(arg1) +} + +func GetFoo() float64 + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/simple/example.i b/Examples/go/simple/example.i new file mode 100644 index 000000000..24093b9bf --- /dev/null +++ b/Examples/go/simple/example.i @@ -0,0 +1,7 @@ +/* File : example.i */ +%module example + +%inline %{ +extern int gcd(int x, int y); +extern double Foo; +%} diff --git a/Examples/go/simple/index.html b/Examples/go/simple/index.html new file mode 100644 index 000000000..21dfc239e --- /dev/null +++ b/Examples/go/simple/index.html @@ -0,0 +1,128 @@ + + +SWIG:Examples:go:simple + + + + + +SWIG/Examples/go/simple/ +
      + +

      Simple Go Example

      + +

      +This example illustrates how you can hook Go to a very simple C program containing +a function and a global variable. + +

      The C Code

      + +Suppose you have the following C code: + +
      +
      +/* File : example.c */
      +
      +/* A global variable */
      +double Foo = 3.0;
      +
      +/* Compute the greatest common divisor of positive integers */
      +int gcd(int x, int y) {
      +  int g;
      +  g = y;
      +  while (x > 0) {
      +    g = x;
      +    x = y % x;
      +    y = g;
      +  }
      +  return g;
      +}
      +
      +
      + +

      The SWIG interface

      + +Here is a simple SWIG interface file: + +
      +
      +/* File: example.i */
      +%module example
      +
      +extern int gcd(int x, int y);
      +extern double Foo;
      +
      +
      + +

      Compilation

      + +These are the instructions if you are using 6g/8g +rather than gccgo. + +
        +
      1. Run swig -go example.i. This + will create the three + files example.go, example_gc.c, + and example_wrap.c. +
      2. Compile example.go + using 6g or 8g; e.g., 6g example.go. +
      3. Compile example_gc.c + using 6c or 8c; e.g., 6c example_gc.c. +
      4. Put the two object files together into an archive + named example.a; e.g., gopack grc example.a example.6 + example_gc.6. +
      5. Compile the example_wrap.c + file using your standard C compiler with the -fpic option; + e.g., gcc -c -O -fpic example_wrap.c. +
      6. Also compile the actual code, not generated by SWIG; e.g., gcc + -c -O -fpic example.c. +
      7. Put the gcc compiled object files into a shared library; + e.g., gcc -shared -o example.so example_wrap.o example.o. +
      8. Compile the program which demonstrates how to use the library; + e.g., 6g runme.go. +
      9. Link the program; e.g., 6l -o runme runme.6. +
      10. Now you should have a program runme. +
      + +

      Using the extension

      + +The Go program which demonstrates calling the C functions from Go +is runme.go. + +

      Key points

      + +
        +
      • Use the import statement to load your extension module from Go. For example: +
        +
        +import "example"
        +
        +
        + +
      • C functions work just like Go functions. However, the function + names are automatically capitalized in order to make the names + visible from other Go packages. For example: +
        +
        +g := example.Gcd(42,105)
        +
        +
        + +(If there are name conflicts, you can use the %rename +directive in the .i file or the -rename option to Go to +rename one or the other symbol). + +
      • C global variables are accessed using getter and setter + functions. The getter function is named Get followed by + the capitalized name of the C variable. The Setter function + uses Set instead of Get. +
        +
        +a = example.GetFoo()
        +
        +
        +
      + +
      + + diff --git a/Examples/go/simple/runme.go b/Examples/go/simple/runme.go new file mode 100644 index 000000000..c829ad21a --- /dev/null +++ b/Examples/go/simple/runme.go @@ -0,0 +1,25 @@ +package main + +import ( + "fmt" + "./example" +) + +func main() { + // Call our gcd() function + x := 42 + y := 105 + g := example.Gcd(x, y) + fmt.Println("The gcd of", x, "and", y, "is", g) + + // Manipulate the Foo global variable + + // Output its current value + fmt.Println("Foo =", example.GetFoo()) + + // Change its value + example.SetFoo(3.1415926) + + // See if the change took effect + fmt.Println("Foo =", example.GetFoo()) +} diff --git a/Examples/go/template/Makefile b/Examples/go/template/Makefile new file mode 100644 index 000000000..b9278b53e --- /dev/null +++ b/Examples/go/template/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: go + +go:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/template/example.go b/Examples/go/template/example.go new file mode 100644 index 000000000..671b5c2ba --- /dev/null +++ b/Examples/go/template/example.go @@ -0,0 +1,150 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +func Maxint(int, int) int +func Maxdouble(float64, float64) float64 +type SwigcptrVecint uintptr + +func (p SwigcptrVecint) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrVecint) SwigIsVecint() { +} + +func _swig_wrap_new_vecint(int) SwigcptrVecint + +func NewVecint(arg1 int) Vecint { + return _swig_wrap_new_vecint(arg1) +} + +func _swig_wrap_vecint_get(SwigcptrVecint, int) *int + +func (arg1 SwigcptrVecint) Get(arg2 int) *int { + return _swig_wrap_vecint_get(arg1, arg2) +} + +func _swig_wrap_vecint_set(SwigcptrVecint, int, *int) + +func (arg1 SwigcptrVecint) Set(arg2 int, arg3 *int) { + _swig_wrap_vecint_set(arg1, arg2, arg3) +} + +func _swig_wrap_vecint_getitem(SwigcptrVecint, int) int + +func (arg1 SwigcptrVecint) Getitem(arg2 int) int { + return _swig_wrap_vecint_getitem(arg1, arg2) +} + +func _swig_wrap_vecint_setitem(SwigcptrVecint, int, int) + +func (arg1 SwigcptrVecint) Setitem(arg2 int, arg3 int) { + _swig_wrap_vecint_setitem(arg1, arg2, arg3) +} + +func _swig_wrap_delete_vecint(uintptr) + +func DeleteVecint(arg1 Vecint) { + _swig_wrap_delete_vecint(arg1.Swigcptr()) +} + +type Vecint interface { + Swigcptr() uintptr + SwigIsVecint() + Get(arg2 int) *int + Set(arg2 int, arg3 *int) + Getitem(arg2 int) int + Setitem(arg2 int, arg3 int) +} + +type SwigcptrVecdouble uintptr + +func (p SwigcptrVecdouble) Swigcptr() uintptr { + return (uintptr)(p) +} + +func (p SwigcptrVecdouble) SwigIsVecdouble() { +} + +func _swig_wrap_new_vecdouble(int) SwigcptrVecdouble + +func NewVecdouble(arg1 int) Vecdouble { + return _swig_wrap_new_vecdouble(arg1) +} + +func _swig_wrap_vecdouble_get(SwigcptrVecdouble, int) *float64 + +func (arg1 SwigcptrVecdouble) Get(arg2 int) *float64 { + return _swig_wrap_vecdouble_get(arg1, arg2) +} + +func _swig_wrap_vecdouble_set(SwigcptrVecdouble, int, *float64) + +func (arg1 SwigcptrVecdouble) Set(arg2 int, arg3 *float64) { + _swig_wrap_vecdouble_set(arg1, arg2, arg3) +} + +func _swig_wrap_vecdouble_getitem(SwigcptrVecdouble, int) float64 + +func (arg1 SwigcptrVecdouble) Getitem(arg2 int) float64 { + return _swig_wrap_vecdouble_getitem(arg1, arg2) +} + +func _swig_wrap_vecdouble_setitem(SwigcptrVecdouble, int, float64) + +func (arg1 SwigcptrVecdouble) Setitem(arg2 int, arg3 float64) { + _swig_wrap_vecdouble_setitem(arg1, arg2, arg3) +} + +func _swig_wrap_delete_vecdouble(uintptr) + +func DeleteVecdouble(arg1 Vecdouble) { + _swig_wrap_delete_vecdouble(arg1.Swigcptr()) +} + +type Vecdouble interface { + Swigcptr() uintptr + SwigIsVecdouble() + Get(arg2 int) *float64 + Set(arg2 int, arg3 *float64) + Getitem(arg2 int) float64 + Setitem(arg2 int, arg3 float64) +} + + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/template/example.h b/Examples/go/template/example.h new file mode 100644 index 000000000..7401df650 --- /dev/null +++ b/Examples/go/template/example.h @@ -0,0 +1,32 @@ +/* File : example.h */ + +// Some template definitions + +template T max(T a, T b) { return a>b ? a : b; } + +template class vector { + T *v; + int sz; + public: + vector(int _sz) { + v = new T[_sz]; + sz = _sz; + } + T &get(int index) { + return v[index]; + } + void set(int index, T &val) { + v[index] = val; + } +#ifdef SWIG + %extend { + T getitem(int index) { + return $self->get(index); + } + void setitem(int index, T val) { + $self->set(index,val); + } + } +#endif +}; + diff --git a/Examples/go/template/example.i b/Examples/go/template/example.i new file mode 100644 index 000000000..8f94c4da1 --- /dev/null +++ b/Examples/go/template/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ + +%template(maxint) max; +%template(maxdouble) max; +%template(vecint) vector; +%template(vecdouble) vector; + diff --git a/Examples/go/template/index.html b/Examples/go/template/index.html new file mode 100644 index 000000000..a14e3b29a --- /dev/null +++ b/Examples/go/template/index.html @@ -0,0 +1,113 @@ + + +SWIG:Examples:go:template + + + + + +SWIG/Examples/go/template/ +
      + +

      C++ template support

      + +

      +This example illustrates how C++ templates can be used from Go using +SWIG. + +

      The C++ Code

      + +Lets take a templated function and a templated class as follows: + +
      +
      +/* File : example.h */
      +
      +// Some template definitions
      +
      +template T max(T a, T b) { return  a>b ? a : b; }
      +
      +template class vector {
      +  T *v;
      +  int sz;
      + public:
      +  vector(int _sz) {
      +    v = new T[_sz];
      +    sz = _sz;
      +  }
      +  T &get(int index) {
      +    return v[index];
      +  }
      +  void set(int index, T &val) {
      +    v[index] = val;
      +  }
      +#ifdef SWIG
      +  %addmethods {
      +    T getitem(int index) {
      +      return self->get(index);
      +    }
      +    void setitem(int index, T val) {
      +      self->set(index,val);
      +    }
      +  }
      +#endif
      +};
      +
      +
      +The %addmethods is used for a neater interface from Go as the +functions get and set use C++ references to +primitive types. These are tricky to use from Go as they end up as +pointers, which only work when the C++ and Go types correspond +precisely. + +

      The SWIG interface

      + +A simple SWIG interface for this can be built by simply grabbing the +header file like this: + +
      +
      +/* File : example.i */
      +%module example
      +
      +%{
      +#include "example.h"
      +%}
      +
      +/* Let's just grab the original header file here */
      +%include "example.h"
      +
      +/* Now instantiate some specific template declarations */
      +
      +%template(maxint) max;
      +%template(maxdouble) max;
      +%template(vecint) vector;
      +%template(vecdouble) vector;
      +
      +
      + +Note that SWIG parses the templated function max and +templated class vector and so knows about them. However to +generate code for use from Go, SWIG has to be told which class/type to +use as the template parameter. The SWIG directive %template is used +for this. + +

      A sample Go program

      + +Click here to see a Go program that calls the +C++ functions from Go. + +

      Notes

      Use templated classes just like you would any other +SWIG generated Go class. Use the classnames specified by the %template +directive. + +
      +
      +vecdouble dv = new vecdouble(1000);
      +dv.setitem(i, 12.34));
      +
      +
      + +
      + + diff --git a/Examples/go/template/runme.go b/Examples/go/template/runme.go new file mode 100644 index 000000000..8b3d4000e --- /dev/null +++ b/Examples/go/template/runme.go @@ -0,0 +1,43 @@ +// This example illustrates how C++ templates can be used from Go. + +package main + +import ( + "fmt" + . "./example" +) + +func main() { + + // Call some templated functions + fmt.Println(Maxint(3, 7)) + fmt.Println(Maxdouble(3.14, 2.18)) + + // Create some class + iv := NewVecint(100) + dv := NewVecdouble(1000) + + for i := 0; i < 100; i++ { + iv.Setitem(i, 2*i) + } + + for i := 0; i < 1000; i++ { + dv.Setitem(i, 1.0/float64(i+1)) + } + + { + sum := 0 + for i := 0; i < 100; i++ { + sum = sum + iv.Getitem(i) + } + fmt.Println(sum) + } + + { + sum := float64(0.0) + for i := 0; i < 1000; i++ { + sum = sum + dv.Getitem(i) + } + fmt.Println(sum) + } +} diff --git a/Examples/go/variables/Makefile b/Examples/go/variables/Makefile new file mode 100644 index 000000000..b0aa9c970 --- /dev/null +++ b/Examples/go/variables/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = + +all:: go + +go:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go + +clean:: + $(MAKE) -f $(TOP)/Makefile go_clean + +check: all + $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run diff --git a/Examples/go/variables/example.c b/Examples/go/variables/example.c new file mode 100644 index 000000000..aa4ffe9b3 --- /dev/null +++ b/Examples/go/variables/example.c @@ -0,0 +1,91 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include +#include +#include "example.h" + +int ivar = 0; +short svar = 0; +long lvar = 0; +unsigned int uivar = 0; +unsigned short usvar = 0; +unsigned long ulvar = 0; +signed char scvar = 0; +unsigned char ucvar = 0; +char cvar = 0; +float fvar = 0; +double dvar = 0; +char *strvar = 0; +const char cstrvar[] = "Goodbye"; +int *iptrvar = 0; +char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; + +/* A variable that we will make read-only in the interface */ +int status = 1; + +/* A debugging function to print out their values */ + +void print_vars() { + printf("ivar = %d\n", ivar); + printf("svar = %d\n", svar); + printf("lvar = %ld\n", lvar); + printf("uivar = %u\n", uivar); + printf("usvar = %u\n", usvar); + printf("ulvar = %lu\n", ulvar); + printf("scvar = %d\n", scvar); + printf("ucvar = %u\n", ucvar); + printf("fvar = %g\n", fvar); + printf("dvar = %g\n", dvar); + printf("cvar = %c\n", cvar); + printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); + printf("iptrvar = %p\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); + printf("status = %d\n", status); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = value; + return ip; +} + +/* A function to create a point */ + +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d,%d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/go/variables/example.go b/Examples/go/variables/example.go new file mode 100644 index 000000000..f4f299b73 --- /dev/null +++ b/Examples/go/variables/example.go @@ -0,0 +1,198 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.1 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ + +package example + + +type _swig_fnptr *byte +type _swig_memberptr *byte + + +func _swig_allocatememory(int) *byte +func _swig_internal_allocate(len int) *byte { + return _swig_allocatememory(len) +} + +func _swig_allocatestring(*byte, int) string +func _swig_internal_makegostring(p *byte, l int) string { + return _swig_allocatestring(p, l) +} + +func _swig_internal_gopanic(p *byte, l int) { + panic(_swig_allocatestring(p, l)) +} + +func _swig_wrap_ivar_set(int) + +func SetIvar(arg1 int) { + _swig_wrap_ivar_set(arg1) +} + +func GetIvar() int +func _swig_wrap_svar_set(int16) + +func SetSvar(arg1 int16) { + _swig_wrap_svar_set(arg1) +} + +func GetSvar() int16 +func _swig_wrap_lvar_set(int32) + +func SetLvar(arg1 int32) { + _swig_wrap_lvar_set(arg1) +} + +func GetLvar() int32 +func _swig_wrap_uivar_set(uint) + +func SetUivar(arg1 uint) { + _swig_wrap_uivar_set(arg1) +} + +func GetUivar() uint +func _swig_wrap_usvar_set(uint16) + +func SetUsvar(arg1 uint16) { + _swig_wrap_usvar_set(arg1) +} + +func GetUsvar() uint16 +func _swig_wrap_ulvar_set(uint32) + +func SetUlvar(arg1 uint32) { + _swig_wrap_ulvar_set(arg1) +} + +func GetUlvar() uint32 +func _swig_wrap_scvar_set(int8) + +func SetScvar(arg1 int8) { + _swig_wrap_scvar_set(arg1) +} + +func GetScvar() int8 +func _swig_wrap_ucvar_set(byte) + +func SetUcvar(arg1 byte) { + _swig_wrap_ucvar_set(arg1) +} + +func GetUcvar() byte +func _swig_wrap_cvar_set(byte) + +func SetCvar(arg1 byte) { + _swig_wrap_cvar_set(arg1) +} + +func GetCvar() byte +func _swig_wrap_fvar_set(float32) + +func SetFvar(arg1 float32) { + _swig_wrap_fvar_set(arg1) +} + +func GetFvar() float32 +func _swig_wrap_dvar_set(float64) + +func SetDvar(arg1 float64) { + _swig_wrap_dvar_set(arg1) +} + +func GetDvar() float64 +func _swig_wrap_strvar_set(string) + +func SetStrvar(arg1 string) { + _swig_wrap_strvar_set(arg1) +} + +func GetStrvar() string +func GetCstrvar() string +func _swig_wrap_iptrvar_set(*int) + +func SetIptrvar(arg1 *int) { + _swig_wrap_iptrvar_set(arg1) +} + +func GetIptrvar() *int +func _swig_wrap_name_set(string) + +func SetName(arg1 string) { + _swig_wrap_name_set(arg1) +} + +func GetName() string +func _swig_wrap_ptptr_set(uintptr) + +func SetPtptr(arg1 Point) { + _swig_wrap_ptptr_set(arg1.Swigcptr()) +} + +func _swig_wrap_ptptr_get() SwigcptrPoint + +func GetPtptr() Point { + return _swig_wrap_ptptr_get() +} + +func _swig_wrap_pt_set(uintptr) + +func SetPt(arg1 Point) { + _swig_wrap_pt_set(arg1.Swigcptr()) +} + +func _swig_wrap_pt_get() SwigcptrPoint + +func GetPt() Point { + return _swig_wrap_pt_get() +} + +func GetStatus() int +func GetPath() string +func _swig_wrap_print_vars() + +func Print_vars() { + _swig_wrap_print_vars() +} + +func New_int(int) *int +func _swig_wrap_new_Point(int, int) SwigcptrPoint + +func New_Point(arg1 int, arg2 int) Point { + return _swig_wrap_new_Point(arg1, arg2) +} + +func _swig_wrap_Point_print(uintptr) string + +func Point_print(arg1 Point) string { + return _swig_wrap_Point_print(arg1.Swigcptr()) +} + +func _swig_wrap_pt_print() + +func Pt_print() { + _swig_wrap_pt_print() +} + + +type SwigcptrPoint uintptr +type Point interface { + Swigcptr() uintptr; +} +func (p SwigcptrPoint) Swigcptr() uintptr { + return uintptr(p) +} + +type SwigcptrVoid uintptr +type Void interface { + Swigcptr() uintptr; +} +func (p SwigcptrVoid) Swigcptr() uintptr { + return uintptr(p) +} + diff --git a/Examples/go/variables/example.h b/Examples/go/variables/example.h new file mode 100644 index 000000000..0f7e89594 --- /dev/null +++ b/Examples/go/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/go/variables/example.i b/Examples/go/variables/example.i new file mode 100644 index 000000000..591b871ed --- /dev/null +++ b/Examples/go/variables/example.i @@ -0,0 +1,49 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Some global variable declarations */ +%inline %{ +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char cstrvar[]; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; +%} + + +/* Some read-only variables */ + +%immutable; + +%inline %{ +extern int status; +extern char path[256]; +%} + +%mutable; + +/* Some helper functions to make it easier to test */ +%inline %{ +extern void print_vars(); +extern int *new_int(int value); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); +%} + diff --git a/Examples/go/variables/index.html b/Examples/go/variables/index.html new file mode 100644 index 000000000..5a11194df --- /dev/null +++ b/Examples/go/variables/index.html @@ -0,0 +1,87 @@ + + +SWIG:Examples:go:variables + + + + +SWIG/Examples/go/variables/ +
      + +

      Wrapping C Global Variables

      + +

      +When a C global variable appears in an interface file, SWIG provides +getter and setter functions for the variable. The getter function is +named Get followed by the capitalized name of the variable. +The setter variable starts with Set instead. The getter +function takes no parameters and returns the value of the variable. +The setter function takes a single parameter with the same type as the +variable, and returns nothing. + +

      Click here to see a SWIG interface with +some variable declarations in it. + +

      Manipulating Variables from Go

      + +For example, if the package is called example, the global +variable + +
      +
      +double foo;
      +
      +
      + +will be accessed from Go as +
      +
      +example.GetFoo();
      +example.SetFoo(12.3);
      +
      +
      + +Click here to see the example program that +updates and prints out the values of the variables using this +technique. + +

      Key points

      + +
        +
      • The name of the variable is capitalized. +
      • When a global variable has the type "char *", SWIG +manages it as a character string. +
      • signed char and unsigned char are handled as +small 8-bit integers. +
      • String array variables such as 'char name[256]' are +managed as Go strings, but when setting the value, the result is +truncated to the maximum length of the array. Furthermore, the string +is assumed to be null-terminated. +
      • When structures and classes are used as global variables, they are +mapped into pointers. Getting the "value" returns a pointer to the +global variable. Setting the value of a structure results in a memory +copy from a pointer to the global. +
      + +

      Creating read-only variables

      + +The %immutable and %mutable directives can be used +to specify a collection of read-only variables. A read only variable +will have a getter function but no setter function. For example: + +
      +
      +%immutable;
      +int    status;
      +double blah;
      +...
      +%mutable;
      +
      +
      + +The %immutable directive remains in effect until it is +explicitly disabled using the %mutable directive. + + + +
      diff --git a/Examples/go/variables/runme.go b/Examples/go/variables/runme.go new file mode 100644 index 000000000..26cad4b3c --- /dev/null +++ b/Examples/go/variables/runme.go @@ -0,0 +1,67 @@ +// This example illustrates global variable access from Go. + +package main + +import ( + "fmt" + "./example" +) + +func main() { + // Try to set the values of some global variables + + example.SetIvar(42) + example.SetSvar(-31000) + example.SetLvar(65537) + example.SetUivar(123456) + example.SetUsvar(61000) + example.SetUlvar(654321) + example.SetScvar(-13) + example.SetUcvar(251) + example.SetCvar('S') + example.SetFvar(3.14159) + example.SetDvar(2.1828) + example.SetStrvar("Hello World") + example.SetIptrvar(example.New_int(37)) + example.SetPtptr(example.New_Point(37, 42)) + example.SetName("Bill") + + // Now print out the values of the variables + + fmt.Println("Variables (values printed from Go)") + + fmt.Println("ivar =", example.GetIvar()) + fmt.Println("svar =", example.GetSvar()) + fmt.Println("lvar =", example.GetLvar()) + fmt.Println("uivar =", example.GetUivar()) + fmt.Println("usvar =", example.GetUsvar()) + fmt.Println("ulvar =", example.GetUlvar()) + fmt.Println("scvar =", example.GetScvar()) + fmt.Println("ucvar =", example.GetUcvar()) + fmt.Println("fvar =", example.GetFvar()) + fmt.Println("dvar =", example.GetDvar()) + fmt.Printf("cvar = %c\n", example.GetCvar()) + fmt.Println("strvar =", example.GetStrvar()) + fmt.Println("cstrvar =", example.GetCstrvar()) + fmt.Println("iptrvar =", example.GetIptrvar()) + fmt.Println("name =", example.GetName()) + fmt.Println("ptptr =", example.GetPtptr(), example.Point_print(example.GetPtptr())) + fmt.Println("pt =", example.GetPt(), example.Point_print(example.GetPt())) + + fmt.Println("\nVariables (values printed from C)") + + example.Print_vars() + + // This line would not compile: since status is marked with + // %immutable, there is no SetStatus function. + // fmt.Println("\nNow I'm going to try and modify some read only variables") + // example.SetStatus(0) + + fmt.Println("\nI'm going to try and update a structure variable.\n") + + example.SetPt(example.GetPtptr()) + + fmt.Println("The new value is") + example.Pt_print() + fmt.Println("You should see the value", example.Point_print(example.GetPtptr())) +} diff --git a/Examples/guile/README b/Examples/guile/README index acec7773b..7d726619e 100644 --- a/Examples/guile/README +++ b/Examples/guile/README @@ -12,6 +12,3 @@ std_vector -- C++ STL vector and vector Note that the examples in this directory build a special version of Guile which includes the wrapped functions in the top-level module. -If you want to put the wrapped functions into an own module, -statically or dynamically linked, see the Examples/GIFPlot/Guile -directory. diff --git a/Examples/index.html b/Examples/index.html index f8b614a89..66885b6a0 100644 --- a/Examples/index.html +++ b/Examples/index.html @@ -46,12 +46,6 @@ language: If your target platform is Windows, make sure you also see the Windows page in the main manual. -

      Real Life

      - -The GIFPlot directory contains examples that illustrate the use of SWIG with -a moderately complex C library for creating GIF images. Many of these -examples illustrate more advanced SWIG features. - diff --git a/Examples/perl5/index.html b/Examples/perl5/index.html index 5648c587d..db46023c4 100644 --- a/Examples/perl5/index.html +++ b/Examples/perl5/index.html @@ -68,9 +68,8 @@ Please see the Windows page in the m

      Due to wide variations in the Perl C API and differences between versions such as the ActivePerl release for Windows, -the code generated by SWIG is extremely messy. We have made every attempt to maintain compatibility with -many Perl releases going as far back as 5.003 and as recent as 5.6. However, your mileage may vary. -If you experience a problem, please let us know by +the code generated by SWIG is extremely messy. +If the code doesn't compile or work with your version of Perl, please let us know by contacting us on the mailing lists. Better yet, send us a patch. diff --git a/Examples/php/disown/runme.php b/Examples/php/disown/runme.php index 73d50786b..d90b03a9d 100644 --- a/Examples/php/disown/runme.php +++ b/Examples/php/disown/runme.php @@ -10,9 +10,9 @@ require("example.php"); print "Creating some objects:\n"; $c = new Circle(10); -print " Created circle $c\n"; +print " Created circle \$c\n"; $s = new Square(10); -print " Created square $s\n"; +print " Created square \$s\n"; # ----- Create the ShapeContainer ---- diff --git a/Examples/php/overloading/runme.php b/Examples/php/overloading/runme.php index 5aa69048d..01044445f 100644 --- a/Examples/php/overloading/runme.php +++ b/Examples/php/overloading/runme.php @@ -10,9 +10,9 @@ include("example.php"); print "Creating some objects:\n"; $c = new Circle(10); -print " Created circle $c\n"; +print " Created circle \$c\n"; $s = new Square(10); -print " Created square $s\n"; +print " Created square \$s\n"; # ----- Access a static member ----- @@ -37,7 +37,7 @@ print " Square = (" . $s->x . "," . $s->y . ")\n"; print "\nHere are some properties of the shapes:\n"; foreach (array(1, 2.1, "quick brown fox", $c, $s) as $o) { - print " ".get_class($o)." $o\n"; + print " ".get_class($o)." \$o\n"; print " overloaded = " . overloaded($o) . "\n"; } diff --git a/Examples/php/proxy/runme.php b/Examples/php/proxy/runme.php index dea80e358..e70ab229f 100644 --- a/Examples/php/proxy/runme.php +++ b/Examples/php/proxy/runme.php @@ -9,10 +9,10 @@ include("example.php"); # ----- Object creation ----- print "Creating some objects:\n"; -$c = CircleFactory(10); -print " Created circle $c with area ". $c->area() ."\n"; +$c = example::CircleFactory(10); +print " Created circle \$c with area ". $c->area() ."\n"; $s = new Square(10); -print " Created square $s\n"; +print " Created square \$s\n"; # ----- Access a static member ----- @@ -37,7 +37,7 @@ print " Square = (" . $s->x . "," . $s->y . ")\n"; print "\nHere are some properties of the shapes:\n"; foreach (array($c,$s) as $o) { - print " ".get_class($o)." $o\n"; + print " ".get_class($o)." \$o\n"; print " x = " . $o->x . "\n"; print " y = " . $o->y . "\n"; print " area = " . $o->area() . "\n"; diff --git a/Examples/php/reference/runme-proxy.php4 b/Examples/php/reference/runme-proxy.php4 deleted file mode 100644 index 9d216f78b..000000000 --- a/Examples/php/reference/runme-proxy.php4 +++ /dev/null @@ -1,79 +0,0 @@ -print() . "\n"; -print " Created b: $b " . $b->print() . "\n"; - -# ----- Call an overloaded operator ----- - -# This calls the wrapper we placed around -# -# operator+(const Vector &a, const Vector &) -# -# It returns a new allocated object. - -print "Adding a+b\n"; -$c = addv($a,$b); -print " a+b =". $c->print()."\n"; - -# Note: Unless we free the result, a memory leak will occur -$c = 0; - -# ----- Create a vector array ----- - -# Note: Using the high-level interface here -print "Creating an array of vectors\n"; -$va = new VectorArray(10); - -print " va: $va size=".$va->size()."\n"; - -# ----- Set some values in the array ----- - -# These operators copy the value of $a and $b to the vector array -$va->set(0,$a); -$va->set(1,$b); - -$va->get(0); -# This will work, but it will cause a memory leak! - -$va->set(2,addv($a,$b)); - -# The non-leaky way to do it - -$c = addv($a,$b); -$va->set(3,$c); -$c = NULL; - -# Get some values from the array - -print "Getting some array values\n"; -for ($i = 0; $i < 5; $i++) { -print "do $i\n"; - $v = $va->get($i); - print " va($i) = ". $v->print(). "\n"; -} - -# Watch under resource meter to check on this -#print "Making sure we don't leak memory.\n"; -#for ($i = 0; $i < 1000000; $i++) { -# $c = VectorArray_get($va,$i % 10); -#} - -# ----- Clean up ----- -print "Cleaning up\n"; -# wants fixing FIXME -#delete_VectorArray($va); -#delete_Vector($a); -#delete_Vector($b); - -?> diff --git a/Examples/php/variables/runme.php4.old b/Examples/php/variables/runme.php4.old deleted file mode 100644 index 9a6bfb386..000000000 --- a/Examples/php/variables/runme.php4.old +++ /dev/null @@ -1,80 +0,0 @@ - - diff --git a/Examples/python/weave/Makefile b/Examples/python/weave/Makefile deleted file mode 100644 index 88f95c095..000000000 --- a/Examples/python/weave/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = -TARGET = example -INTERFACE = example.i -LIBS = -lm -SWIGOPT = - -all:: - $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp - -static:: - $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static - -clean:: - $(MAKE) -f $(TOP)/Makefile python_clean - rm -f $(TARGET).py - -check: all - $(MAKE) -f $(TOP)/Makefile python_run diff --git a/Examples/python/weave/README b/Examples/python/weave/README deleted file mode 100644 index a616a4f46..000000000 --- a/Examples/python/weave/README +++ /dev/null @@ -1,25 +0,0 @@ -This directory contains a simple example to test weave support for -SWIG wrapped objects. - -The weave package provides tools for including C/C++ code in Python -code. This offers both another level of optimization to those who need -it, and an easy way to modify and extend any supported extension -libraries. Weave automatically builds an extension module from the -given C/C++ code and runs that. This can result in very significant -speedups (of upto 500x) depending on the problem. Weave also supports -inlining SWIG-1.3.x wrapped objects. - -The example in this directory requires that weave be installed. Weave -is distributed as part of SciPy (http://www.scipy.org). More -information on Weave may be had from here: - - http://www.scipy.org/documentation/weave - -As of November 22, 2004, this example only works with weave from CVS. -If there is a more recent release of SciPy after this date, it should -work fine. - - -Also, you need to replace the weave file swigptr2.py by the one -provided here. - diff --git a/Examples/python/weave/example.h b/Examples/python/weave/example.h deleted file mode 100644 index d09d60850..000000000 --- a/Examples/python/weave/example.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _EXAMPLE_H -#define _EXAMPLE_H - -class Foo { - public: - int x; -}; - -class Bar { - public: - int y; -}; - -class FooBar : public Foo, public Bar { - public: - int z; -}; -#endif diff --git a/Examples/python/weave/example.i b/Examples/python/weave/example.i deleted file mode 100644 index 5d71eaa93..000000000 --- a/Examples/python/weave/example.i +++ /dev/null @@ -1,15 +0,0 @@ -%module(directors="1") example - -%{ -#include "example.h" -%} - -%include "std_vector.i" - -%director Foo; -%director Bar; -%include "example.h" - - -%template(VectorBar) std::vector; -%template(VectorFoo) std::vector; diff --git a/Examples/python/weave/runme.py b/Examples/python/weave/runme.py deleted file mode 100644 index 529b4fc4b..000000000 --- a/Examples/python/weave/runme.py +++ /dev/null @@ -1,72 +0,0 @@ -""" -Test weave support for SWIG wrapped objects. - -This example requires that one has weave installed. Weave is -distributed as part of SciPy (http://www.scipy.org). More information -on Weave may be had from here: - - http://www.scipy.org/documentation/weave - -As of November 22, 2004, this only works with weave from CVS. If -there is a more recent release of SciPy after this date, it should -work fine. - -""" - -import example -import weave -from weave import converters -from weave import swig2_spec - -# Weave does not support swig2 by default (yet). So add this to the -# list of default converters to test. -converters.default.insert(0, swig2_spec.swig2_converter()) - -def test(): - """ A simple test case for weave.""" - a = example.Foo() - a.x = 1 - b = example.Bar() - b.y = 2 - c = example.FooBar() - c.x = 1 - c.y = 2 - c.z = 3 - v = example.VectorBar() - v.append(b) - v.append(c) - d = v[0] - e = v[1] - v = example.VectorFoo() - v.append(a) - v.append(c) - f = v[0] - g = v[1] - - code = """ - std::cout << a->x << std::endl; - assert(a->x == 1); - std::cout << b->y << std::endl; - assert(b->y == 2); - std::cout << c->x << std::endl; - std::cout << c->y << std::endl; - std::cout << c->z << std::endl; - assert(c->x == 1); - assert(c->y == 2); - assert(c->z == 3); - std::cout << d->y << std::endl; - assert(d->y == 2); - std::cout << e->y << std::endl; - assert(e->y == 2); - std::cout << f->x << std::endl; - assert(f->x == 1); - std::cout << g->x << std::endl; - assert(g->x == 1); - """ - weave.inline(code, ['a', 'b', 'c', 'd', 'e', 'f', 'g'], - include_dirs=['.'], - headers=['"example.h"'], - verbose=2) - -if __name__ == "__main__": - test() diff --git a/Examples/python/weave/swigptr2.py b/Examples/python/weave/swigptr2.py deleted file mode 100644 index 7ffe0fb65..000000000 --- a/Examples/python/weave/swigptr2.py +++ /dev/null @@ -1,3556 +0,0 @@ -# This code allows one to use SWIG wrapped objects from weave. This -# code is specific to SWIG-1.3 and above where things are different. -# The code is basically all copied out from the SWIG wrapper code but -# it has been hand edited for brevity. -# -# Prabhu Ramachandran - -###################################################################### -# This is for SWIG-1.3.x where x < 22. -# Essentially, SWIG_RUNTIME_VERSION was not yet used. -swigptr2_code_v0 = """ - -#include "Python.h" - -/*************************************************************** -*- c -*- - * python/precommon.swg - * - * Rename all exported symbols from common.swg, to avoid symbol - * clashes if multiple interpreters are included - * - ************************************************************************/ - -#define SWIG_TypeCheck SWIG_Python_TypeCheck -#define SWIG_TypeCast SWIG_Python_TypeCast -#define SWIG_TypeName SWIG_Python_TypeName -#define SWIG_TypeQuery SWIG_Python_TypeQuery -#define SWIG_PackData SWIG_Python_PackData -#define SWIG_UnpackData SWIG_Python_UnpackData - - -/*********************************************************************** - * common.swg - * - * This file contains generic SWIG runtime support for pointer - * type checking as well as a few commonly used macros to control - * external linkage. - * - * Author : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (c) 1999-2000, The University of Chicago - * - * This file may be freely redistributed without license or fee provided - * this copyright message remains intact. - ************************************************************************/ - -#include - -#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(_MSC_VER) || defined(__GNUC__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT(a) a -# define SWIGIMPORT(a) extern a -# else -# define SWIGEXPORT(a) __declspec(dllexport) a -# define SWIGIMPORT(a) extern a -# endif -# else -# if defined(__BORLANDC__) -# define SWIGEXPORT(a) a _export -# define SWIGIMPORT(a) a _export -# else -# define SWIGEXPORT(a) a -# define SWIGIMPORT(a) a -# endif -# endif -#else -# define SWIGEXPORT(a) a -# define SWIGIMPORT(a) a -#endif - -#ifdef SWIG_GLOBAL -# define SWIGRUNTIME(a) SWIGEXPORT(a) -#else -# define SWIGRUNTIME(a) static a -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *(*swig_converter_func)(void *); -typedef struct swig_type_info *(*swig_dycast_func)(void **); - -typedef struct swig_type_info { - const char *name; - swig_converter_func converter; - const char *str; - void *clientdata; - swig_dycast_func dcast; - struct swig_type_info *next; - struct swig_type_info *prev; -} swig_type_info; - -#ifdef SWIG_NOINCLUDE - -SWIGIMPORT(swig_type_info *) SWIG_TypeCheck(char *c, swig_type_info *); -SWIGIMPORT(void *) SWIG_TypeCast(swig_type_info *, void *); -SWIGIMPORT(const char *) SWIG_TypeName(const swig_type_info *); -SWIGIMPORT(swig_type_info *) SWIG_TypeQuery(const char *); -SWIGIMPORT(char *) SWIG_PackData(char *, void *, int); -SWIGIMPORT(char *) SWIG_UnpackData(char *, void *, int); - -#else - -static swig_type_info *swig_type_list = 0; - -/* Check the typename */ -SWIGRUNTIME(swig_type_info *) -SWIG_TypeCheck(char *c, swig_type_info *ty) { - swig_type_info *s; - if (!ty) return 0; /* Void pointer */ - s = ty->next; /* First element always just a name */ - do { - if (strcmp(s->name,c) == 0) { - if (s == ty->next) return s; - /* Move s to the top of the linked list */ - s->prev->next = s->next; - if (s->next) { - s->next->prev = s->prev; - } - /* Insert s as second element in the list */ - s->next = ty->next; - if (ty->next) ty->next->prev = s; - ty->next = s; - s->prev = ty; - return s; - } - s = s->next; - } while (s && (s != ty->next)); - return 0; -} - -/* Cast a pointer up an inheritance hierarchy */ -SWIGRUNTIME(void *) -SWIG_TypeCast(swig_type_info *ty, void *ptr) { - if ((!ty) || (!ty->converter)) return ptr; - return (*ty->converter)(ptr); -} - -/* Return the name associated with this type */ -SWIGRUNTIME(const char *) -SWIG_TypeName(const swig_type_info *ty) { - return ty->name; -} - -/* - Compare two type names skipping the space characters, therefore - "char*" == "char *" and "Class" == "Class", etc. - - Return 0 when the two name types are equivalent, as in - strncmp, but skipping ' '. -*/ -static 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; - } - return (l1 - f1) - (l2 - f2); -} - -/* - Check type equivalence in a name list like ||... -*/ -static int -SWIG_TypeEquiv(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = SWIG_TypeNameComp(nb, ne, tb, te) == 0; - if (*ne) ++ne; - } - return equiv; -} - - -/* Search for a swig_type_info structure */ -SWIGRUNTIME(swig_type_info *) -SWIG_TypeQuery(const char *name) { - swig_type_info *ty = swig_type_list; - while (ty) { - if (ty->str && (SWIG_TypeEquiv(ty->str,name))) return ty; - if (ty->name && (strcmp(name,ty->name) == 0)) return ty; - ty = ty->prev; - } - return 0; -} - -/* Pack binary data into a string */ -SWIGRUNTIME(char *) -SWIG_PackData(char *c, void *ptr, int sz) { - static char hex[17] = "0123456789abcdef"; - int i; - unsigned char *u = (unsigned char *) ptr; - register unsigned char uu; - for (i = 0; i < sz; i++,u++) { - uu = *u; - *(c++) = hex[(uu & 0xf0) >> 4]; - *(c++) = hex[uu & 0xf]; - } - return c; -} - -/* Unpack binary data from a string */ -SWIGRUNTIME(char *) -SWIG_UnpackData(char *c, void *ptr, int sz) { - register unsigned char uu = 0; - register int d; - unsigned char *u = (unsigned char *) ptr; - int i; - for (i = 0; i < sz; i++, u++) { - d = *(c++); - if ((d >= '0') && (d <= '9')) - uu = ((d - '0') << 4); - else if ((d >= 'a') && (d <= 'f')) - uu = ((d - ('a'-10)) << 4); - d = *(c++); - if ((d >= '0') && (d <= '9')) - uu |= (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - uu |= (d - ('a'-10)); - *u = uu; - } - return c; -} - -#endif - -#ifdef __cplusplus -} -#endif - -/*********************************************************************** - * python.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * Author : David Beazley (beazley@cs.uchicago.edu) - ************************************************************************/ - -#include "Python.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SWIG_PY_INT 1 -#define SWIG_PY_FLOAT 2 -#define SWIG_PY_STRING 3 -#define SWIG_PY_POINTER 4 -#define SWIG_PY_BINARY 5 - -/* Flags for pointer conversion */ - -#define SWIG_POINTER_EXCEPTION 0x1 -#define SWIG_POINTER_DISOWN 0x2 - -/* Exception handling in wrappers */ -#define SWIG_fail goto fail - -/* Constant information structure */ -typedef struct swig_const_info { - int type; - char *name; - long lvalue; - double dvalue; - void *pvalue; - swig_type_info **ptype; -} swig_const_info; - -/* Common SWIG API */ -#define SWIG_ConvertPtr(obj, pp, type, flags) \ - SWIG_Python_ConvertPtr(obj, pp, type, flags) -#define SWIG_NewPointerObj(p, type, flags) \ - SWIG_Python_NewPointerObj(p, type, flags) -#define SWIG_MustGetPtr(p, type, argnum, flags) \ - SWIG_Python_MustGetPtr(p, type, argnum, flags) - - -typedef double (*py_objasdbl_conv)(PyObject *obj); - -#ifdef SWIG_NOINCLUDE - -SWIGIMPORT(int) SWIG_Python_ConvertPtr(PyObject *, void **, swig_type_info *, int); -SWIGIMPORT(PyObject *) SWIG_Python_NewPointerObj(void *, swig_type_info *,int own); -SWIGIMPORT(void *) SWIG_Python_MustGetPtr(PyObject *, swig_type_info *, int, int); - -#else - - -/* Convert a pointer value */ -SWIGRUNTIME(int) -SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) { - swig_type_info *tc; - char *c = 0; - static PyObject *SWIG_this = 0; - int newref = 0; - PyObject *pyobj = 0; - - if (!obj) return 0; - if (obj == Py_None) { - *ptr = 0; - return 0; - } -#ifdef SWIG_COBJECT_TYPES - if (!(PyCObject_Check(obj))) { - if (!SWIG_this) - SWIG_this = PyString_FromString("this"); - pyobj = obj; - obj = PyObject_GetAttr(obj,SWIG_this); - newref = 1; - if (!obj) goto type_error; - if (!PyCObject_Check(obj)) { - Py_DECREF(obj); - goto type_error; - } - } - *ptr = PyCObject_AsVoidPtr(obj); - c = (char *) PyCObject_GetDesc(obj); - if (newref) Py_DECREF(obj); - goto cobject; -#else - if (!(PyString_Check(obj))) { - if (!SWIG_this) - SWIG_this = PyString_FromString("this"); - pyobj = obj; - obj = PyObject_GetAttr(obj,SWIG_this); - newref = 1; - if (!obj) goto type_error; - if (!PyString_Check(obj)) { - Py_DECREF(obj); - goto type_error; - } - } - c = PyString_AsString(obj); - /* Pointer values must start with leading underscore */ - if (*c != '_') { - *ptr = (void *) 0; - if (strcmp(c,"NULL") == 0) { - if (newref) { Py_DECREF(obj); } - return 0; - } else { - if (newref) { Py_DECREF(obj); } - goto type_error; - } - } - c++; - c = SWIG_UnpackData(c,ptr,sizeof(void *)); - if (newref) { Py_DECREF(obj); } -#endif - -#ifdef SWIG_COBJECT_TYPES -cobject: -#endif - - if (ty) { - tc = SWIG_TypeCheck(c,ty); - if (!tc) goto type_error; - *ptr = SWIG_TypeCast(tc,(void*) *ptr); - } - - if ((pyobj) && (flags & SWIG_POINTER_DISOWN)) { - PyObject *zero = PyInt_FromLong(0); - PyObject_SetAttrString(pyobj,(char*)"thisown",zero); - Py_DECREF(zero); - } - return 0; - -type_error: - PyErr_Clear(); - if (flags & SWIG_POINTER_EXCEPTION) { - if (ty && c) { - PyErr_Format(PyExc_TypeError, - "Type error. Got %s, expected %s", - c, ty->name); - } else { - PyErr_SetString(PyExc_TypeError,"Expected a pointer"); - } - } - return -1; -} - -/* Convert a pointer value, signal an exception on a type mismatch */ -SWIGRUNTIME(void *) -SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { - void *result; - SWIG_Python_ConvertPtr(obj, &result, ty, flags | SWIG_POINTER_EXCEPTION); - return result; -} - -/* Create a new pointer object */ -SWIGRUNTIME(PyObject *) -SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int own) { - PyObject *robj; - if (!ptr) { - Py_INCREF(Py_None); - return Py_None; - } -#ifdef SWIG_COBJECT_TYPES - robj = PyCObject_FromVoidPtrAndDesc((void *) ptr, (char *) type->name, NULL); -#else - { - char result[1024]; - char *r = result; - *(r++) = '_'; - r = SWIG_PackData(r,&ptr,sizeof(void *)); - strcpy(r,type->name); - robj = PyString_FromString(result); - } -#endif - if (!robj || (robj == Py_None)) return robj; - if (type->clientdata) { - PyObject *inst; - PyObject *args = Py_BuildValue((char*)"(O)", robj); - Py_DECREF(robj); - inst = PyObject_CallObject((PyObject *) type->clientdata, args); - Py_DECREF(args); - if (inst) { - if (own) { - PyObject *n = PyInt_FromLong(1); - PyObject_SetAttrString(inst,(char*)"thisown",n); - Py_DECREF(n); - } - robj = inst; - } - } - return robj; -} - -#endif - -#ifdef __cplusplus -} -#endif - -""" - - -###################################################################### -# This is for SWIG-1.3.x where x >= 23. -# SWIG_RUNTIME_VERSION == "1" - -# All this does is to include (cut/paste): -# and -swigptr2_code_v1 = """ -/*********************************************************************** - * swigrun.swg - * - * This file contains generic CAPI 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 "1" - -/* 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 - -#include - -#ifndef SWIGINLINE -#if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -#else -# define SWIGINLINE -#endif -#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 is strictly necessary, ie, if you have problems - with your compiler or so. -*/ -#ifndef SWIGRUNTIME -#define SWIGRUNTIME static -#endif -#ifndef SWIGRUNTIMEINLINE -#define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *(*swig_converter_func)(void *); -typedef struct swig_type_info *(*swig_dycast_func)(void **); - -typedef struct swig_type_info { - const char *name; - swig_converter_func converter; - const char *str; - void *clientdata; - swig_dycast_func dcast; - struct swig_type_info *next; - struct swig_type_info *prev; -} swig_type_info; - -/* - Compare two type names skipping the space characters, therefore - "char*" == "char *" and "Class" == "Class", 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; - } - return (l1 - f1) - (l2 - f2); -} - -/* - Check type equivalence in a name list like ||... -*/ -SWIGRUNTIME int -SWIG_TypeEquiv(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = SWIG_TypeNameComp(nb, ne, tb, te) == 0; - if (*ne) ++ne; - } - return equiv; -} - -/* - Register a type mapping with the type-checking -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeRegisterTL(swig_type_info **tl, swig_type_info *ti) { - swig_type_info *tc, *head, *ret, *next; - /* Check to see if this type has already been registered */ - tc = *tl; - while (tc) { - /* check simple type equivalence */ - int typeequiv = (strcmp(tc->name, ti->name) == 0); - /* check full type equivalence, resolving typedefs */ - if (!typeequiv) { - /* only if tc is not a typedef (no '|' on it) */ - if (tc->str && ti->str && !strstr(tc->str,"|")) { - typeequiv = SWIG_TypeEquiv(ti->str,tc->str); - } - } - if (typeequiv) { - /* Already exists in the table. Just add additional types to the list */ - if (ti->clientdata) tc->clientdata = ti->clientdata; - head = tc; - next = tc->next; - goto l1; - } - tc = tc->prev; - } - head = ti; - next = 0; - - /* Place in list */ - ti->prev = *tl; - *tl = ti; - - /* Build linked lists */ - l1: - ret = head; - tc = ti + 1; - /* Patch up the rest of the links */ - while (tc->name) { - head->next = tc; - tc->prev = head; - head = tc; - tc++; - } - if (next) next->prev = head; - head->next = next; - - return ret; -} - -/* - Check the typename -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeCheck(const char *c, swig_type_info *ty) { - swig_type_info *s; - if (!ty) return 0; /* Void pointer */ - s = ty->next; /* First element always just a name */ - do { - if (strcmp(s->name,c) == 0) { - if (s == ty->next) return s; - /* Move s to the top of the linked list */ - s->prev->next = s->next; - if (s->next) { - s->next->prev = s->prev; - } - /* Insert s as second element in the list */ - s->next = ty->next; - if (ty->next) ty->next->prev = s; - ty->next = s; - s->prev = ty; - return s; - } - s = s->next; - } while (s && (s != ty->next)); - return 0; -} - -/* - Cast a pointer up an inheritance hierarchy -*/ -SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_type_info *ty, void *ptr) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); -} - -/* - 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. We choose - to print the last name, as it is often (?) the most - specific. */ - 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; -} - -/* - Search for a swig_type_info structure -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeQueryTL(swig_type_info *tl, const char *name) { - swig_type_info *ty = tl; - while (ty) { - if (ty->str && (SWIG_TypeEquiv(ty->str,name))) return ty; - if (ty->name && (strcmp(name,ty->name) == 0)) return ty; - ty = ty->prev; - } - return 0; -} - -/* - Set the clientdata field for a type -*/ -SWIGRUNTIME void -SWIG_TypeClientDataTL(swig_type_info *tl, swig_type_info *ti, void *clientdata) { - swig_type_info *tc, *equiv; - if (ti->clientdata) return; - /* if (ti->clientdata == clientdata) return; */ - ti->clientdata = clientdata; - equiv = ti->next; - while (equiv) { - if (!equiv->converter) { - tc = tl; - while (tc) { - if ((strcmp(tc->name, equiv->name) == 0)) - SWIG_TypeClientDataTL(tl,tc,clientdata); - tc = tc->prev; - } - } - equiv = equiv->next; - } -} - -/* - Pack binary data into a string -*/ -SWIGRUNTIME char * -SWIG_PackData(char *c, void *ptr, size_t sz) { - static char hex[17] = "0123456789abcdef"; - unsigned char *u = (unsigned char *) ptr; - const unsigned char *eu = u + sz; - register unsigned char uu; - for (; u != eu; ++u) { - 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) { - register unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register int d = *(c++); - register unsigned char uu = 0; - 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; -} - -/* - 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_PropagateClientDataTL(swig_type_info *tl, swig_type_info *type) { - swig_type_info *equiv = type->next; - swig_type_info *tc; - if (!type->clientdata) return; - while (equiv) { - if (!equiv->converter) { - tc = tl; - while (tc) { - if ((strcmp(tc->name, equiv->name) == 0) && !tc->clientdata) - SWIG_TypeClientDataTL(tl,tc, type->clientdata); - tc = tc->prev; - } - } - equiv = equiv->next; - } -} - -/* - 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 - -/*********************************************************************** - * pyrun.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * Author : David Beazley (beazley@cs.uchicago.edu) - ************************************************************************/ - -/* Common SWIG API */ -#define SWIG_ConvertPtr(obj, pp, type, flags) SWIG_Python_ConvertPtr(obj, pp, type, flags) -#define SWIG_NewPointerObj(p, type, flags) SWIG_Python_NewPointerObj(p, type, flags) -#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) - - -/* Python-specific SWIG API */ -#define SWIG_ConvertPacked(obj, ptr, sz, ty, flags) SWIG_Python_ConvertPacked(obj, ptr, sz, ty, flags) -#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - - -/* ----------------------------------------------------------------------------- - * Pointer declarations - * ----------------------------------------------------------------------------- */ -/* - Use SWIG_NO_COBJECT_TYPES to force the use of strings to represent - C/C++ pointers in the python side. Very useful for debugging, but - not always safe. -*/ -#if !defined(SWIG_NO_COBJECT_TYPES) && !defined(SWIG_COBJECT_TYPES) -# define SWIG_COBJECT_TYPES -#endif - -/* Flags for pointer conversion */ -#define SWIG_POINTER_EXCEPTION 0x1 -#define SWIG_POINTER_DISOWN 0x2 - - -#ifdef __cplusplus -extern "C" { -#endif - -/* ----------------------------------------------------------------------------- - * Create a new pointer string - * ----------------------------------------------------------------------------- */ - -#ifndef SWIG_BUFFER_SIZE -#define SWIG_BUFFER_SIZE 1024 -#endif - -#if defined(SWIG_COBJECT_TYPES) -#if !defined(SWIG_COBJECT_PYTHON) -/* ----------------------------------------------------------------------------- - * Implements a simple Swig Object type, and use it instead of PyCObject - * ----------------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - void *ptr; - const char *desc; -} PySwigObject; - -/* Declarations for objects of type PySwigObject */ - -SWIGRUNTIME int -PySwigObject_print(PySwigObject *v, FILE *fp, int flags) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackVoidPtr(result, v->ptr, v->desc, sizeof(result))) { - fputs("", fp); - return 0; - } else { - return 1; - } -} - -SWIGRUNTIME PyObject * -PySwigObject_repr(PySwigObject *v) -{ - char result[SWIG_BUFFER_SIZE]; - return SWIG_PackVoidPtr(result, v->ptr, v->desc, sizeof(result)) ? - PyString_FromFormat("", result) : 0; -} - -SWIGRUNTIME PyObject * -PySwigObject_str(PySwigObject *v) -{ - char result[SWIG_BUFFER_SIZE]; - return SWIG_PackVoidPtr(result, v->ptr, v->desc, sizeof(result)) ? - PyString_FromString(result) : 0; -} - -SWIGRUNTIME PyObject * -PySwigObject_long(PySwigObject *v) -{ - return PyLong_FromUnsignedLong((unsigned long) v->ptr); -} - -SWIGRUNTIME PyObject * -PySwigObject_oct(PySwigObject *v) -{ - char buf[100]; - unsigned long x = (unsigned long)v->ptr; - if (x == 0) - strcpy(buf, "0"); - else - PyOS_snprintf(buf, sizeof(buf), "0%lo", x); - return PyString_FromString(buf); -} - -SWIGRUNTIME PyObject * -PySwigObject_hex(PySwigObject *v) -{ - char buf[100]; - PyOS_snprintf(buf, sizeof(buf), "0x%lx", (unsigned long)v->ptr); - return PyString_FromString(buf); -} - -SWIGRUNTIME int -PySwigObject_compare(PySwigObject *v, PySwigObject *w) -{ - int c = strcmp(v->desc, w->desc); - if (c) { - return c; - } else { - void *i = v->ptr; - void *j = w->ptr; - return (i < j) ? -1 : (i > j) ? 1 : 0; - } -} - -SWIGRUNTIME void -PySwigObject_dealloc(PySwigObject *self) -{ - PyObject_DEL(self); -} - -SWIGRUNTIME PyTypeObject* -PySwigObject_GetType() { - static char PySwigObject_Type__doc__[] = - "Swig object carries a C/C++ instance pointer"; - - static PyNumberMethods PySwigObject_as_number = { - (binaryfunc)0, /*nb_add*/ - (binaryfunc)0, /*nb_subtract*/ - (binaryfunc)0, /*nb_multiply*/ - (binaryfunc)0, /*nb_divide*/ - (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*/ - (coercion)0, /*nb_coerce*/ - (unaryfunc)PySwigObject_long, /*nb_int*/ - (unaryfunc)PySwigObject_long, /*nb_long*/ - (unaryfunc)0, /*nb_float*/ - (unaryfunc)PySwigObject_oct, /*nb_oct*/ - (unaryfunc)PySwigObject_hex, /*nb_hex*/ -#if PY_VERSION_HEX >= 0x02000000 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ -#endif - }; - - static PyTypeObject PySwigObject_Type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /*ob_size*/ - "PySwigObject", /*tp_name*/ - sizeof(PySwigObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PySwigObject_dealloc, /*tp_dealloc*/ - (printfunc)PySwigObject_print, /*tp_print*/ - (getattrfunc)0, /*tp_getattr*/ - (setattrfunc)0, /*tp_setattr*/ - (cmpfunc)PySwigObject_compare, /*tp_compare*/ - (reprfunc)PySwigObject_repr, /*tp_repr*/ - &PySwigObject_as_number, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)PySwigObject_str, /*tp_str*/ - /* Space for future expansion */ - 0L,0L,0L,0L, - PySwigObject_Type__doc__, /* Documentation string */ -#if PY_VERSION_HEX >= 0x02000000 - 0, /* tp_traverse */ - 0, /* tp_clear */ -#endif -#if PY_VERSION_HEX >= 0x02010000 - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#endif -#if PY_VERSION_HEX >= 0x02020000 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - - return &PySwigObject_Type; -} - -SWIGRUNTIME PyObject * -PySwigObject_FromVoidPtrAndDesc(void *ptr, const char *desc) -{ - PySwigObject *self = PyObject_NEW(PySwigObject, PySwigObject_GetType()); - if (self == NULL) return NULL; - self->ptr = ptr; - self->desc = desc; - return (PyObject *)self; -} - -SWIGRUNTIMEINLINE void * -PySwigObject_AsVoidPtr(PyObject *self) -{ - return ((PySwigObject *)self)->ptr; -} - -SWIGRUNTIMEINLINE const char * -PySwigObject_GetDesc(PyObject *self) -{ - return ((PySwigObject *)self)->desc; -} - -SWIGRUNTIMEINLINE int -PySwigObject_Check(PyObject *op) { - return ((op)->ob_type == PySwigObject_GetType()) - || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); -} - -/* ----------------------------------------------------------------------------- - * Implements a simple Swig Packed type, and use it instead of string - * ----------------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - void *pack; - const char *desc; - size_t size; -} PySwigPacked; - -SWIGRUNTIME int -PySwigPacked_print(PySwigPacked *v, FILE *fp, int flags) -{ - char result[SWIG_BUFFER_SIZE]; - fputs("pack, v->size, 0, sizeof(result))) { - fputs("at ", fp); - fputs(result, fp); - } - fputs(v->desc,fp); - fputs(">", fp); - return 0; -} - -SWIGRUNTIME PyObject * -PySwigPacked_repr(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { - return PyString_FromFormat("", result, v->desc); - } else { - return PyString_FromFormat("", v->desc); - } -} - -SWIGRUNTIME PyObject * -PySwigPacked_str(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ - return PyString_FromFormat("%s%s", result, v->desc); - } else { - return PyString_FromFormat("%s", v->desc); - } -} - -SWIGRUNTIME int -PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) -{ - int c = strcmp(v->desc, w->desc); - if (c) { - return c; - } else { - size_t i = v->size; - size_t j = w->size; - int s = (i < j) ? -1 : (i > j) ? 1 : 0; - return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); - } -} - -SWIGRUNTIME void -PySwigPacked_dealloc(PySwigPacked *self) -{ - free(self->pack); - PyObject_DEL(self); -} - -SWIGRUNTIME PyTypeObject* -PySwigPacked_GetType() { - static char PySwigPacked_Type__doc__[] = - "Swig object carries a C/C++ instance pointer"; - - static PyTypeObject PySwigPacked_Type = { - PyObject_HEAD_INIT(&PyType_Type) - 0, /*ob_size*/ - "PySwigPacked", /*tp_name*/ - sizeof(PySwigPacked), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PySwigPacked_dealloc, /*tp_dealloc*/ - (printfunc)PySwigPacked_print, /*tp_print*/ - (getattrfunc)0, /*tp_getattr*/ - (setattrfunc)0, /*tp_setattr*/ - (cmpfunc)PySwigPacked_compare, /*tp_compare*/ - (reprfunc)PySwigPacked_repr, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)PySwigPacked_str, /*tp_str*/ - /* Space for future expansion */ - 0L,0L,0L,0L, - PySwigPacked_Type__doc__, /* Documentation string */ -#if PY_VERSION_HEX >= 0x02000000 - 0, /* tp_traverse */ - 0, /* tp_clear */ -#endif -#if PY_VERSION_HEX >= 0x02010000 - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#endif -#if PY_VERSION_HEX >= 0x02020000 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - - return &PySwigPacked_Type; -} - -SWIGRUNTIME PyObject * -PySwigPacked_FromDataAndDesc(void *ptr, size_t size, const char *desc) -{ - PySwigPacked *self = PyObject_NEW(PySwigPacked, PySwigPacked_GetType()); - if (self == NULL) { - return NULL; - } else { - void *pack = malloc(size); - memcpy(pack, ptr, size); - self->pack = pack; - self->desc = desc; - self->size = size; - return (PyObject *) self; - } -} - -SWIGRUNTIMEINLINE const char * -PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) -{ - PySwigPacked *self = (PySwigPacked *)obj; - if (self->size != size) return 0; - memcpy(ptr, self->pack, size); - return self->desc; -} - -SWIGRUNTIMEINLINE const char * -PySwigPacked_GetDesc(PyObject *self) -{ - return ((PySwigPacked *)self)->desc; -} - -SWIGRUNTIMEINLINE int -PySwigPacked_Check(PyObject *op) { - return ((op)->ob_type == PySwigPacked_GetType()) - || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); -} - -#else -/* ----------------------------------------------------------------------------- - * Use the old Python PyCObject instead of PySwigObject - * ----------------------------------------------------------------------------- */ - -#define PySwigObject_GetDesc(obj) PyCObject_GetDesc(obj) -#define PySwigObject_Check(obj) PyCObject_Check(obj) -#define PySwigObject_AsVoidPtr(obj) PyCObject_AsVoidPtr(obj) -#define PySwigObject_FromVoidPtrAndDesc(p, d) PyCObject_FromVoidPtrAndDesc(p, d, NULL) - -#endif - -#endif - -/* ----------------------------------------------------------------------------- - * errors manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIME void -SWIG_Python_TypeError(const char *type, PyObject *obj) -{ - if (type) { -#if defined(SWIG_COBJECT_TYPES) - if (PySwigObject_Check(obj)) { - const char *otype = (const char *) PySwigObject_GetDesc(obj); - if (otype) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%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 ? PyString_AsString(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_DECREF(str); - return; - } - } - PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); - } else { - PyErr_Format(PyExc_TypeError, "unexpected type is received"); - } -} - -SWIGRUNTIMEINLINE void -SWIG_Python_NullRef(const char *type) -{ - if (type) { - PyErr_Format(PyExc_TypeError, "null reference of type '%s' was received",type); - } else { - PyErr_Format(PyExc_TypeError, "null reference was received"); - } -} - -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); - Py_XINCREF(type); - PyErr_Clear(); - if (infront) { - PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str)); - } else { - PyErr_Format(type, "%s %s", PyString_AsString(old_str), 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]; - sprintf(mesg, "argument number %d:", argnum); - return SWIG_Python_AddErrMesg(mesg, 1); - } else { - return 0; - } -} - - -/* ----------------------------------------------------------------------------- - * pointers/data manipulation - * ----------------------------------------------------------------------------- */ - -/* Convert a pointer value */ -SWIGRUNTIME int -SWIG_Python_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) { - swig_type_info *tc; - const char *c = 0; - static PyObject *SWIG_this = 0; - int newref = 0; - PyObject *pyobj = 0; - void *vptr; - - if (!obj) return 0; - if (obj == Py_None) { - *ptr = 0; - return 0; - } - -#ifdef SWIG_COBJECT_TYPES - if (!(PySwigObject_Check(obj))) { - if (!SWIG_this) - SWIG_this = PyString_FromString("this"); - pyobj = obj; - obj = PyObject_GetAttr(obj,SWIG_this); - newref = 1; - if (!obj) goto type_error; - if (!PySwigObject_Check(obj)) { - Py_DECREF(obj); - goto type_error; - } - } - vptr = PySwigObject_AsVoidPtr(obj); - c = (const char *) PySwigObject_GetDesc(obj); - if (newref) { Py_DECREF(obj); } - goto type_check; -#else - if (!(PyString_Check(obj))) { - if (!SWIG_this) - SWIG_this = PyString_FromString("this"); - pyobj = obj; - obj = PyObject_GetAttr(obj,SWIG_this); - newref = 1; - if (!obj) goto type_error; - if (!PyString_Check(obj)) { - Py_DECREF(obj); - goto type_error; - } - } - c = PyString_AS_STRING(obj); - /* Pointer values must start with leading underscore */ - c = SWIG_UnpackVoidPtr(c, &vptr, ty->name); - if (newref) { Py_DECREF(obj); } - if (!c) goto type_error; -#endif - -type_check: - - if (ty) { - tc = SWIG_TypeCheck(c,ty); - if (!tc) goto type_error; - *ptr = SWIG_TypeCast(tc,vptr); - } - - if ((pyobj) && (flags & SWIG_POINTER_DISOWN)) { - PyObject_SetAttrString(pyobj,(char*)"thisown",Py_False); - } - return 0; - -type_error: - PyErr_Clear(); - if (pyobj && !obj) { - obj = pyobj; - if (PyCFunction_Check(obj)) { - /* here we get the method pointer for callbacks */ - char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); - c = doc ? strstr(doc, "swig_ptr: ") : 0; - if (c) { - c = SWIG_UnpackVoidPtr(c + 10, &vptr, ty->name); - if (!c) goto type_error; - goto type_check; - } - } - } - if (flags & SWIG_POINTER_EXCEPTION) { - if (ty) { - SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); - } else { - SWIG_Python_TypeError("C/C++ pointer", obj); - } - } - return -1; -} - -/* Convert a pointer value, signal an exception on a type mismatch */ -SWIGRUNTIME void * -SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { - void *result; - if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { - PyErr_Clear(); - if (flags & SWIG_POINTER_EXCEPTION) { - SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); - SWIG_Python_ArgFail(argnum); - } - } - return result; -} - -/* Convert a packed value value */ -SWIGRUNTIME int -SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty, int flags) { - swig_type_info *tc; - const char *c = 0; - -#if defined(SWIG_COBJECT_TYPES) && !defined(SWIG_COBJECT_PYTHON) - c = PySwigPacked_UnpackData(obj, ptr, sz); -#else - if ((!obj) || (!PyString_Check(obj))) goto type_error; - c = PyString_AS_STRING(obj); - /* Pointer values must start with leading underscore */ - c = SWIG_UnpackDataName(c, ptr, sz, ty->name); -#endif - if (!c) goto type_error; - if (ty) { - tc = SWIG_TypeCheck(c,ty); - if (!tc) goto type_error; - } - return 0; - -type_error: - PyErr_Clear(); - if (flags & SWIG_POINTER_EXCEPTION) { - if (ty) { - SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); - } else { - SWIG_Python_TypeError("C/C++ packed data", obj); - } - } - return -1; -} - -/* Create a new array object */ -SWIGRUNTIME PyObject * -SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int own) { - PyObject *robj = 0; - if (!ptr) { - Py_INCREF(Py_None); - return Py_None; - } -#ifdef SWIG_COBJECT_TYPES - robj = PySwigObject_FromVoidPtrAndDesc((void *) ptr, (char *)type->name); -#else - { - char result[SWIG_BUFFER_SIZE]; - robj = SWIG_PackVoidPtr(result, ptr, type->name, sizeof(result)) ? - PyString_FromString(result) : 0; - } -#endif - if (!robj || (robj == Py_None)) return robj; - if (type->clientdata) { - PyObject *inst; - PyObject *args = Py_BuildValue((char*)"(O)", robj); - Py_DECREF(robj); - inst = PyObject_CallObject((PyObject *) type->clientdata, args); - Py_DECREF(args); - if (inst) { - if (own) { - PyObject_SetAttrString(inst,(char*)"thisown",Py_True); - } - robj = inst; - } - } - return robj; -} - -SWIGRUNTIME PyObject * -SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { - PyObject *robj = 0; - if (!ptr) { - Py_INCREF(Py_None); - return Py_None; - } -#if defined(SWIG_COBJECT_TYPES) && !defined(SWIG_COBJECT_PYTHON) - robj = PySwigPacked_FromDataAndDesc((void *) ptr, sz, (char *)type->name); -#else - { - char result[SWIG_BUFFER_SIZE]; - robj = SWIG_PackDataName(result, ptr, sz, type->name, sizeof(result)) ? - PyString_FromString(result) : 0; - } -#endif - return robj; -} - -/* -----------------------------------------------------------------------------* - * Get type list - * -----------------------------------------------------------------------------*/ - -#ifdef SWIG_LINK_RUNTIME -void *SWIG_ReturnGlobalTypeList(void *); -#endif - -SWIGRUNTIME swig_type_info ** -SWIG_Python_GetTypeListHandle() { - static void *type_pointer = (void *)0; - /* first check if module already created */ - if (!type_pointer) { -#ifdef SWIG_LINK_RUNTIME - type_pointer = SWIG_ReturnGlobalTypeList((void *)0); -#else - type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); - if (PyErr_Occurred()) { - PyErr_Clear(); - type_pointer = (void *)0; - } - } -#endif - return (swig_type_info **) type_pointer; -} - -/* - Search for a swig_type_info structure - */ -SWIGRUNTIMEINLINE swig_type_info * -SWIG_Python_GetTypeList() { - swig_type_info **tlh = SWIG_Python_GetTypeListHandle(); - return tlh ? *tlh : (swig_type_info*)0; -} - -#define SWIG_Runtime_GetTypeList SWIG_Python_GetTypeList - -#ifdef __cplusplus -} -#endif - -/* -----------------------------------------------------------------------------* - Standard SWIG API for use inside user code. - - You need to include in your code as follow: - -#include // or using your favorite language -#include -#include // or using your favorite language -#include - - * -----------------------------------------------------------------------------*/ - -SWIGRUNTIMEINLINE swig_type_info * -SWIG_Runtime_TypeQuery(const char *name) { - swig_type_info *tl = SWIG_Runtime_GetTypeList(); - return SWIG_TypeQueryTL(tl, name); -} - -SWIGRUNTIMEINLINE swig_type_info * -SWIG_Runtime_TypeRegister(swig_type_info *ti) { - swig_type_info *tl = SWIG_Runtime_GetTypeList(); - return SWIG_TypeRegisterTL(&tl, ti); -} - -SWIGRUNTIMEINLINE void -SWIG_Runtime_TypeClientData(swig_type_info *ti, void *clientdata) { - swig_type_info *tl = SWIG_Runtime_GetTypeList(); - SWIG_TypeClientDataTL(tl, ti, clientdata); -} - -SWIGRUNTIMEINLINE void -SWIG_Runtime_PropagateClientData(swig_type_info *type) { - swig_type_info *tl = SWIG_Runtime_GetTypeList(); - SWIG_PropagateClientDataTL(tl, type); -} - -#define SWIG_GetTypeList() SWIG_Runtime_GetTypeList() -#define SWIG_TypeQuery(name) SWIG_Runtime_TypeQuery(name) -#define SWIG_TypeRegister(ti) SWIG_Runtime_TypeRegister(ti) -#define SWIG_TypeClientData(ti, cd) SWIG_Runtime_TypeClientData(ti, cd) -#define SWIG_PropagateClientData(ti) SWIG_Runtime_PropagateClientData(ti) - -""" - -###################################################################### -# This is for SWIG-1.3.x where x >= 25. -# SWIG_RUNTIME_VERSION == "2" - -# All this does is to include the contents of the file generated by -# this command: -# swig -python -external-runtime -swigptr2_code_v2 = """ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.28 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -/*********************************************************************** - * - * 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) -# if (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -# 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 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 for Windows DLLs */ -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# define SWIGEXPORT -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - - -/* Errors in SWIG */ -#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 - - - -/*********************************************************************** - * swigrun.swg - * - * This file contains generic CAPI 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 "2" - -/* 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 is strictly necessary, ie, if you have problems - with your compiler or so. -*/ - -#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 - -/* Flags for new pointer objects */ -#define SWIG_POINTER_OWN 0x1 - - -/* - Flags/methods for returning states. - - The swig conversion methods, as ConvertPtr, return and 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 swig versions, you usually write code as: - - if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { - // success code - } else { - //fail code - } - - Now you can be more explicit as: - - int res = SWIG_ConvertPtr(obj,vptr,ty.flags); - if (SWIG_IsOK(res)) { - // success code - } else { - // fail code - } - - that seems to be the same, 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 - requires also to SWIG_ConvertPtr to return new result values, as - - int SWIG_ConvertPtr(obj, ptr,...) { - if () { - if () { - *ptr = ; - return SWIG_NEWOBJ; - } else { - *ptr = ; - 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 to return 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) -#define SWIG_ERROR (-1) -#define SWIG_IsOK(r) (r >= 0) - -/* 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 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 -# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) -#endif - - - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *(*swig_converter_func)(void *); -typedef struct swig_type_info *(*swig_dycast_func)(void **); - -/* Structure to store inforomation 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" == "Class", 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 (int)(*f1 - *f2); - } - return (l1 - f1) - (l2 - f2); -} - -/* - Check type equivalence in a name list like ||... - Return 0 if not equal, 1 if equal -*/ -SWIGRUNTIME int -SWIG_TypeEquiv(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - -/* - Check type equivalence in a name list like ||... - Return 0 if equal, -1 if nb < tb, 1 if nb > tb -*/ -SWIGRUNTIME int -SWIG_TypeCompare(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - - -/* think of this as a c++ template<> or a scheme macro */ -#define SWIG_TypeCheck_Template(comparison, ty) \ - if (ty) { \ - swig_cast_info *iter = ty->cast; \ - while (iter) { \ - if (comparison) { \ - 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 - -/* - Check the typename -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheck(const char *c, swig_type_info *ty) { - SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); -} - -/* Same as previous function, except strcmp is replaced with a pointer comparison */ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { - SWIG_TypeCheck_Template(iter->type == from, into); -} - -/* - Cast a pointer up an inheritance hierarchy -*/ -SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); -} - -/* - 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. We choose - to print the last name, as it is often (?) the most - specific. */ - 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) { - register size_t l = 0; - register size_t r = iter->size - 1; - do { - /* since l+r >= 0, we can (>> 1) instead (/ 2) */ - register size_t i = (l + r) >> 1; - const char *iname = iter->types[i]->name; - if (iname) { - register 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 { - register 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"; - register const unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register 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) { - register unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register char d = *(c++); - register 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; -} - -/* - 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 - -/*********************************************************************** - * pyrun.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * Author : David Beazley (beazley@cs.uchicago.edu) - ************************************************************************/ - -/* 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) -#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(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(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() -#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) -#define SWIG_NewClientData(obj) PySwigClientData_New(obj) - -/* A functor is a function object with one single object argument */ -#if PY_VERSION_HEX >= 0x02020000 -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); -#else -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); -#endif - -/* Error manipulation */ -#define SWIG_SetErrorObj(type, obj) {SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyErr_SetObject(type, obj); SWIG_PYTHON_THREAD_END_BLOCK; } -#define SWIG_SetErrorMsg(type, msg) {SWIG_PYTHON_THREAD_BEGIN_BLOCK; PyErr_SetString(type, msg); SWIG_PYTHON_THREAD_END_BLOCK; } -#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) -#define SWIG_Error(code, msg) SWIG_SetErrorMsg(SWIG_Python_ErrorType(code), msg) -#define SWIG_fail goto fail - - -/* - 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 - -/* ----------------------------------------------------------------------------- - * 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) - -/* For backward compatibility only */ -#define SWIG_POINTER_EXCEPTION 0 - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* cc-mode */ -#endif -#endif - -/* Safe Py_None and Py_Void accessors */ - -#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# ifndef SWIG_PYTHON_NO_SAFE_NONE -# ifndef SWIG_PYTHON_SAFE_NONE -# define SWIG_PYTHON_SAFE_NONE -# endif -# endif -#endif - -#ifdef SWIG_PYTHON_SAFE_NONE -SWIGRUNTIMEINLINE PyObject * -_SWIG_Py_None(void) -{ - PyObject *none = Py_BuildValue(""); - Py_DECREF(none); - return none; -} -SWIGRUNTIME PyObject * -SWIG_Py_None(void) -{ - static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); - return none; -} -# ifdef Py_None -# undef Py_None -# define Py_None SWIG_Py_None() -# endif -#endif - -SWIGRUNTIMEINLINE PyObject * -SWIG_Py_Void(void) -{ - PyObject *none = Py_None; - Py_INCREF(none); - return none; -} - -/* 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); - PyList_SetItem(result, 0, o2); - } - PyList_Append(result,obj); - Py_DECREF(obj); - } - return result; -} - -SWIGINTERN int -SWIG_Python_UnpackTuple(PyObject *args, const char *name, int min, int max, PyObject **objs) -{ - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); - return 0; - } else { - register int l = PyTuple_GET_SIZE(args); - if (l < min) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at least "), min, l); - return 0; - } else if (l > max) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at most "), max, l); - return 0; - } else { - register int i; - for (i = 0; i < l; ++i) { - objs[i] = PyTuple_GET_ITEM(args, i); - } - for (; l < max; ++l) { - objs[l] = 0; - } - return i + 1; - } - } -} - -/* PySwigClientData */ - -typedef struct { - PyObject *klass; - PyObject *newraw; - PyObject *newargs; - PyObject *destroy; - int delargs; - int implicitconv; -} PySwigClientData; - -SWIGRUNTIMEINLINE int -SWIG_Python_CheckImplicit(swig_type_info *ty) -{ - PySwigClientData *data = (PySwigClientData *)ty->clientdata; - return data ? data->implicitconv : 0; -} - - -SWIGRUNTIME PySwigClientData * -PySwigClientData_New(PyObject* obj) -{ - if (!obj) { - return 0; - } else { - PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); - /* the klass element */ - data->klass = obj; - Py_INCREF(obj); - /* the newraw method and newargs arguments used to create a new raw instance */ - if (PyClass_Check(obj)) { - data->newraw = 0; - data->newargs = obj; - Py_INCREF(obj); - } else { -#if (PY_VERSION_HEX < 0x02020000) - data->newraw = 0; - data->newargs = obj; - Py_INCREF(obj); -#else - data->newraw = PyObject_GetAttrString((PyObject*)&PyBaseObject_Type, "__new__"); - Py_INCREF(data->newraw); - data->newargs = PyTuple_New(1); - PyTuple_SetItem(data->newargs, 0, obj); - Py_INCREF(data->newargs); -#endif - } - /* 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) { - Py_INCREF(data->destroy); - int flags = PyCFunction_GET_FLAGS(data->destroy); -#ifdef METH_O - data->delargs = !(flags & (METH_O)); -#else - data->delargs = 0; -#endif - } else { - data->delargs = 0; - } - data->implicitconv = 0; - return data; - } -} - -SWIGRUNTIME void -PySwigClientData_Del(PySwigClientData* data) -{ - Py_XDECREF(data->klass); - Py_XDECREF(data->newraw); - Py_XDECREF(data->newargs); - Py_XDECREF(data->destroy); - free(data); -} - -/* =============== PySwigObject =====================*/ - -typedef struct { - PyObject_HEAD - void *ptr; - swig_type_info *ty; - int own; - PyObject *next; -} PySwigObject; - -SWIGRUNTIME PyObject * -PySwigObject_long(PySwigObject *v) -{ - return PyLong_FromVoidPtr(v->ptr); -} - -SWIGRUNTIME PyObject * -PySwigObject_format(const char* fmt, PySwigObject *v) -{ - PyObject *res = NULL; - PyObject *args = PyTuple_New(1); - if (args) { - if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) { - PyObject *ofmt = PyString_FromString(fmt); - if (ofmt) { - res = PyString_Format(ofmt,args); - Py_DECREF(ofmt); - } - Py_DECREF(args); - } - } - return res; -} - -SWIGRUNTIME PyObject * -PySwigObject_oct(PySwigObject *v) -{ - return PySwigObject_format("%o",v); -} - -SWIGRUNTIME PyObject * -PySwigObject_hex(PySwigObject *v) -{ - return PySwigObject_format("%x",v); -} - -SWIGRUNTIME PyObject * -PySwigObject_repr(PySwigObject *v) -{ - const char *name = SWIG_TypePrettyName(v->ty); - PyObject *hex = PySwigObject_hex(v); - PyObject *repr = PyString_FromFormat("", name, PyString_AsString(hex)); - Py_DECREF(hex); - if (v->next) { - PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); - PyString_ConcatAndDel(&repr,nrep); - } - return repr; -} - -SWIGRUNTIME int -PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ - PyObject *repr = PySwigObject_repr(v); - if (repr) { - fputs(PyString_AsString(repr), fp); - Py_DECREF(repr); - return 0; - } else { - return 1; - } -} - -SWIGRUNTIME PyObject * -PySwigObject_str(PySwigObject *v) -{ - char result[SWIG_BUFFER_SIZE]; - return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? - PyString_FromString(result) : 0; -} - -SWIGRUNTIME int -PySwigObject_compare(PySwigObject *v, PySwigObject *w) -{ - void *i = v->ptr; - void *j = w->ptr; - return (i < j) ? -1 : ((i > j) ? 1 : 0); -} - -SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); - -SWIGRUNTIME PyTypeObject* -PySwigObject_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); - return type; -} - -SWIGRUNTIMEINLINE int -PySwigObject_Check(PyObject *op) { - return ((op)->ob_type == PySwigObject_type()) - || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); -} - - -SWIGRUNTIME PyObject * -PySwigObject_New(void *ptr, swig_type_info *ty, int own); - -SWIGRUNTIME void -PySwigObject_dealloc(PyObject *v) -{ - PySwigObject *sobj = (PySwigObject *) v; - PyObject *next = sobj->next; - if (sobj->own) { - swig_type_info *ty = sobj->ty; - PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; - PyObject *destroy = data ? data->destroy : 0; - if (destroy) { - /* destroy is always a VARARGS method */ - PyObject *res; - if (data->delargs) { - /* we need to create a temporal object to carry the destroy operation */ - PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); - res = SWIG_Python_CallFunctor(destroy, tmp); - Py_DECREF(tmp); - } else { - PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); - PyObject *mself = PyCFunction_GET_SELF(destroy); - res = ((*meth)(mself, v)); - } - Py_XDECREF(res); - } else { - const char *name = SWIG_TypePrettyName(ty); -#if (PY_VERSION_HEX >= 0x02020000) - PyObject *wrn = PyString_FromFormat("swig/python detected a memory leak of type '%s'.", name); - PyErr_Warn(PyExc_RuntimeWarning, PyString_AsString(wrn)); - Py_DECREF(wrn); -#else - printf("swig/python detected a memory leak of type '%s'.", name); -#endif - } - } - Py_XDECREF(next); - PyObject_DEL(v); -} - -SWIGRUNTIME PyObject* -PySwigObject_append(PyObject* v, PyObject* next) -{ - PySwigObject *sobj = (PySwigObject *) v; -#ifndef METH_O - PyObject *tmp = 0; - if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; - next = tmp; -#endif - if (!PySwigObject_Check(next)) { - return NULL; - } - sobj->next = next; - Py_INCREF(next); - return SWIG_Py_Void(); -} - -SWIGRUNTIME PyObject* -#ifdef METH_NOARGS -PySwigObject_next(PyObject* v) -#else -PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *) v; - if (sobj->next) { - Py_INCREF(sobj->next); - return sobj->next; - } else { - return SWIG_Py_Void(); - } -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -PySwigObject_disown(PyObject *v) -#else -PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *)v; - sobj->own = 0; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -PySwigObject_acquire(PyObject *v) -#else -PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *)v; - sobj->own = SWIG_POINTER_OWN; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -PySwigObject_own(PyObject *v, PyObject *args) -{ - PyObject *val = 0; -#if (PY_VERSION_HEX < 0x02020000) - if (!PyArg_ParseTuple(args,(char *)"O:own",&val)) -#else - if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) -#endif - { - return NULL; - } - else - { - PySwigObject *sobj = (PySwigObject *)v; - PyObject *obj = sobj->own ? Py_True : Py_False; - if (val) { -#ifdef METH_NOARGS - if (PyObject_IsTrue(val)) { - PySwigObject_acquire(v); - } else { - PySwigObject_disown(v); - } -#else - if (PyObject_IsTrue(val)) { - PySwigObject_acquire(v,args); - } else { - PySwigObject_disown(v,args); - } -#endif - } - Py_INCREF(obj); - return obj; - } -} - -SWIGRUNTIME PyTypeObject* -_PySwigObject_type(void) { - static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; - static PyMethodDef -#ifdef METH_O - swigobject_methods[] = { - {"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, "releases ownership of the pointer"}, - {"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, "aquires ownership of the pointer"}, - {"own", (PyCFunction)PySwigObject_own, METH_VARARGS, "returns/sets ownership of the pointer"}, - {"append", (PyCFunction)PySwigObject_append, METH_O, "appends another 'this' object"}, - {"next", (PyCFunction)PySwigObject_next, METH_NOARGS, "returns the next 'this' object"}, - {0, 0, 0, 0} - }; -#else - swigobject_methods[] = { - {"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, "releases ownership of the pointer"}, - {"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, "aquires ownership of the pointer"}, - {"own", (PyCFunction)PySwigObject_own, METH_VARARGS, "returns/sets ownership of the pointer"}, - {"append", (PyCFunction)PySwigObject_append, METH_VARARGS, "appends another 'this' object"}, - {"next", (PyCFunction)PySwigObject_next, METH_VARARGS, "returns the next 'this' object"}, - {0, 0, 0, 0} - }; -#endif - - static PyNumberMethods PySwigObject_as_number = { - (binaryfunc)0, /*nb_add*/ - (binaryfunc)0, /*nb_subtract*/ - (binaryfunc)0, /*nb_multiply*/ - (binaryfunc)0, /*nb_divide*/ - (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*/ - (coercion)0, /*nb_coerce*/ - (unaryfunc)PySwigObject_long, /*nb_int*/ - (unaryfunc)PySwigObject_long, /*nb_long*/ - (unaryfunc)0, /*nb_float*/ - (unaryfunc)PySwigObject_oct, /*nb_oct*/ - (unaryfunc)PySwigObject_hex, /*nb_hex*/ -#if PY_VERSION_HEX >= 0x02020000 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ -#elif PY_VERSION_HEX >= 0x02000000 - 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ -#endif - }; - - static PyTypeObject pyswigobject_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - (char *)"PySwigObject", /* tp_name */ - sizeof(PySwigObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)PySwigObject_dealloc, /* tp_dealloc */ - (printfunc)PySwigObject_print, /* tp_print */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)PySwigObject_compare, /* tp_compare */ - (reprfunc)PySwigObject_repr, /* tp_repr */ - &PySwigObject_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)PySwigObject_str, /* 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 */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 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 */ - PyObject_Del, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - pyswigobject_type = tmp; - pyswigobject_type.ob_type = &PyType_Type; - type_init = 1; - } - return &pyswigobject_type; -} - -SWIGRUNTIME PyObject * -PySwigObject_New(void *ptr, swig_type_info *ty, int own) -{ - PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); - if (sobj) { - sobj->ptr = ptr; - sobj->ty = ty; - sobj->own = own; - sobj->next = 0; - } - 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; -} PySwigPacked; - -SWIGRUNTIME int -PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ - char result[SWIG_BUFFER_SIZE]; - fputs("pack, v->size, 0, sizeof(result))) { - fputs("at ", fp); - fputs(result, fp); - } - fputs(v->ty->name,fp); - fputs(">", fp); - return 0; -} - -SWIGRUNTIME PyObject * -PySwigPacked_repr(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { - return PyString_FromFormat("", result, v->ty->name); - } else { - return PyString_FromFormat("", v->ty->name); - } -} - -SWIGRUNTIME PyObject * -PySwigPacked_str(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ - return PyString_FromFormat("%s%s", result, v->ty->name); - } else { - return PyString_FromString(v->ty->name); - } -} - -SWIGRUNTIME int -PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) -{ - size_t i = v->size; - size_t j = w->size; - int s = (i < j) ? -1 : ((i > j) ? 1 : 0); - return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); -} - -SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); - -SWIGRUNTIME PyTypeObject* -PySwigPacked_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); - return type; -} - -SWIGRUNTIMEINLINE int -PySwigPacked_Check(PyObject *op) { - return ((op)->ob_type == _PySwigPacked_type()) - || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); -} - -SWIGRUNTIME void -PySwigPacked_dealloc(PyObject *v) -{ - if (PySwigPacked_Check(v)) { - PySwigPacked *sobj = (PySwigPacked *) v; - free(sobj->pack); - } - PyObject_DEL(v); -} - -SWIGRUNTIME PyTypeObject* -_PySwigPacked_type(void) { - static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; - static PyTypeObject pyswigpacked_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - (char *)"PySwigPacked", /* tp_name */ - sizeof(PySwigPacked), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)PySwigPacked_dealloc, /* tp_dealloc */ - (printfunc)PySwigPacked_print, /* tp_print */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)PySwigPacked_compare, /* tp_compare */ - (reprfunc)PySwigPacked_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)PySwigPacked_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 */ -#if PY_VERSION_HEX >= 0x02020000 - 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 */ - PyObject_Del, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - pyswigpacked_type = tmp; - pyswigpacked_type.ob_type = &PyType_Type; - type_init = 1; - } - return &pyswigpacked_type; -} - -SWIGRUNTIME PyObject * -PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) -{ - PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_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 * -PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) -{ - if (PySwigPacked_Check(obj)) { - PySwigPacked *sobj = (PySwigPacked *)obj; - if (sobj->size != size) return 0; - memcpy(ptr, sobj->pack, size); - return sobj->ty; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * pointers/data manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIME PyObject * -_SWIG_This(void) -{ - static PyObject *_this = 0; - if (!_this) { - _this = PyString_FromString("this"); - } - return _this; -} - -SWIGRUNTIME PyObject * -SWIG_This(void) -{ - static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); - return swig_this; -} - -/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ - -SWIGRUNTIME PySwigObject * -SWIG_Python_GetSwigThis(PyObject *pyobj) -{ - if (PySwigObject_Check(pyobj)) { - return (PySwigObject *) pyobj; - } else { - PyObject *obj = 0; -#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && !(PY_VERSION_HEX < 0x02020000)) - 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; - } -#ifdef PyWeakref_CheckProxy - else if (PyWeakref_CheckProxy(pyobj)) { - PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); - return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; - } -#endif - if (!obj) { - 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 - return (PySwigObject *)obj; - } -} - - -/* Acquire a pointer value */ - -SWIGRUNTIME int -SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own) { - PySwigObject *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) { - if (!obj) return SWIG_ERROR; - if (obj == Py_None) { - if (ptr) *ptr = 0; - return SWIG_OK; - } else { - PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); - 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 = (PySwigObject *)sobj->next; - } else { - if (ptr) *ptr = SWIG_TypeCast(tc,vptr); - break; - } - } - } else { - if (ptr) *ptr = vptr; - break; - } - } - if (sobj) { - if (own) *own = sobj->own; - if (flags & SWIG_POINTER_DISOWN) { - sobj->own = 0; - } - return SWIG_OK; - } else { - int res = SWIG_ERROR; - if (flags & SWIG_POINTER_IMPLICIT_CONV) { - PySwigClientData *data = ty ? (PySwigClientData *) 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) { - PySwigObject *sobj = SWIG_Python_GetSwigThis(impconv); - if (sobj) { - void *vptr; - res = SWIG_Python_ConvertPtrAndOwn((PyObject*)sobj, &vptr, ty, 0, 0); - if (SWIG_IsOK(res)) { - if (ptr) { - *ptr = vptr; - /* transfer the ownership to 'ptr' */ - sobj->own = 0; - res = SWIG_AddNewMask(SWIG_AddCast(res)); - } else { - res = SWIG_AddCast(res); - } - } - } - Py_DECREF(impconv); - } - } - } - } - 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; - - /* here we get the method pointer for callbacks */ - 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; - } - if (ty) { - swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (!tc) return SWIG_ERROR; - *ptr = SWIG_TypeCast(tc,vptr); - } else { - *ptr = vptr; - } - return SWIG_OK; - } -} - -/* Convert a packed value value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { - swig_type_info *to = PySwigPacked_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, whitout calling __init__, and set the - 'this' attribute. -*/ - -SWIGRUNTIME PyObject* -SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) -{ -#if (PY_VERSION_HEX >= 0x02020000) - 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; - PyDict_SetItem(dict, SWIG_This(), swig_this); - } - } -#else - PyObject *key = SWIG_This(); - PyObject_SetAttr(inst, key, swig_this); -#endif - } - } else { - PyObject *dict = PyDict_New(); - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - } - return inst; -#else - PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); - if (inst == NULL) { - return NULL; - } - inst->in_class = (PyClassObject *)data->newargs; - Py_INCREF(inst->in_class); - inst->in_dict = PyDict_New(); - if (inst->in_dict == NULL) { - Py_DECREF(inst); - return NULL; - } - PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); - return (PyObject *) inst; -#endif -} - -/* Create a new pointer object */ - -SWIGRUNTIME PyObject * -SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { - if (!ptr) { - return SWIG_Py_Void(); - } else { - int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; - PyObject *robj = PySwigObject_New(ptr, type, own); - PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0; - if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { - PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); - if (inst) { - 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 ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); -} - -/* -----------------------------------------------------------------------------* - * Get type list - * -----------------------------------------------------------------------------*/ - -#ifdef SWIG_LINK_RUNTIME -void *SWIG_ReturnGlobalTypeList(void *); -#endif - -SWIGRUNTIME swig_module_info * -SWIG_Python_GetModule(void) { - static void *type_pointer = (void *)0; - /* first check if module already created */ - if (!type_pointer) { -#ifdef SWIG_LINK_RUNTIME - type_pointer = SWIG_ReturnGlobalTypeList((void *)0); -#else - type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); - if (PyErr_Occurred()) { - PyErr_Clear(); - type_pointer = (void *)0; - } -#endif - } - return (swig_module_info *) type_pointer; -} - -#if PY_MAJOR_VERSION < 2 -/* PyModule_AddObject function was introduced in Python 2.0. The following function - is copied out of Python/modsupport.c in python version 2.3.4 */ -SWIGINTERN int -PyModule_AddObject(PyObject *m, char *name, PyObject *o) -{ - PyObject *dict; - if (!PyModule_Check(m)) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs module as first arg"); - return SWIG_ERROR; - } - if (!o) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs non-NULL value"); - return SWIG_ERROR; - } - - dict = PyModule_GetDict(m); - if (dict == NULL) { - /* Internal error -- modules must have a dict! */ - PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", - PyModule_GetName(m)); - return SWIG_ERROR; - } - if (PyDict_SetItemString(dict, name, o)) - return SWIG_ERROR; - Py_DECREF(o); - return SWIG_OK; -} -#endif - -SWIGRUNTIME void -SWIG_Python_DestroyModule(void *vptr) -{ - swig_module_info *swig_module = (swig_module_info *) vptr; - swig_type_info **types = swig_module->types; - size_t i; - for (i =0; i < swig_module->size; ++i) { - swig_type_info *ty = types[i]; - if (ty->owndata) { - PySwigClientData *data = (PySwigClientData *) ty->clientdata; - if (data) PySwigClientData_Del(data); - ty->clientdata = 0; - } - } - Py_DECREF(SWIG_This()); -} - -SWIGRUNTIME void -SWIG_Python_SetModule(swig_module_info *swig_module) { - static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ - - PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - swig_empty_runtime_method_table); - PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); - if (pointer && module) { - PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); - } else { - Py_XDECREF(pointer); - } -} - -#ifdef __cplusplus -#if 0 -{ /* cc-mode */ -#endif -} -#endif - -/* -----------------------------------------------------------------------------* - Standard SWIG API for use inside user code. - - Don't include this file directly, run the command - swig -python -external-runtime - Also, read the Modules chapter of the SWIG Manual. - - * -----------------------------------------------------------------------------*/ - -#ifdef SWIG_MODULE_CLIENTDATA_TYPE - -SWIGRUNTIMEINLINE swig_type_info * -SWIG_TypeQuery(SWIG_MODULE_CLIENTDATA_TYPE clientdata, const char *name) { - swig_module_info *module = SWIG_GetModule(clientdata); - return SWIG_TypeQueryModule(module, module, name); -} - -SWIGRUNTIMEINLINE swig_type_info * -SWIG_MangledTypeQuery(SWIG_MODULE_CLIENTDATA_TYPE clientdata, const char *name) { - swig_module_info *module = SWIG_GetModule(clientdata); - return SWIG_MangledTypeQueryModule(module, module, name); -} - -#else - -SWIGRUNTIMEINLINE swig_type_info * -SWIG_TypeQuery(const char *name) { - swig_module_info *module = SWIG_GetModule(NULL); - return SWIG_TypeQueryModule(module, module, name); -} - -SWIGRUNTIMEINLINE swig_type_info * -SWIG_MangledTypeQuery(const char *name) { - swig_module_info *module = SWIG_GetModule(NULL); - return SWIG_MangledTypeQueryModule(module, module, name); -} - -#endif - -""" diff --git a/Examples/r/class/Makefile b/Examples/r/class/Makefile index 6bed3ce53..0cd8ed3d3 100644 --- a/Examples/r/class/Makefile +++ b/Examples/r/class/Makefile @@ -3,16 +3,13 @@ SWIG = $(TOP)/../preinst-swig CXXSRCS = example.cxx TARGET = example INTERFACE = example.i -LIBS = -lm -ARGS = SRCS='$(SRCS)' SWIG='$(SWIG)' \ - TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' r_cpp clean:: - $(MAKE) -f $(TOP)/Makefile $(ARGS) r_clean + $(MAKE) -f $(TOP)/Makefile INTERFACE='$(INTERFACE)' r_clean check: all R CMD BATCH runme.R diff --git a/Examples/r/simple/Makefile b/Examples/r/simple/Makefile index e01d35925..5ef29565a 100644 --- a/Examples/r/simple/Makefile +++ b/Examples/r/simple/Makefile @@ -3,14 +3,13 @@ SWIG = $(TOP)/../preinst-swig SRCS = example.c TARGET = example INTERFACE = example.i -ARGS = SRCS='$(SRCS)' SWIG='$(SWIG)' \ - TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' all:: - $(MAKE) -f $(TOP)/Makefile $(ARGS) r + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' r clean:: - $(MAKE) -f $(TOP)/Makefile $(ARGS) r_clean + $(MAKE) -f $(TOP)/Makefile INTERFACE='$(INTERFACE)' r_clean check: all R CMD BATCH runme.R diff --git a/Examples/s-exp/uffi.lisp b/Examples/s-exp/uffi.lisp index 5ddb4c20f..253f85aba 100644 --- a/Examples/s-exp/uffi.lisp +++ b/Examples/s-exp/uffi.lisp @@ -312,67 +312,6 @@ is no representation." ;; Test instances -#|| - -#+ignore -(defvar *gifplot-interface* - (run-swig (merge-pathnames "Examples/GIFPlot/Interface/gifplot.i" - *swig-source-directory*) - :directory-search-list (list (merge-pathnames "Examples/GIFPlot/Interface/" *swig-source-directory*)))) - -(defvar *simple-gifplot-interface* - (run-swig (merge-pathnames "Examples/GIFPlot/Include/gifplot.h" - *swig-source-directory*) - :directory-search-list (list (merge-pathnames "Examples/GIFPlot/Interface/" *swig-source-directory*)) - :module "gifplot")) - -(defvar *cplex-glue-directory* #p"/home/mkoeppe/cvs/cplex-glue/") - -(defvar *cplex-glue-interface* - (run-swig (merge-pathnames "cplex.i" *cplex-glue-directory*) - :directory-search-list (list (merge-pathnames "Lib/guile" - *swig-source-directory*) - *cplex-glue-directory*) - :ignore-errors t)) - - - -(require 'uffi) - -;;(let ((*uffi-primitive-type-alist* (cons '("Pixel" . :unsigned-int) *uffi-default-primitive-type-alist*))) -;; (eval (cons 'progn (compute-uffi-definitions *simple-gifplot-interface*)))) - - -(with-open-file (f "/tmp/swig-uffi.lisp" :direction :output - :if-exists :supersede) - (let ((*uffi-definitions* '()) - (*uffi-output* f) - (*uffi-primitive-type-alist* - (cons '("Pixel" . :unsigned-int) *uffi-default-primitive-type-alist*))) - (apply 'handle-node *simple-gifplot-interface*))) - -#+cplex -(with-open-file (f "/tmp/swig-uffi.lisp" :direction :output) - (let ((*uffi-definitions* '()) - (*uffi-output* f) - (*uffi-primitive-type-alist* - (cons '("Pixel" . :unsigned-int) *uffi-default-primitive-type-alist*))) - (apply 'handle-node *cplex-glue-interface*))) - -(compile-file "/tmp/swig-uffi.lisp") - -(uffi:load-foreign-library (merge-pathnames "Examples/GIFPlot/libgifplot.a" - *swig-source-directory*)) - -(load "/tmp/swig-uffi.lisp") - -(load (merge-pathnames "Examples/GIFPlot/Common-Lisp/full/runme.lisp" *swig-source-directory*)) - -(action (namestring (merge-pathnames "Examples/GIFPlot/Common-Lisp/full/cmap" - *swig-source-directory*))) - -||# - ;;; Link to SWIG itself #|| diff --git a/Examples/test-suite/char_strings.i b/Examples/test-suite/char_strings.i index 2561108c6..cc59815b2 100644 --- a/Examples/test-suite/char_strings.i +++ b/Examples/test-suite/char_strings.i @@ -21,7 +21,7 @@ below. static char *global_str = NULL; const int UINT_DIGITS = 10; // max unsigned int is 4294967295 -bool check(const char *str, unsigned int number) { +bool check(const char *const str, unsigned int number) { static char expected[256]; sprintf(expected, "%s%d", OTHERLAND_MSG, number); bool matches = (strcmp(str, expected) == 0); @@ -105,10 +105,28 @@ bool SetConstCharArrayStaticString(const char str[], unsigned int number) { return check(static_str, number); } +bool SetCharConstStaticString(char *const str, unsigned int number) { + static char static_str[] = CPLUSPLUS_MSG; + strcpy(static_str, str); + return check(static_str, number); +} + +bool SetConstCharConstStaticString(const char *const str, unsigned int number) { + static char static_str[] = CPLUSPLUS_MSG; + strcpy(static_str, str); + return check(static_str, number); +} + // get set function char *CharPingPong(char *str) { return str; } +char *CharArrayPingPong(char abcstr[]) { + return abcstr; +} +char *CharArrayDimsPingPong(char abcstr[16]) { + return abcstr; +} // variables char *global_char = NULL; diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index c69c152df..f3414f931 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -29,14 +29,17 @@ # # Note that the RUNTOOL, COMPILETOOL and SWIGTOOL variables can be used # for invoking tools for the runtime tests and target language -# compiler (eg javac) respectively. For example, valgrind can be used -# for memory checking of the runtime tests using: +# compiler (eg javac), and on SWIG respectively. For example, valgrind +# can be used for memory checking of the runtime tests using: # make RUNTOOL="valgrind --leak-check=full" # and valgrind can be used when invoking SWIG using: # make SWIGTOOL="valgrind --tool=memcheck --trace-children=yes" # Note: trace-children needed because of preinst-swig shell wrapper # to the swig executable. # +# An individual test run can be debugged easily: +# make director_string.cpptest RUNTOOL="gdb --args" +# # The variables below can be overridden after including this makefile ####################################################################### @@ -66,7 +69,7 @@ INCLUDES = -I$(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE) LIBS = -L. LIBPREFIX = lib ACTION = check -INTERFACEDIR = ../ +INTERFACEDIR = $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/ # # Please keep test cases in alphabetical order. @@ -133,6 +136,7 @@ CPP_TEST_CASES += \ constructor_exception \ constructor_explicit \ constructor_ignore \ + constructor_rename \ constructor_value \ contract \ conversion \ @@ -178,6 +182,7 @@ CPP_TEST_CASES += \ disown \ dynamic_cast \ empty \ + enum_rename \ enum_scope_template \ enum_template \ enum_thorough \ @@ -194,9 +199,11 @@ CPP_TEST_CASES += \ extern_c \ extern_namespace \ extern_throws \ + expressions \ features \ fragments \ friends \ + funcptr_cpp \ fvirtual \ global_namespace \ global_ns_arg \ @@ -244,6 +251,8 @@ CPP_TEST_CASES += \ namespace_typemap \ namespace_union \ namespace_virtual_method \ + nspace \ + nspace_extend \ naturalvar \ nested_class \ nested_comment \ @@ -375,6 +384,7 @@ CPP_TEST_CASES += \ template_virtual \ template_whitespace \ threads \ + threads_exception \ throw_exception \ typedef_array_member \ typedef_class \ @@ -385,12 +395,14 @@ CPP_TEST_CASES += \ typedef_scope \ typedef_sizet \ typedef_struct \ + typemap_delete \ typemap_global_scope \ typemap_namespace \ typemap_ns_using \ typemap_numinputs \ typemap_template \ typemap_out_optimal \ + typemap_qualifier_strip \ typemap_variables \ typemap_various \ typename \ diff --git a/Examples/test-suite/constant_expr.i b/Examples/test-suite/constant_expr.i index 47db2d026..8e5c8aee6 100644 --- a/Examples/test-suite/constant_expr.i +++ b/Examples/test-suite/constant_expr.i @@ -5,7 +5,7 @@ /* % didn't work in SWIG 1.3.40 and earlier. */ const int X = 123%7; -#define FOO 12 % 6 -double d_array[12 % 6]; +#define FOO 12 % 9 +double d_array[12 % 9]; %} diff --git a/Examples/test-suite/constant_pointers.i b/Examples/test-suite/constant_pointers.i index c2344fb6a..7d46cdb31 100644 --- a/Examples/test-suite/constant_pointers.i +++ b/Examples/test-suite/constant_pointers.i @@ -5,6 +5,7 @@ This testcase primarily test constant pointers, eg int* const. Only a getter is %module constant_pointers %warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK); /* memory leak when setting a ptr/ref variable */ +%warnfilter(SWIGWARN_GO_NAME_CONFLICT); /* Ignoring 'Foo' due to Go name ('Foo') conflict with 'foo' */ %inline %{ @@ -70,6 +71,8 @@ public: void ret6(int*& a) {} int*& ret7() {return GlobalIntPtr;} + void ret8(int*const& a) {} + int*const& ret9() {return GlobalIntPtr;} ReturnValuesTest() : int3(NULL) {} private: ReturnValuesTest& operator=(const ReturnValuesTest&); @@ -112,7 +115,7 @@ int* const globalRet2() {return &GlobalInt;} return b; } - B const*& cbar(B const*& b) { + B *const& cbar(B *const& b) { return b; } } diff --git a/Examples/test-suite/constructor_rename.i b/Examples/test-suite/constructor_rename.i new file mode 100644 index 000000000..401b07d65 --- /dev/null +++ b/Examples/test-suite/constructor_rename.i @@ -0,0 +1,12 @@ +%module constructor_rename + +%{ +struct Foo { + Foo() {} +}; +%} + +struct Foo { + %rename(RenamedConstructor) Foo(); + Foo() {} +}; diff --git a/Examples/test-suite/cpp_enum.i b/Examples/test-suite/cpp_enum.i index e6eef6d0c..cb212615a 100644 --- a/Examples/test-suite/cpp_enum.i +++ b/Examples/test-suite/cpp_enum.i @@ -24,7 +24,6 @@ struct StructWithEnums { enum SOME_ENUM& enum_test8() { return some_enum; }; }; - struct Foo { enum {Hi, Hello } hola; @@ -41,3 +40,15 @@ extern "C" } %} + +// Using true and false in enums is legal in C++. Quoting the standard: +// [dcl.enum] +// ... The constant-expression shall be of integral or enumeration type. +// [basic.fundamental] +// ... Types bool, char, wchar_t, and the signed and unsigned integer +// types are collectively called integral types. +// So this shouldn't lead to a warning, at least in C++ mode. +%inline %{ +typedef enum { PLAY = true, STOP = false } play_state; +%} + diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in index 1545eb30d..5f50095a1 100644 --- a/Examples/test-suite/csharp/Makefile.in +++ b/Examples/test-suite/csharp/Makefile.in @@ -27,7 +27,6 @@ include $(srcdir)/../common.mk # Overridden variables here SWIGOPT += -namespace $*Namespace -INTERFACEDIR = ../../ CSHARPFLAGSSPECIAL = @@ -69,14 +68,13 @@ run_testcase = \ if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ $(MAKE) -f $*/$(top_builddir)/$(EXAMPLES)/Makefile \ CSHARPFLAGS='-nologo $(CSHARPFLAGSSPECIAL) -out:$*_runme.exe' \ - CSHARPSRCS='`$(CSHARPCYGPATH_W) $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX)` \ - $*$(CSHARPPATHSEPARATOR)*.cs' csharp_compile && \ + CSHARPSRCS='`$(CSHARPCYGPATH_W) $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX)` `find $* -name "*.cs" -exec $(CSHARPCYGPATH_W) "{}" \+`' csharp_compile && \ env LD_LIBRARY_PATH="$*:$$LD_LIBRARY_PATH" PATH="$*:$$PATH" SHLIB_PATH="$*:$$SHLIB_PATH" $(RUNTOOL) $(INTERPRETER) $*_runme.exe; \ else \ cd $* && \ $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \ CSHARPFLAGS='-nologo $(CSHARPFLAGSSPECIAL) -t:module -out:$*.netmodule' \ - CSHARPSRCS='*.cs' csharp_compile && cd .. ; \ + CSHARPSRCS='`find . -name "*.cs" -exec $(CSHARPCYGPATH_W) "{}" \+`' csharp_compile; \ fi # Clean: remove testcase directories diff --git a/Examples/test-suite/csharp/char_strings_runme.cs b/Examples/test-suite/csharp/char_strings_runme.cs index 59bcc64df..414d32b7a 100644 --- a/Examples/test-suite/csharp/char_strings_runme.cs +++ b/Examples/test-suite/csharp/char_strings_runme.cs @@ -76,6 +76,16 @@ public class char_strings_runme { throw new Exception("Test char set 6 failed, iteration " + i); } + for (i=0; i

      - Like gccgo -fgo-prefix option\n\ + -soname - Set shared library holding C/C++ code to \n\ + -longsize - Set size of C/C++ long type--32 or 64 bits\n\ +\n"; diff --git a/Source/Modules/guile.cxx b/Source/Modules/guile.cxx index 9e0f43daf..fc0418496 100644 --- a/Source/Modules/guile.cxx +++ b/Source/Modules/guile.cxx @@ -114,7 +114,7 @@ static String *memberfunction_name = 0; extern "C" { static int has_classname(Node *class_node) { - return Getattr(class_node, "guile:goopsclassname") != NULL; + return Getattr(class_node, "guile:goopsclassname") ? 1 : 0; } } @@ -254,7 +254,7 @@ public: } // set default value for primsuffix - if (primsuffix == NULL) + if (!primsuffix) primsuffix = NewString("primitive"); //goops support can only be enabled if passive or module linkage is used @@ -628,7 +628,7 @@ public: if (maybe_delimiter && Len(output) > 0 && Len(tm) > 0) { Printv(output, maybe_delimiter, NIL); } - const String *pn = (name == NULL) ? (const String *) Getattr(p, "name") : name; + 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)); @@ -657,7 +657,7 @@ public: Parm *p; String *proc_name = 0; char source[256]; - Wrapper *f = NewWrapper();; + Wrapper *f = NewWrapper(); String *cleanup = NewString(""); String *outarg = NewString(""); String *signature = NewString(""); @@ -781,7 +781,7 @@ public: 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) ? NULL : Getattr(class_node, "guile:goopsclassname"); + String *goopsclassname = !class_node ? NULL : Getattr(class_node, "guile:goopsclassname"); /* do input conversion */ if (goopsclassname) { Printv(method_signature, " (", argname, " ", goopsclassname, ")", NIL); diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 7a9d739f1..4a6abd569 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -56,7 +56,9 @@ class JAVA:public Language { String *proxy_class_def; String *proxy_class_code; String *module_class_code; - String *proxy_class_name; + 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; @@ -125,6 +127,8 @@ public: proxy_class_code(NULL), module_class_code(NULL), proxy_class_name(NULL), + full_proxy_class_name(NULL), + full_imclass_name(NULL), variable_name(NULL), proxy_class_constants_code(NULL), module_class_constants_code(NULL), @@ -157,19 +161,35 @@ public: /* ----------------------------------------------------------------------------- * getProxyName() * - * Test to see if a type corresponds to something wrapped with a proxy class - * Return NULL if not otherwise the proxy class name + * 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. * ----------------------------------------------------------------------------- */ String *getProxyName(SwigType *t) { - if (proxy_flag) { - Node *n = classLookup(t); - if (n) { - return Getattr(n, "sym:name"); - } - } - return NULL; - } + 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 = Getattr(n, "sym:name"); + if (nspace) { + if (package) + proxyname = NewStringf("%s.%s.%s", package, nspace, symname); + else + proxyname = NewStringf("%s.%s", nspace, symname); + } else { + proxyname = Copy(symname); + } + Setattr(n, "proxyname", proxyname); + Delete(proxyname); + } + } + } + return proxyname; + } /* ----------------------------------------------------------------------------- * makeValidJniName() @@ -214,6 +234,10 @@ public: 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++; @@ -370,8 +394,6 @@ public: dmethods_table = NewHash(); n_dmethods = 0; n_directors = 0; - if (!package) - package = NewString(""); jnipackage = NewString(""); package_path = NewString(""); @@ -400,7 +422,7 @@ public: String *wrapper_name = NewString(""); - if (Len(package)) { + if (package) { String *jniname = makeValidJniName(package); Printv(jnipackage, jniname, NIL); Delete(jniname); @@ -410,13 +432,13 @@ public: Replaceall(package_path, ".", "/"); } String *jniname = makeValidJniName(imclass_name); - Printf(wrapper_name, "Java_%s%s_%%f", Char(jnipackage), jniname); + 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_%v"); - Swig_name_register("get", "get_%v"); + Swig_name_register("set", "set_%n%v"); + Swig_name_register("get", "get_%n%v"); } Delete(wrapper_name); @@ -447,7 +469,7 @@ public: // Start writing out the intermediary class file emitBanner(f_im); - if (Len(package) > 0) + if (package) Printf(f_im, "package %s;\n", package); if (imclass_imports) @@ -498,7 +520,7 @@ public: // Start writing out the module class file emitBanner(f_module); - if (Len(package) > 0) + if (package) Printf(f_module, "package %s;\n", package); if (module_imports) @@ -550,7 +572,7 @@ public: // Start writing out the Java constants interface file emitBanner(f_module); - if (Len(package) > 0) + if (package) Printf(f_module, "package %s;\n", package); if (module_imports) @@ -763,7 +785,7 @@ public: Swig_restore(n); native_function_flag = false; } else { - Printf(stderr, "%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n, "wrap:name")); + Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name")); } return SWIG_OK; @@ -1002,7 +1024,7 @@ public: // below based on Swig_VargetToFunction() SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n)); - Setattr(n, "wrap:action", NewStringf("result = (%s) %s;", SwigType_lstr(ty, 0), Getattr(n, "value"))); + Setattr(n, "wrap:action", NewStringf("result = (%s)(%s);", SwigType_lstr(ty, 0), Getattr(n, "value"))); } // Now write code to make the function call @@ -1099,7 +1121,7 @@ public: */ if (proxy_flag && wrapping_member_flag && !enum_constant_flag) { // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name - bool getter_flag = Cmp(symname, Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) != 0; + bool getter_flag = Cmp(symname, Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) != 0; String *getter_setter_name = NewString(""); if (!getter_flag) @@ -1167,6 +1189,24 @@ public: 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 (package) { + full_imclass_name = NewStringf("%s.%s", package, imclass_name); + } else { + String *name = Getattr(n, "name") ? Getattr(n, "name") : NewString(""); + Swig_error(Getfile(n), Getline(n), "The nspace feature used on '%s' is not supported unless a package is specified with -package - Java does not support types declared in a named package accessing types declared in an unnamed package.\n", name); + SWIG_exit(EXIT_FAILURE); + } + } + } + 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; @@ -1176,6 +1216,17 @@ public: if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) { // Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum + String *scope = 0; + if (nspace || proxy_class_name) { + scope = NewString(""); + if (nspace) + Printf(scope, "%s", nspace); + if (proxy_class_name) + Printv(scope, nspace ? "." : "", proxy_class_name, NIL); + } + 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); @@ -1189,6 +1240,7 @@ public: Replaceall(enum_code, "$static ", "static "); else Replaceall(enum_code, "$static ", ""); + 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")) @@ -1224,7 +1276,8 @@ public: Printv(proxy_class_constants_code, " ", enum_code, "\n\n", NIL); } else { // Global enums are defined in their own file - String *filen = NewStringf("%s%s.java", SWIG_output_directory(), symname); + 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); @@ -1237,14 +1290,21 @@ public: // Start writing out the enum file emitBanner(f_enum); - if (Len(package) > 0) - Printf(f_enum, "package %s;\n", package); + 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"); Close(f_enum); + Delete(output_directory); } } else { // Wrap C++ enum with simple constant @@ -1257,6 +1317,11 @@ public: Delete(enum_code); enum_code = NULL; + + if (proxy_flag && !is_wrapping_class()) { + Delete(full_imclass_name); + full_imclass_name = 0; + } } return SWIG_OK; } @@ -1276,6 +1341,7 @@ public: Node *parent = parentNode(n); int unnamedinstance = GetFlag(parent, "unnamedinstance"); String *parent_name = Getattr(parent, "name"); + String *nspace = getNSpace(); String *tmpValue; // Strange hack from parent method @@ -1286,9 +1352,38 @@ public: // Note that this is used in enumValue() amongst other places Setattr(n, "value", tmpValue); + // Deal with enum values that are bools + if (SwigType_type(Getattr(n, "type")) == T_BOOL) { + String *boolValue = NewStringf("%s ? 1 : 0", Getattr(n, "enumvalue")); + Setattr(n, "enumvalue", boolValue); + Delete(boolValue); + } + { EnumFeature enum_feature = decodeEnumFeature(parent); + // Add to language symbol table + String *scope = 0; + if (unnamedinstance || !parent_name || enum_feature == SimpleEnum) { + if (proxy_class_name) { + scope = NewString(""); + if (nspace) + Printf(scope, "%s.", nspace); + Printf(scope, "%s", proxy_class_name); + } else { + scope = Copy(constants_interface_name); + } + } else { + scope = NewString(""); + if (nspace) + Printf(scope, "%s.", nspace); + if (proxy_class_name) + Printf(scope, "%s.", proxy_class_name); + Printf(scope, "%s",Getattr(parent, "sym:name")); + } + if (!addSymbol(name, n, scope)) + return SWIG_ERROR; + if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) { // Wrap (non-anonymous) C/C++ enum with a proper Java enum // Emit the enum item. @@ -1335,6 +1430,7 @@ public: Setattr(parent, "enumvalues", Copy(symname)); else Printv(enumvalues, ", ", symname, NIL); + Delete(scope); } Delete(tmpValue); @@ -1364,9 +1460,21 @@ public: bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0); const String *itemname = (proxy_flag && wrapping_member_flag) ? variable_name : symname; - String *scope = proxy_flag && wrapping_member_flag ? proxy_class_name : constants_interface_name; - if (!addSymbol(itemname, n, scope)) - return SWIG_ERROR; + 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"); @@ -1418,13 +1526,14 @@ public: 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, imclass_name, Swig_name_get(symname)); + Printf(constants_code, "%s.swigToEnum(%s.%s());\n", return_type, full_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, imclass_name, Swig_name_get(symname)); + 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", imclass_name, Swig_name_get(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"); @@ -1528,37 +1637,37 @@ public: Delete(module_interfaces); module_interfaces = Copy(strvalue); } else if (Strcmp(code, "moduleimport") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use the moduleimports pragma.\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use the moduleimports pragma.\n"); } else if (Strcmp(code, "moduleinterface") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use the moduleinterfaces pragma.\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use the moduleinterfaces pragma.\n"); } else if (Strcmp(code, "modulemethodmodifiers") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use %%javamethodmodifiers.\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use %%javamethodmodifiers.\n"); } else if (Strcmp(code, "allshadowimport") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use %%typemap(javaimports).\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaimports).\n"); } else if (Strcmp(code, "allshadowcode") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use %%typemap(javacode).\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javacode).\n"); } else if (Strcmp(code, "allshadowbase") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use %%typemap(javabase).\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javabase).\n"); } else if (Strcmp(code, "allshadowinterface") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use %%typemap(javainterfaces).\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javainterfaces).\n"); } else if (Strcmp(code, "allshadowclassmodifiers") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n"); } else if (proxy_flag) { if (Strcmp(code, "shadowcode") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use %%typemap(javacode).\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javacode).\n"); } else if (Strcmp(code, "shadowimport") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use %%typemap(javaimports).\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaimports).\n"); } else if (Strcmp(code, "shadowbase") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use %%typemap(javabase).\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javabase).\n"); } else if (Strcmp(code, "shadowinterface") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use %%typemap(javainterfaces).\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javainterfaces).\n"); } else if (Strcmp(code, "shadowclassmodifiers") == 0) { - Printf(stderr, "%s : Line %d. Ignored: Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n", input_file, line_number); + Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n"); } else { - Printf(stderr, "%s : Line %d. Unrecognized pragma.\n", input_file, line_number); + Swig_error(input_file, line_number, "Unrecognized pragma.\n"); } } else { - Printf(stderr, "%s : Line %d. Unrecognized pragma.\n", input_file, line_number); + Swig_error(input_file, line_number, "Unrecognized pragma.\n"); } Delete(strvalue); } @@ -1691,16 +1800,18 @@ public: /* Also insert the swigTakeOwnership and swigReleaseOwnership methods */ if (feature_director) { String *destruct_jnicall, *release_jnicall, *take_jnicall; + String *changeown_method_name = Swig_name_member(getNSpace(), proxy_class_name, "change_ownership"); destruct_jnicall = NewStringf("%s()", destruct_methodname); - release_jnicall = NewStringf("%s.%s_change_ownership(this, swigCPtr, false)", imclass_name, proxy_class_name); - take_jnicall = NewStringf("%s.%s_change_ownership(this, swigCPtr, true)", imclass_name, proxy_class_name); + 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); } @@ -1712,38 +1823,56 @@ public: Printv(proxy_class_def, typemapLookup(n, "javacode", typemap_lookup_type, WARN_NONE), // extra Java code "\n", NIL); - // Substitute various strings into the above template - Replaceall(proxy_class_code, "$javaclassname", proxy_class_name); - Replaceall(proxy_class_def, "$javaclassname", proxy_class_name); - - Replaceall(proxy_class_def, "$module", module_class_name); - Replaceall(proxy_class_code, "$module", module_class_name); - - Replaceall(proxy_class_def, "$imclassname", imclass_name); - Replaceall(proxy_class_code, "$imclassname", imclass_name); - // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy) if (derived) { - Printv(imclass_cppcasts_code, " public final static native long SWIG$javaclassnameUpcast(long jarg1);\n", NIL); - - Replaceall(imclass_cppcasts_code, "$javaclassname", proxy_class_name); - - Printv(upcasts_code, - "SWIGEXPORT jlong JNICALL Java_$jnipackage$imimclass_SWIG$imclazznameUpcast", - "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", - " jlong baseptr = 0;\n" - " (void)jenv;\n" " (void)jcls;\n" " *($cbaseclass **)&baseptr = *($cclass **)&jarg1;\n" " return baseptr;\n" "}\n", "\n", NIL); - - String *imimclass = makeValidJniName(imclass_name); - String *imclazzname = makeValidJniName(proxy_class_name); - Replaceall(upcasts_code, "$cbaseclass", c_baseclass); - Replaceall(upcasts_code, "$imclazzname", imclazzname); - Replaceall(upcasts_code, "$cclass", c_classname); - Replaceall(upcasts_code, "$jnipackage", jnipackage); - Replaceall(upcasts_code, "$imimclass", imimclass); - - Delete(imclazzname); - Delete(imimclass); + String *smartptr = Getattr(n, "feature:smartptr"); + String *upcast_method = Swig_name_member(getNSpace(), proxy_class_name, smartptr != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast"); + String *jniname = makeValidJniName(upcast_method); + String *wname = Swig_name_wrapper(jniname); + Printf(imclass_cppcasts_code, " public final static native long %s(long jarg1);\n", upcast_method); + if (smartptr) { + SwigType *spt = Swig_cparse_type(smartptr); + if (spt) { + SwigType *smart = SwigType_typedef_resolve_all(spt); + Delete(spt); + SwigType *bsmart = Copy(smart); + SwigType *rclassname = SwigType_typedef_resolve_all(c_classname); + SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass); + Replaceall(bsmart, rclassname, rbaseclass); + Delete(rclassname); + Delete(rbaseclass); + String *smartnamestr = SwigType_namestr(smart); + String *bsmartnamestr = SwigType_namestr(bsmart); + Printv(upcasts_code, + "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n", + " jlong baseptr = 0;\n" + " ", smartnamestr, " *argp1;\n" + " ", bsmartnamestr, " result;\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(bsmartnamestr); + Delete(smartnamestr); + Delete(bsmart); + } else { + Swig_error(Getfile(n), Getline(n), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, c_classname); + } + } 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" + " *(", c_baseclass, " **)&baseptr = *(", c_classname, " **)&jarg1;\n" + " return baseptr;\n" + "}\n", "\n", NIL); + } + Delete(wname); + Delete(jniname); + Delete(upcast_method); } Delete(baseclass); } @@ -1757,21 +1886,36 @@ public: File *f_proxy = NULL; if (proxy_flag) { proxy_class_name = NewString(Getattr(n, "sym:name")); + String *nspace = getNSpace(); - if (!addSymbol(proxy_class_name, n)) + if (!nspace) { + full_proxy_class_name = NewStringf("%s", proxy_class_name); + full_imclass_name = NewStringf("%s", imclass_name); + if (Cmp(proxy_class_name, imclass_name) == 0) { + Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name); + SWIG_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); + SWIG_exit(EXIT_FAILURE); + } + } else { + if (package) { + full_proxy_class_name = NewStringf("%s.%s.%s", package, nspace, proxy_class_name); + full_imclass_name = NewStringf("%s.%s", package, imclass_name); + } else { + String *name = Getattr(n, "name") ? Getattr(n, "name") : NewString(""); + Swig_error(Getfile(n), Getline(n), "The nspace feature used on '%s' is not supported unless a package is specified with -package - Java does not support types declared in a named package accessing types declared in an unnamed package.\n", name); + SWIG_exit(EXIT_FAILURE); + } + } + + if (!addSymbol(proxy_class_name, n, nspace)) return SWIG_ERROR; - if (Cmp(proxy_class_name, imclass_name) == 0) { - Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name); - SWIG_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); - SWIG_exit(EXIT_FAILURE); - } - - String *filen = NewStringf("%s%s.java", SWIG_output_directory(), proxy_class_name); + 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); @@ -1784,8 +1928,14 @@ public: // Start writing out the proxy class file emitBanner(f_proxy); - if (Len(package) > 0) - Printf(f_proxy, "package %s;\n", package); + 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"); + } Clear(proxy_class_def); Clear(proxy_class_code); @@ -1793,6 +1943,7 @@ public: destructor_call = NewString(""); destructor_throws_clause = NewString(""); proxy_class_constants_code = NewString(""); + Delete(output_directory); } Language::classHandler(n); @@ -1801,12 +1952,24 @@ public: emitProxyClassDefAndCPPCasts(n); + String *javaclazzname = Swig_name_member(getNSpace(), proxy_class_name, ""); // 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(proxy_class_def, "$javaclazzname", javaclazzname); + Replaceall(proxy_class_code, "$javaclazzname", javaclazzname); + Replaceall(proxy_class_constants_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(proxy_class_def, "$imclassname", imclass_name); - Replaceall(proxy_class_code, "$imclassname", imclass_name); - Replaceall(proxy_class_constants_code, "$imclassname", imclass_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); + Printv(f_proxy, proxy_class_def, proxy_class_code, NIL); // Write out all the constants @@ -1822,16 +1985,17 @@ public: downcasts, making the constructorHandler() a bad place (because ABCs don't get to have constructors emitted.) */ if (GetFlag(n, "feature:javadowncast")) { - String *jni_imclass_name = makeValidJniName(imclass_name); - String *jni_class_name = makeValidJniName(proxy_class_name); + String *downcast_method = Swig_name_member(getNSpace(), proxy_class_name, "SWIGDowncast"); + String *jniname = makeValidJniName(downcast_method); + String *wname = Swig_name_wrapper(jniname); + String *norm_name = SwigType_namestr(Getattr(n, "name")); - Printf(imclass_class_code, " public final static native %s downcast%s(long cPtrBase, boolean cMemoryOwn);\n", proxy_class_name, proxy_class_name); + Printf(imclass_class_code, " public final static native %s %s(long cPtrBase, boolean cMemoryOwn);\n", proxy_class_name, downcast_method); Wrapper *dcast_wrap = NewWrapper(); - Printf(dcast_wrap->def, "SWIGEXPORT jobject JNICALL Java_%s%s_downcast%s(JNIEnv *jenv, jclass jcls, jlong jCPtrBase, jboolean cMemoryOwn) {", - jnipackage, jni_imclass_name, jni_class_name); + Printf(dcast_wrap->def, "SWIGEXPORT jobject JNICALL %s(JNIEnv *jenv, jclass jcls, jlong jCPtrBase, jboolean cMemoryOwn) {", wname); Printf(dcast_wrap->code, " Swig::Director *director = (Swig::Director *) 0;\n"); Printf(dcast_wrap->code, " jobject jresult = (jobject) 0;\n"); Printf(dcast_wrap->code, " %s *obj = *((%s **)&jCPtrBase);\n", norm_name, norm_name); @@ -1842,12 +2006,22 @@ public: Wrapper_print(dcast_wrap, f_wrappers); DelWrapper(dcast_wrap); + + Delete(norm_name); + Delete(wname); + Delete(jniname); + Delete(downcast_method); } emitDirectorExtraMethods(n); + Delete(javaclazzname); Delete(proxy_class_name); proxy_class_name = NULL; + Delete(full_proxy_class_name); + full_proxy_class_name = NULL; + Delete(full_imclass_name); + full_imclass_name = NULL; Delete(destructor_call); destructor_call = NULL; Delete(destructor_throws_clause); @@ -1869,7 +2043,7 @@ public: if (proxy_flag) { String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name); + 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); proxyClassFunctionHandler(n); @@ -1891,7 +2065,7 @@ public: if (proxy_flag) { String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name); + 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); proxyClassFunctionHandler(n); @@ -1967,7 +2141,7 @@ public: if (wrapping_member_flag && !enum_constant_flag) { // For wrapping member variables (Javabean setter) - setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) == 0); + setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), Swig_name_member(0, proxy_class_name, variable_name))) == 0); } /* Start generating the proxy function */ @@ -1978,7 +2152,7 @@ public: Printf(function_code, "static "); Printf(function_code, "%s %s(", return_type, proxy_function_name); - Printv(imcall, imclass_name, ".$imfuncname(", NIL); + Printv(imcall, full_imclass_name, ".$imfuncname(", NIL); if (!static_flag) { Printf(imcall, "swigCPtr"); @@ -2121,7 +2295,7 @@ public: Node *explicit_n = Getattr(n, "explicitcallnode"); if (explicit_n) { String *ex_overloaded_name = getOverloadedName(explicit_n); - String *ex_intermediary_function_name = Swig_name_member(proxy_class_name, ex_overloaded_name); + 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); @@ -2183,7 +2357,7 @@ public: if (proxy_flag) { String *overloaded_name = getOverloadedName(n); - String *mangled_overname = Swig_name_construct(overloaded_name); + String *mangled_overname = Swig_name_construct(getNSpace(), overloaded_name); String *imcall = NewString(""); const String *methodmods = Getattr(n, "feature:java:methodmodifiers"); @@ -2195,7 +2369,7 @@ public: 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, imclass_name, ".", mangled_overname, "(", NIL); + Printv(imcall, full_imclass_name, ".", mangled_overname, "(", NIL); /* Attach the non-standard typemaps to the parameter list */ Swig_typemap_attach_parms("in", l, NULL); @@ -2368,7 +2542,7 @@ public: String *symname = Getattr(n, "sym:name"); if (proxy_flag) { - Printv(destructor_call, imclass_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL); + Printv(destructor_call, full_imclass_name, ".", Swig_name_destroy(getNSpace(), symname), "(swigCPtr)", NIL); generateThrowsClause(n, destructor_throws_clause); } return SWIG_OK; @@ -2476,7 +2650,7 @@ public: 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(variable_name)) == 0); + setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(getNSpace(), variable_name)) == 0); if (setter_flag) Printf(func_name, "set"); else @@ -2681,10 +2855,10 @@ public: // 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()", imclass_name, Swig_name_get(symname)); + value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), symname)); } else { memberconstantHandler(n); - value = NewStringf("%s.%s()", imclass_name, Swig_name_get(Swig_name_member(proxy_class_name, symname))); + value = NewStringf("%s.%s()", full_imclass_name ? full_imclass_name : imclass_name, Swig_name_get(getNSpace(), Swig_name_member(0, proxy_class_name, symname))); } } } @@ -2698,28 +2872,44 @@ public: * ----------------------------------------------------------------------------- */ String *getEnumName(SwigType *t, bool jnidescriptor) { - Node *enum_name = NULL; + Node *enumname = NULL; Node *n = enumLookup(t); if (n) { - 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); + 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); + } + 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) + enumname = NewStringf("%s.%s.%s", package, nspace, symname); + else + enumname = NewStringf("%s.%s", nspace, symname); + } else { + enumname = Copy(symname); + } + } + if (!jnidescriptor) { // not cached + Setattr(n, "enumname", enumname); + Delete(enumname); + } + Delete(scopename_prefix); } - if (proxyname) { - const char *class_separator = jnidescriptor ? "$" : "."; - enum_name = NewStringf("%s%s%s", proxyname, class_separator, symname); - } else { - enum_name = NewStringf("%s", symname); - } - Delete(scopename_prefix); } } - return enum_name; + return enumname; } /* ----------------------------------------------------------------------------- @@ -2753,8 +2943,10 @@ public: if (Strstr(tm, "$*javaclassname")) { SwigType *classnametype = Copy(strippedtype); Delete(SwigType_pop(classnametype)); - substituteClassnameSpecialVariable(classnametype, tm, "$*javaclassname", jnidescriptor); - substitution_performed = true; + if (Len(classnametype) > 0) { + substituteClassnameSpecialVariable(classnametype, tm, "$*javaclassname", jnidescriptor); + substitution_performed = true; + } Delete(classnametype); } if (Strstr(tm, "$&javaclassname")) { @@ -2858,7 +3050,7 @@ public: // Start writing out the type wrapper class file emitBanner(f_swigtype); - if (Len(package) > 0) + if (package) Printf(f_swigtype, "package %s;\n", package); // Pure Java baseclass and interfaces @@ -3004,10 +3196,10 @@ public: if (Cmp(jtype, "long") == 0) { if (proxy_flag) { if (!GetFlag(p, "tmap:jtype:nopgcpp") && !nopgcpp_flag) { - Node *n = classLookup(t); - if (n) { + String *proxyname = getProxyName(t); + if (proxyname) { // Found a struct/class parameter passed by value, reference, pointer, or pointer reference - proxyClassName = Getattr(n, "sym:name"); + proxyClassName = proxyname; } else { // 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")); @@ -3045,6 +3237,30 @@ public: return proxyClassName; } + /* ----------------------------------------------------------------------------- + * 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); + SWIG_exit(EXIT_FAILURE); + } + Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0); + Delete(nspace_subdirectory); + } + return output_directory; + } + /*---------------------------------------------------------------------- * Start of director methods *--------------------------------------------------------------------*/ @@ -3145,8 +3361,7 @@ public: /*---------------------------------------------------------------------- * emitDirectorExtraMethods() * - * This is where the $javaclassname_director_connect is - * generated. + * This is where the director connect method is generated. *--------------------------------------------------------------------*/ void emitDirectorExtraMethods(Node *n) { if (!Swig_directorclass(n)) @@ -3155,13 +3370,13 @@ public: // Output the director connect method: String *jni_imclass_name = makeValidJniName(imclass_name); String *norm_name = SwigType_namestr(Getattr(n, "name")); - String *swig_director_connect = NewStringf("%s_director_connect", proxy_class_name); + String *swig_director_connect = Swig_name_member(getNSpace(), proxy_class_name, "director_connect"); String *swig_director_connect_jni = makeValidJniName(swig_director_connect); String *sym_name = Getattr(n, "sym:name"); 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, proxy_class_name); + swig_director_connect, full_proxy_class_name); code_wrap = NewWrapper(); Printf(code_wrap->def, @@ -3183,10 +3398,10 @@ public: Delete(swig_director_connect); // Output the swigReleaseOwnership, swigTakeOwnership methods: - String *changeown_method_name = NewStringf("%s_change_ownership", proxy_class_name); + String *changeown_method_name = Swig_name_member(getNSpace(), proxy_class_name, "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, proxy_class_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, @@ -3342,7 +3557,7 @@ public: // we're consistent with the sym:overload name in functionWrapper. (?? when // does the overloaded method name get set?) - imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(classname, overloaded_name)); + imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), classname, overloaded_name)); if (returntype) { @@ -3885,7 +4100,7 @@ public: int classDirectorConstructor(Node *n) { Node *parent = parentNode(n); - String *decl = Getattr(n, "decl");; + String *decl = Getattr(n, "decl"); String *supername = Swig_class_name(parent); String *classname = directorClassName(parent); String *sub = NewString(""); diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index a22c06dd0..e28fcbb89 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -60,6 +60,7 @@ extern "C" { static int InClass = 0; /* Parsing C++ or not */ static String *ClassName = 0; /* This is the real name of the current class */ static String *ClassPrefix = 0; /* Class prefix */ +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; @@ -1198,7 +1199,7 @@ int Language::memberfunctionHandler(Node *n) { Setline(cbn, Getline(n)); memberconstantHandler(cbn); - Setattr(n, "feature:callback:name", Swig_name_member(ClassPrefix, cbname)); + Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname)); Delete(cb); Delete(cbn); @@ -1211,7 +1212,7 @@ int Language::memberfunctionHandler(Node *n) { } } - String *fname = Swig_name_member(ClassPrefix, symname); + String *fname = Swig_name_member(NSpace, ClassPrefix, symname); if (Extend && SmartPointer) { if (!Getattr(n, "classname")) { Setattr(n, "classname", Getattr(CurrentClass, "allocate:smartpointerbase")); @@ -1236,7 +1237,7 @@ int Language::memberfunctionHandler(Node *n) { if (GetFlag(n, "explicitcall")) DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL; - Swig_MethodToFunction(n, ClassType, Getattr(n, "template") ? SmartPointer : Extend | SmartPointer | DirectorExtraCall, director_type, + Swig_MethodToFunction(n, NSpace, ClassType, Getattr(n, "template") ? SmartPointer : Extend | SmartPointer | DirectorExtraCall, director_type, is_member_director(CurrentClass, n)); Setattr(n, "sym:name", fname); @@ -1272,10 +1273,10 @@ int Language::staticmemberfunctionHandler(Node *n) { cname = NewStringf("%s::%s", sname, name); } else { String *mname = Swig_name_mangle(ClassName); - cname = Swig_name_member(mname, name); + cname = Swig_name_member(NSpace, mname, name); Delete(mname); } - mrename = Swig_name_member(ClassPrefix, symname); + mrename = Swig_name_member(NSpace, ClassPrefix, symname); if (Extend) { String *code = Getattr(n, "code"); @@ -1299,7 +1300,7 @@ int Language::staticmemberfunctionHandler(Node *n) { if (cb) { String *cbname = NewStringf(cb, symname); - Setattr(n, "feature:callback:name", Swig_name_member(ClassPrefix, cbname)); + Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname)); Setattr(n, "feature:callback:staticname", name); } Delattr(n, "storage"); @@ -1380,9 +1381,9 @@ int Language::membervariableHandler(Node *n) { SwigType *type = Getattr(n, "type"); if (!AttributeFunctionGet) { - String *mname = Swig_name_member(ClassPrefix, symname); - String *mrename_get = Swig_name_get(mname); - String *mrename_set = Swig_name_set(mname); + 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 */ @@ -1493,7 +1494,7 @@ int Language::membervariableHandler(Node *n) { cpp_member_func(Char(gname), Char(gname), type, 0); Delete(ActionFunc); } else { - String *cname = Swig_name_get(name); + String *cname = Swig_name_get(NSpace, name); cpp_member_func(Char(cname), Char(gname), type, 0); Delete(cname); } @@ -1506,7 +1507,7 @@ int Language::membervariableHandler(Node *n) { cpp_member_func(Char(gname), Char(gname), vty, p); Delete(ActionFunc); } else { - String *cname = Swig_name_set(name); + String *cname = Swig_name_set(NSpace, name); cpp_member_func(Char(cname), Char(gname), vty, p); Delete(cname); } @@ -1534,7 +1535,7 @@ int Language::staticmembervariableHandler(Node *n) { String *cname, *mrename; /* Create the variable name */ - mrename = Swig_name_member(ClassPrefix, symname); + mrename = Swig_name_member(0, ClassPrefix, symname); cname = NewStringf("%s::%s", classname, name); Setattr(n, "sym:name", mrename); @@ -1611,9 +1612,15 @@ int Language::externDeclaration(Node *n) { * ---------------------------------------------------------------------- */ int Language::enumDeclaration(Node *n) { + String *oldNSpace = NSpace; + NSpace = Getattr(n, "sym:nspace"); + if (!ImportMode) { emit_children(n); } + + NSpace = oldNSpace; + return SWIG_OK; } @@ -1676,7 +1683,7 @@ int Language::memberconstantHandler(Node *n) { String *symname = Getattr(n, "sym:name"); String *value = Getattr(n, "value"); - String *mrename = Swig_name_member(ClassPrefix, symname); + String *mrename = Swig_name_member(0, ClassPrefix, symname); Setattr(n, "sym:name", mrename); String *new_name = 0; @@ -1908,7 +1915,7 @@ int Language::classDirectorDisown(Node *n) { Node *disown = NewHash(); String *mrename; String *symname = Getattr(n, "sym:name"); - mrename = Swig_name_disown(symname); //Getattr(n, "name")); + mrename = Swig_name_disown(NSpace, symname); String *type = NewString(ClassType); String *name = NewString("self"); SwigType_add_pointer(type); @@ -1917,7 +1924,7 @@ int Language::classDirectorDisown(Node *n) { Delete(type); type = NewString("void"); String *action = NewString(""); - Printv(action, "{\n", "Swig::Director *director = dynamic_cast(arg1);\n", "if (director) director->swig_disown();\n", "}\n", NULL); + 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); @@ -2354,6 +2361,8 @@ int Language::classDeclaration(Node *n) { InClass = 1; CurrentClass = n; + String *oldNSpace = NSpace; + NSpace = Getattr(n, "sym:nspace"); /* Call classHandler() here */ if (!ImportMode) { @@ -2403,6 +2412,7 @@ int Language::classDeclaration(Node *n) { Language::classHandler(n); } + NSpace = oldNSpace; InClass = 0; CurrentClass = 0; Delete(ClassType); @@ -2635,7 +2645,7 @@ static String *get_director_ctor_code(Node *n, String *director_ctor_code, Strin 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(symname); + String *mrename = Swig_name_construct(NSpace, symname); String *nodeType = Getattr(n, "nodeType"); int constructor = (!Cmp(nodeType, "constructor")); List *abstract = 0; @@ -2647,7 +2657,7 @@ int Language::constructorHandler(Node *n) { Setattr(n, "handled_as_constructor", "1"); } - Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend); + Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend); Setattr(n, "sym:name", mrename); functionWrapper(n); Delete(mrename); @@ -2664,12 +2674,12 @@ int Language::constructorHandler(Node *n) { 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(symname); + String *mrename = Swig_name_copyconstructor(NSpace, symname); List *abstract = 0; String *director_ctor = get_director_ctor_code(n, director_ctor_code, director_prot_ctor_code, abstract); - Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend); + Swig_ConstructorToFunction(n, NSpace, ClassType, none_comparison, director_ctor, CPlusPlus, Getattr(n, "template") ? 0 : Extend); Setattr(n, "sym:name", mrename); functionWrapper(n); Delete(mrename); @@ -2687,7 +2697,7 @@ int Language::destructorDeclaration(Node *n) { if (!CurrentClass) return SWIG_NOWRAP; - if (cplus_mode != PUBLIC) + if (cplus_mode != PUBLIC && !Getattr(CurrentClass, "feature:unref")) return SWIG_NOWRAP; if (ImportMode) return SWIG_NOWRAP; @@ -2739,9 +2749,9 @@ int Language::destructorHandler(Node *n) { if (csymname && (*csymname == '~')) csymname += 1; - mrename = Swig_name_destroy(csymname); + mrename = Swig_name_destroy(NSpace, csymname); - Swig_DestructorToFunction(n, ClassType, CPlusPlus, Extend); + Swig_DestructorToFunction(n, NSpace, ClassType, CPlusPlus, Extend); Setattr(n, "sym:name", mrename); functionWrapper(n); Delete(mrename); @@ -2844,7 +2854,7 @@ int Language::variableWrapper(Node *n) { String *tm = Swig_typemap_lookup("globalin", n, name, 0); Swig_VarsetToFunction(n, flags); - String *sname = Swig_name_set(symname); + String *sname = Swig_name_set(NSpace, symname); Setattr(n, "sym:name", sname); Delete(sname); @@ -2879,7 +2889,7 @@ int Language::variableWrapper(Node *n) { } Swig_VargetToFunction(n, flags); - String *gname = Swig_name_get(symname); + String *gname = Swig_name_get(NSpace, symname); Setattr(n, "sym:name", gname); Delete(gname); functionWrapper(n); @@ -2922,11 +2932,11 @@ void Language::main(int argc, char *argv[]) { * 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 - * resolved scope and the symbol s must not contain any scope qualifiers. + * 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) { - Hash *symbols = Getattr(symtabs, scope); + Hash *symbols = Getattr(symtabs, scope ? scope : ""); if (!symbols) { // New scope which has not been added by the target language - lazily created. symbols = NewHash(); @@ -2940,7 +2950,10 @@ int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr } else { Node *c = Getattr(symbols, s); if (c && (c != n)) { - Swig_error(input_file, line_number, "'%s' is multiply defined in the generated target language module.\n", s); + if (scope) + 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; } @@ -2982,7 +2995,10 @@ void Language::dumpSymbols() { * ----------------------------------------------------------------------------- */ Node *Language::symbolLookup(String *s, const_String_or_char_ptr scope) { - Hash *symbols = Getattr(symtabs, scope); + Hash *symbols = Getattr(symtabs, scope ? scope : ""); + if (!symbols) { + return NULL; + } return Getattr(symbols, s); } @@ -3001,8 +3017,6 @@ Node *Language::classLookup(SwigType *s) { Symtab *stab = 0; SwigType *ty1 = SwigType_typedef_resolve_all(s); SwigType *ty2 = SwigType_strip_qualifiers(ty1); - Delete(ty1); - ty1 = 0; String *base = SwigType_base(ty2); @@ -3039,11 +3053,18 @@ Node *Language::classLookup(SwigType *s) { if (n) { /* Found a match. Look at the prefix. We only allow the cases where where we want a proxy class for the particular type */ - if ((Len(prefix) == 0) || // simple type (pass by value) - (Strcmp(prefix, "p.") == 0) || // pointer - (Strcmp(prefix, "r.") == 0) || // reference - (Strcmp(prefix, "r.p.") == 0) || // pointer by reference - SwigType_prefix_is_simple_1D_array(prefix)) { // Simple 1D array (not arrays of pointers/references) + bool acceptable_prefix = + (Len(prefix) == 0) || // simple type (pass by value) + (Strcmp(prefix, "p.") == 0) || // pointer + (Strcmp(prefix, "r.") == 0) || // 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); Setattr(classtypes, cs, n); Delete(cs); @@ -3051,9 +3072,10 @@ Node *Language::classLookup(SwigType *s) { n = 0; } } - Delete(ty2); - Delete(base); Delete(prefix); + Delete(base); + Delete(ty2); + Delete(ty1); } if (n && (GetFlag(n, "feature:ignore") || Getattr(n, "feature:onlychildren"))) { n = 0; @@ -3079,10 +3101,6 @@ Node *Language::enumLookup(SwigType *s) { SwigType *lt = SwigType_ltype(s); SwigType *ty1 = SwigType_typedef_resolve_all(lt); SwigType *ty2 = SwigType_strip_qualifiers(ty1); - Delete(lt); - Delete(ty1); - lt = 0; - ty1 = 0; String *base = SwigType_base(ty2); @@ -3121,9 +3139,11 @@ Node *Language::enumLookup(SwigType *s) { n = 0; } } - Delete(ty2); - Delete(base); Delete(prefix); + Delete(base); + Delete(ty2); + Delete(ty1); + Delete(lt); } if (n && (GetFlag(n, "feature:ignore"))) { n = 0; @@ -3306,7 +3326,7 @@ bool Language::extraDirectorProtectedCPPMethodsRequired() const { * Language::is_wrapping_class() * ----------------------------------------------------------------------------- */ -int Language::is_wrapping_class() { +int Language::is_wrapping_class() const { return InClass; } @@ -3318,6 +3338,14 @@ Node *Language::getCurrentClass() const { return CurrentClass; } +/* ----------------------------------------------------------------------------- + * Language::getNSpace() + * ----------------------------------------------------------------------------- */ + +String *Language::getNSpace() const { + return NSpace; +} + /* ----------------------------------------------------------------------------- * Language::getClassName() * ----------------------------------------------------------------------------- */ diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx index 4640d9ed7..d240d3d6f 100644 --- a/Source/Modules/lua.cxx +++ b/Source/Modules/lua.cxx @@ -758,7 +758,7 @@ public: current=NO_CPP; // normally SWIG will generate 2 wrappers, a get and a set // but in certain scenarios (immutable, or if its arrays), it will not - String *getName = Swig_name_wrapper(Swig_name_get(iname)); + String *getName = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, iname)); String *setName = 0; // checking whether it can be set to or not appears to be a very error prone issue // I refered to the Language::variableWrapper() to find this out @@ -770,7 +770,7 @@ public: Delete(tm); if (assignable) { - setName = Swig_name_wrapper(Swig_name_set(iname)); + setName = Swig_name_wrapper(Swig_name_set(NSPACE_TODO, iname)); } else { // how about calling a 'this is not settable' error message? setName = NewString("SWIG_Lua_set_immutable"); // error message @@ -790,7 +790,6 @@ public: // REPORT("constantWrapper", n); String *name = Getattr(n, "name"); String *iname = Getattr(n, "sym:name"); - //String *nsname = !nspace ? Copy(iname) : NewStringf("%s::%s",ns_name,iname); String *nsname = Copy(iname); SwigType *type = Getattr(n, "type"); String *rawval = Getattr(n, "rawval"); @@ -799,7 +798,6 @@ public: if (!addSymbol(iname, n)) return SWIG_ERROR; - //if (nspace) Setattr(n,"sym:name",nsname); /* Special hook for member pointer */ if (SwigType_type(type) == T_MPOINTER) { @@ -997,7 +995,7 @@ public: Printv(f_wrappers, "static swig_lua_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(constructor_name))); + Printf(f_wrappers, "%s", Swig_name_wrapper(Swig_name_construct(NSPACE_TODO, constructor_name))); Delete(constructor_name); constructor_name = 0; } else { @@ -1043,7 +1041,7 @@ public: current = NO_CPP; realname = iname ? iname : name; - rname = Swig_name_wrapper(Swig_name_member(class_name, realname)); + rname = Swig_name_wrapper(Swig_name_member(NSPACE_TODO, class_name, realname)); if (!Getattr(n, "sym:nextSibling")) { Printv(s_methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL); } @@ -1063,9 +1061,9 @@ public: current = MEMBER_VAR; Language::membervariableHandler(n); current = NO_CPP; - gname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name, symname))); + gname = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname))); if (!GetFlag(n, "feature:immutable")) { - sname = Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name, symname))); + sname = Swig_name_wrapper(Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname))); } else { //sname = NewString("0"); sname = NewString("SWIG_Lua_set_immutable"); // error message diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index 86f279a67..f0e941f22 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -197,11 +197,11 @@ enum { STAGE1=1, STAGE2=2, STAGE3=4, STAGE4=8, STAGEOVERFLOW=16 }; static List *libfiles = 0; static List *all_output_files = 0; -// ----------------------------------------------------------------------------- -// check_suffix() -// -// Checks the suffix of a file to see if we should emit extern declarations. -// ----------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- + * check_suffix() + * + * Checks the suffix of a file to see if we should emit extern declarations. + * ----------------------------------------------------------------------------- */ static int check_suffix(String *filename) { const char *name = Char(filename); @@ -216,10 +216,11 @@ static int check_suffix(String *filename) { return 0; } -// ----------------------------------------------------------------------------- -// install_opts(int argc, char *argv[]) -// Install all command line options as preprocessor symbols -// ----------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- + * install_opts() + * + * Install all command line options as preprocessor symbols + * ----------------------------------------------------------------------------- */ static void install_opts(int argc, char *argv[]) { int i; @@ -255,11 +256,12 @@ static void install_opts(int argc, char *argv[]) { } } -// ----------------------------------------------------------------------------- -// decode_numbers_list(String *numlist) -// 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 -// ----------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- + * 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; @@ -279,22 +281,25 @@ static unsigned int decode_numbers_list(String *numlist) { return decoded_number; } -// ----------------------------------------------------------------------------- -// Sets the output directory for language specific (proxy) files if not set and -// adds trailing file separator if necessary. -// ----------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- + * Sets the output directory for language specific (proxy) files if not set and + * corrects the directory name and adds trailing file separator if necessary. + * ----------------------------------------------------------------------------- */ -static void set_outdir(const String *c_wrapper_file_dir) { +static void configure_outdir(const String *c_wrapper_file_dir) { - // Add file delimiter if not present in output directory name - if (outdir && Len(outdir) != 0) { + // Use the C wrapper file's directory if the output directory has not been set by user + if (!outdir || Len(outdir) == 0) + outdir = NewString(c_wrapper_file_dir); + + 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); } - // Use the C wrapper file's directory if the output directory has not been set by user - if (!outdir) - outdir = NewString(c_wrapper_file_dir); } /* This function sets the name of the configuration file */ @@ -1221,7 +1226,7 @@ int SWIG_main(int argc, char *argv[], Language *l) { } else { Setattr(top, "outfile_h", outfile_name_h); } - set_outdir(Swig_file_dirname(Getattr(top, "outfile"))); + configure_outdir(Swig_file_dirname(Getattr(top, "outfile"))); if (Swig_contract_mode_get()) { Swig_contracts(top); } @@ -1290,11 +1295,11 @@ int SWIG_main(int argc, char *argv[], Language *l) { return Swig_error_count(); } -// -------------------------------------------------------------------------- -// SWIG_exit(int exit_code) -// -// Cleanup and either freeze or exit -// -------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- + * SWIG_exit() + * + * Cleanup and either freeze or exit + * ----------------------------------------------------------------------------- */ void SWIG_exit(int exit_code) { while (freeze) { diff --git a/Source/Modules/modula3.cxx b/Source/Modules/modula3.cxx index d1e10b974..edd6690ce 100644 --- a/Source/Modules/modula3.cxx +++ b/Source/Modules/modula3.cxx @@ -972,8 +972,8 @@ MODULA3(): Swig_name_register("wrapper", "Modula3_%f"); if (old_variable_names) { - Swig_name_register("set", "set_%v"); - Swig_name_register("get", "get_%v"); + Swig_name_register("set", "set_%n%v"); + Swig_name_register("get", "get_%n%v"); } Printf(f_wrappers, "\n#ifdef __cplusplus\n"); @@ -1196,7 +1196,7 @@ MODULA3(): Swig_restore(n); native_function_flag = false; } else { - Printf(stderr, "%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n, "wrap:name")); + Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name")); } return SWIG_OK; @@ -1324,7 +1324,7 @@ MODULA3(): Parm *p; attachParameterNames(n, "tmap:name", "c:wrapname", "m3arg%d"); bool gencomma = false; - for (p = skipIgnored(l, "in"); p != NULL; p = skipIgnored(p, "in")) { + for (p = skipIgnored(l, "in"); p; p = skipIgnored(p, "in")) { String *arg = Getattr(p, "c:wrapname"); { @@ -1422,7 +1422,7 @@ MODULA3(): // below based on Swig_VargetToFunction() SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n)); - Setattr(n, "wrap:action", NewStringf("result = (%s) %s;", SwigType_lstr(ty, 0), Getattr(n, "value"))); + Setattr(n, "wrap:action", NewStringf("result = (%s)(%s);", SwigType_lstr(ty, 0), Getattr(n, "value"))); } Setattr(n, "wrap:name", wname); @@ -1545,7 +1545,7 @@ MODULA3(): Parm *p; writeArgState state; attachParameterNames(n, "tmap:rawinname", "modula3:rawname", "arg%d"); - for (p = skipIgnored(l, "m3rawintype"); p != NULL; p = skipIgnored(p, "m3rawintype")) { + for (p = skipIgnored(l, "m3rawintype"); p; p = skipIgnored(p, "m3rawintype")) { /* Get argument passing mode, should be one of VALUE, VAR, READONLY */ String *mode = Getattr(p, "tmap:m3rawinmode"); @@ -1928,7 +1928,7 @@ MODULA3(): } else if (Strcmp(code, "unsafe") == 0) { unsafe_module = true; } else if (Strcmp(code, "library") == 0) { - if (targetlibrary != NULL) { + if (targetlibrary) { Delete(targetlibrary); } targetlibrary = Copy(strvalue); @@ -2620,7 +2620,7 @@ MODULA3(): if (proxy_flag) { String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name); + String *intermediary_function_name = Swig_name_member(NSPACE_TODO, proxy_class_name, overloaded_name); Setattr(n, "proxyfuncname", Getattr(n, "sym:name")); Setattr(n, "imfuncname", intermediary_function_name); proxyClassFunctionHandler(n); @@ -2641,7 +2641,7 @@ MODULA3(): if (proxy_flag) { String *overloaded_name = getOverloadedName(n); - String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name); + String *intermediary_function_name = Swig_name_member(NSPACE_TODO, proxy_class_name, overloaded_name); Setattr(n, "proxyfuncname", Getattr(n, "sym:name")); Setattr(n, "imfuncname", intermediary_function_name); proxyClassFunctionHandler(n); @@ -2699,7 +2699,7 @@ MODULA3(): if (proxy_flag && wrapping_member_flag && !enum_constant_flag) { // Properties - setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) + setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, proxy_class_name, variable_name))) == 0); } @@ -2844,7 +2844,7 @@ MODULA3(): String *imcall = NewString(""); Printf(proxy_class_code, " %s %s(", Getattr(n, "feature:modula3:methodmodifiers"), proxy_class_name); - Printv(imcall, " : this(", m3raw_name, ".", Swig_name_construct(overloaded_name), "(", NIL); + Printv(imcall, " : this(", m3raw_name, ".", Swig_name_construct(NSPACE_TODO, overloaded_name), "(", NIL); /* Attach the non-standard typemaps to the parameter list */ Swig_typemap_attach_parms("in", l, NULL); @@ -2935,7 +2935,7 @@ MODULA3(): String *symname = Getattr(n, "sym:name"); if (proxy_flag) { - Printv(destructor_call, m3raw_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL); + Printv(destructor_call, m3raw_name, ".", Swig_name_destroy(NSPACE_TODO, symname), "(swigCPtr)", NIL); } return SWIG_OK; } diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx index 5eb0a58c9..0bc3c8a68 100644 --- a/Source/Modules/mzscheme.cxx +++ b/Source/Modules/mzscheme.cxx @@ -514,7 +514,7 @@ public: String *proc_name = NewString(""); String *tm; - String *tm2 = NewString("");; + String *tm2 = NewString(""); String *argnum = NewString("0"); String *arg = NewString("argv[0]"); Wrapper *f; diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index 41c30c858..82e3f846a 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -265,8 +265,8 @@ public: Swig_register_filebyname("class_ctors", f_class_ctors); if (old_variable_names) { - Swig_name_register("set", "%v__set__"); - Swig_name_register("get", "%v__get__"); + Swig_name_register("set", "%n%v__set__"); + Swig_name_register("get", "%n%v__get__"); } Swig_banner(f_begin); @@ -778,7 +778,7 @@ public: String *proc_name = NewString(""); String *tm; - String *tm2 = NewString("");; + String *tm2 = NewString(""); String *argnum = NewString("0"); String *arg = NewString("SWIG_Field(args,0)"); Wrapper *f; @@ -1599,7 +1599,7 @@ public: tm = Getattr(n, "feature:director:except"); } if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { - Printf(w->code, "if (result == NULL) {\n"); + Printf(w->code, "if (!result) {\n"); Printf(w->code, " CAML_VALUE error = *caml_named_value(\"director_except\");\n"); Replaceall(tm, "$error", "error"); Printv(w->code, Str(tm), "\n", NIL); diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index ab001a48b..ad425e3c8 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -701,8 +701,8 @@ public: Wrapper *getf = NewWrapper(); Wrapper *setf = NewWrapper(); - String *getname = Swig_name_get(iname); - String *setname = Swig_name_set(iname); + String *getname = Swig_name_get(NSPACE_TODO, iname); + String *setname = Swig_name_set(NSPACE_TODO, iname); Printf(setf->def, "static octave_value_list _wrap_%s(const octave_value_list& args,int nargout) {", setname); Printf(setf->def, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname); @@ -760,6 +760,7 @@ public: 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)) @@ -775,7 +776,7 @@ public: if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) { Replaceall(tm, "$source", value); Replaceall(tm, "$target", name); - Replaceall(tm, "$value", value); + Replaceall(tm, "$value", cppvalue ? cppvalue : value); Replaceall(tm, "$nsname", iname); Printf(f_init, "%s\n", tm); } else { @@ -882,7 +883,7 @@ public: 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 *cname = Swig_name_construct(constructor_name); + String *cname = Swig_name_construct(NSPACE_TODO, constructor_name); String *wcname = Swig_name_wrapper(cname); String *tname = texinfo_name(n); Printf(f_wrappers, "%s,%s,", wcname, tname); @@ -915,7 +916,7 @@ public: String *name = Getattr(n, "name"); String *iname = GetChar(n, "sym:name"); String *realname = iname ? iname : name; - String *rname = Swig_name_wrapper(Swig_name_member(class_name, realname)); + String *rname = Swig_name_wrapper(Swig_name_member(NSPACE_TODO, class_name, realname)); if (!Getattr(n, "sym:nextSibling")) { String *tname = texinfo_name(n); @@ -936,9 +937,9 @@ public: assert(s_members_tab); assert(class_name); String *symname = Getattr(n, "sym:name"); - String *getname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name, symname))); + String *getname = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname))); String *setname = GetFlag(n, "feature:immutable") ? - NewString("octave_set_immutable") : Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name, symname))); + NewString("octave_set_immutable") : Swig_name_wrapper(Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname))); assert(s_members_tab); Printf(s_members_tab, "{\"%s\",0,%s,%s,0,0},\n", symname, getname, setname); @@ -972,12 +973,12 @@ public: Delete(self); } - return Language::constructorHandler(n);; + return Language::constructorHandler(n); } virtual int destructorHandler(Node *n) { have_destructor = 1; - return Language::destructorHandler(n);; + return Language::destructorHandler(n); } virtual int staticmemberfunctionHandler(Node *n) { @@ -988,7 +989,7 @@ public: String *name = Getattr(n, "name"); String *iname = GetChar(n, "sym:name"); String *realname = iname ? iname : name; - String *rname = Swig_name_wrapper(Swig_name_member(class_name, realname)); + String *rname = Swig_name_wrapper(Swig_name_member(NSPACE_TODO, class_name, realname)); if (!Getattr(n, "sym:nextSibling")) { String *tname = texinfo_name(n); @@ -1014,9 +1015,9 @@ public: assert(s_members_tab); assert(class_name); String *symname = Getattr(n, "sym:name"); - String *getname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name, symname))); + String *getname = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname))); String *setname = GetFlag(n, "feature:immutable") ? - NewString("octave_set_immutable") : Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name, symname))); + NewString("octave_set_immutable") : Swig_name_wrapper(Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, class_name, symname))); assert(s_members_tab); Printf(s_members_tab, "{\"%s\",0,%s,%s,1,0},\n", symname, getname, setname); @@ -1243,7 +1244,7 @@ public: idx = 0; p = l; int use_parse = 0; - while (p != NULL) { + while (p) { if (checkAttribute(p, "tmap:in:numinputs", "0")) { p = Getattr(p, "tmap:in:next"); continue; diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx index 65deee2de..a62bdc1bf 100644 --- a/Source/Modules/overload.cxx +++ b/Source/Modules/overload.cxx @@ -59,7 +59,7 @@ void Wrapper_cast_dispatch_mode_set(int flag) { * languages ignore the first method parsed. * ----------------------------------------------------------------------------- */ -static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { +List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { Overloaded nodes[MAX_OVERLOAD]; int nnodes = 0; Node *o = Getattr(n, "sym:overloaded"); diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx index 4c7dba1eb..01e557b1a 100644 --- a/Source/Modules/perl5.cxx +++ b/Source/Modules/perl5.cxx @@ -308,7 +308,7 @@ public: if (no_pmfile) { f_pm = NewString(0); } else { - if (pmfile == NULL) { + if (!pmfile) { char *m = Char(module) + Len(module); while (m != Char(module)) { if (*m == ':') { @@ -840,8 +840,8 @@ public: SwigType *t = Getattr(n, "type"); Wrapper *getf, *setf; String *tm; - String *getname = Swig_name_get(iname); - String *setname = Swig_name_set(iname); + 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); @@ -1432,12 +1432,12 @@ public: if (Getattr(n, "feature:shadow")) { String *plcode = perlcode(Getattr(n, "feature:shadow"), 0); - String *plaction = NewStringf("%s::%s", cmodule, Swig_name_member(class_name, symname)); + 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(class_name, symname), ";\n", NIL); + Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL); } } return SWIG_OK; @@ -1462,8 +1462,8 @@ public: if (blessed) { - Printv(pcode, "*swig_", symname, "_get = *", cmodule, "::", Swig_name_get(Swig_name_member(class_name, symname)), ";\n", NIL); - Printv(pcode, "*swig_", symname, "_set = *", cmodule, "::", Swig_name_set(Swig_name_member(class_name, symname)), ";\n", NIL); + 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 */ @@ -1501,7 +1501,7 @@ public: 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(class_name, symname)); + String *plaction = NewStringf("%s::%s", module, Swig_name_member(NSPACE_TODO, class_name, symname)); Replaceall(plcode, "$action", plaction); Delete(plaction); Printv(pcode, plcode, NIL); @@ -1511,12 +1511,12 @@ public: 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(symname), " {\n", NIL); + Printv(pcode, "sub ", Swig_name_construct(NSPACE_TODO, symname), " {\n", NIL); } Printv(pcode, tab4, "my $pkg = shift;\n", - tab4, "my $self = ", cmodule, "::", Swig_name_construct(symname), "(@_);\n", tab4, "bless $self, $pkg if defined($self);\n", "}\n\n", NIL); + 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; } @@ -1536,7 +1536,7 @@ public: if (blessed) { if (Getattr(n, "feature:shadow")) { String *plcode = perlcode(Getattr(n, "feature:shadow"), 0); - String *plaction = NewStringf("%s::%s", module, Swig_name_member(class_name, symname)); + String *plaction = NewStringf("%s::%s", module, Swig_name_member(NSPACE_TODO, class_name, symname)); Replaceall(plcode, "$action", plaction); Delete(plaction); Printv(pcode, plcode, NIL); @@ -1548,7 +1548,7 @@ public: tab4, "return unless defined $self;\n", tab4, "delete $ITERATORS{$self};\n", tab4, "if (exists $OWNER{$self}) {\n", - tab8, cmodule, "::", Swig_name_destroy(symname), "($self);\n", tab8, "delete $OWNER{$self};\n", tab4, "}\n}\n\n", NIL); + tab8, cmodule, "::", Swig_name_destroy(NSPACE_TODO, symname), "($self);\n", tab8, "delete $OWNER{$self};\n", tab4, "}\n}\n\n", NIL); have_destructor = 1; } } @@ -1566,7 +1566,7 @@ public: member_func = 0; if ((blessed) && (!Getattr(n, "sym:nextSibling"))) { String *symname = Getattr(n, "sym:name"); - Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(class_name, symname), ";\n", NIL); + Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL); } return SWIG_OK; } @@ -1579,7 +1579,7 @@ public: Language::staticmembervariableHandler(n); if (blessed) { String *symname = Getattr(n, "sym:name"); - Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(class_name, symname), ";\n", NIL); + Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL); } return SWIG_OK; } @@ -1598,7 +1598,7 @@ public: blessed = oldblessed; if (blessed) { - Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(class_name, symname), ";\n", NIL); + Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(NSPACE_TODO, class_name, symname), ";\n", NIL); } return SWIG_OK; } @@ -1631,7 +1631,7 @@ public: if (value) { FILE *f = Swig_include_open(value); if (!f) { - Printf(stderr, "%s : Line %d. Unable to locate file %s\n", input_file, line_number, value); + Swig_error(input_file, line_number, "Unable to locate file %s\n", value); } else { char buffer[4096]; while (fgets(buffer, 4095, f)) { @@ -1641,7 +1641,7 @@ public: fclose(f); } } else { - Printf(stderr, "%s : Line %d. Unrecognized pragma.\n", input_file, line_number); + Swig_error(input_file, line_number, "Unrecognized pragma.\n"); } } } diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 989127101..e53009aaa 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -799,7 +799,7 @@ public: Wrapper_add_local(f, "director", "Swig::Director *director = 0"); Printf(f->code, "director = dynamic_cast(arg1);\n"); Wrapper_add_local(f, "upcall", "bool upcall = false"); - Printf(f->code, "upcall = !director->is_overriden_method((char *)\"%s\", (char *)\"%s\");\n", + Printf(f->code, "upcall = !director->swig_is_overridden_method((char *)\"%s\", (char *)\"%s\");\n", Swig_class_name(Swig_methodclass(n)), name); } @@ -1206,7 +1206,7 @@ public: } if (!pname_cstr) { // Unnamed parameter, e.g. int foo(int); - } else if (pname == NULL) { + } else if (!pname) { pname = NewString(pname_cstr); } else { size_t len = strlen(pname_cstr); @@ -1290,7 +1290,7 @@ public: if (errno || *p) { Clear(value); Append(value, "?"); - } else if (strchr(Char(value), '.') == NULL) { + } else if (strchr(Char(value), '.') == 0) { // Ensure value is a double constant, not an integer one. Append(value, ".0"); double val2 = strtod(Char(value), &p); @@ -1496,7 +1496,7 @@ public: Printf(prepare, "case %d: ", ++last_handled_i); } if (Cmp(d, "void") != 0) { - if ((!directorsEnabled() || !Swig_directorclass(n)) && !newobject) { + if ((!directorsEnabled() || !Swig_directorclass(n)) && !newobject) { Append(prepare, "$r="); } else { Printf(prepare, "$this->%s=", SWIG_PTR); @@ -1576,14 +1576,21 @@ public: } if (Getattr(n, "access") && haspublicbase) { Delete(acc); - acc = NewString("public"); + acc = NewStringEmpty(); // implicitly public Swig_warning(WARN_PHP_PUBLIC_BASE, input_file, line_number, Char(warnmsg)); Delete(warnmsg); } } - if (Cmp(acc, "") != 0) { + + if (Cmp(acc, "public") == 0) { + // The default visibility for methods is public, so don't specify + // that explicitly to keep the wrapper size down. + Delete(acc); + acc = NewStringEmpty(); + } else if (Cmp(acc, "") != 0) { Append(acc, " "); } + if (constructor) { const char * arg0; if (max_num_of_arguments > 0) { @@ -1632,11 +1639,13 @@ public: Printf(output, "%s", prepare); if (constructor) { if (!directorsEnabled() || !Swig_directorclass(n)) { - if (strcmp(methodname, "__construct") == 0) { - Printf(output, "\t\t$this->%s=%s;\n", SWIG_PTR, invoke); - } else { - String *classname = Swig_class_name(current_class); - Printf(output, "\t\treturn new %s(%s);\n", classname, invoke); + if (!Len(prepare)) { + if (strcmp(methodname, "__construct") == 0) { + Printf(output, "\t\t$this->%s=%s;\n", SWIG_PTR, invoke); + } else { + String *classname = Swig_class_name(current_class); + Printf(output, "\t\treturn new %s(%s);\n", classname, invoke); + } } } else { Node *parent = Swig_methodclass(n); @@ -1694,7 +1703,7 @@ public: Printf(output, "\t\t\treturn new $c($r);\n"); } else { Printf(output, "\t\t\t$c = new stdClass();\n"); - Printf(output, "\t\t\t$c->_cPtr = $r;\n"); + Printf(output, "\t\t\t$c->"SWIG_PTR" = $r;\n"); Printf(output, "\t\t\treturn $c;\n"); } Printf(output, "\t\t}\n\t\treturn $r;\n"); @@ -1780,8 +1789,6 @@ done: if (!addSymbol(iname, n)) return SWIG_ERROR; - SwigType_remember(t); - /* First link C variables to PHP */ tm = Swig_typemap_lookup("varinit", n, name, 0); @@ -1789,7 +1796,7 @@ done: Replaceall(tm, "$target", name); Printf(s_vinit, "%s\n", tm); } else { - Printf(stderr, "%s: Line %d, Unable to link with type %s\n", input_file, line_number, SwigType_str(t, 0)); + Swig_error(input_file, line_number, "Unable to link with type %s\n", SwigType_str(t, 0)); } /* Now generate PHP -> C sync blocks */ @@ -1799,7 +1806,7 @@ done: Replaceall(tm, "$symname", iname); Printf(f_c->code, "%s\n", tm); } else { - Printf(stderr,"%s: Line %d, Unable to link with type %s\n", input_file, line_number, SwigType_str(t, 0)); + Swig_error(input_file, line_number, "Unable to link with type %s\n", SwigType_str(t, 0)); } */ /* Now generate C -> PHP sync blocks */ @@ -1811,7 +1818,7 @@ done: Replaceall(tm, "$symname", iname); Printf(f_php->code, "%s\n", tm); } else { - Printf(stderr,"%s: Line %d, Unable to link with type %s\n", input_file, line_number, SwigType_str(t, 0)); + Swig_error(input_file, line_number, "Unable to link with type %s\n", SwigType_str(t, 0)); } } */ @@ -2497,7 +2504,7 @@ done: idx = 0; p = l; int use_parse = 0; - while (p != NULL) { + while (p) { if (checkAttribute(p, "tmap:in:numinputs", "0")) { p = Getattr(p, "tmap:in:next"); continue; @@ -2566,7 +2573,7 @@ done: } Append(w->code, "zval *result, funcname;\n"); Append(w->code, "MAKE_STD_ZVAL(result);\n"); - Printf(w->code, "ZVAL_STRING(&funcname, (char *)\"%s\", 0);\n", name); + Printf(w->code, "ZVAL_STRING(&funcname, (char *)\"%s\", 0);\n", GetChar(n, "sym:name")); Append(w->code, "if (!swig_self) {\n"); Append(w->code, " SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");"); Append(w->code, "}\n\n"); diff --git a/Source/Modules/pike.cxx b/Source/Modules/pike.cxx index 6913596d3..bd1edec62 100644 --- a/Source/Modules/pike.cxx +++ b/Source/Modules/pike.cxx @@ -159,8 +159,8 @@ public: Printf(f_header, "#define SWIG_name \"%s\"\n\n", module); /* Change naming scheme for constructors and destructors */ - Swig_name_register("construct", "%c_create"); - Swig_name_register("destroy", "%c_destroy"); + Swig_name_register("construct", "%n%c_create"); + Swig_name_register("destroy", "%n%c_destroy"); /* Current wrap type */ current = NO_CPP; @@ -766,7 +766,7 @@ public: /* Create a function to set the values of the (mutable) variables */ if (need_setter) { Wrapper *wrapper = NewWrapper(); - String *setter = Swig_name_member(getClassPrefix(), "`->="); + String *setter = Swig_name_member(NSPACE_TODO, getClassPrefix(), "`->="); String *wname = Swig_name_wrapper(setter); Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL); Printf(wrapper->locals, "char *name = (char *) STR0(Pike_sp[0-args].u.string);\n"); @@ -775,7 +775,7 @@ public: while (i.item) { if (!GetFlag(i.item, "feature:immutable")) { name = Getattr(i.item, "name"); - funcname = Swig_name_wrapper(Swig_name_set(Swig_name_member(getClassPrefix(), name))); + funcname = Swig_name_wrapper(Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, getClassPrefix(), name))); Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name); Printf(wrapper->code, "%s(args);\n", funcname); Printf(wrapper->code, "return;\n"); @@ -805,7 +805,7 @@ public: /* Create a function to get the values of the (mutable) variables */ Wrapper *wrapper = NewWrapper(); - String *getter = Swig_name_member(getClassPrefix(), "`->"); + String *getter = Swig_name_member(NSPACE_TODO, getClassPrefix(), "`->"); String *wname = Swig_name_wrapper(getter); Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL); Printf(wrapper->locals, "char *name = (char *) STR0(Pike_sp[0-args].u.string);\n"); @@ -813,7 +813,7 @@ public: i = First(membervariables); while (i.item) { name = Getattr(i.item, "name"); - funcname = Swig_name_wrapper(Swig_name_get(Swig_name_member(getClassPrefix(), name))); + funcname = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, getClassPrefix(), name))); Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name); Printf(wrapper->code, "%s(args);\n", funcname); Printf(wrapper->code, "return;\n"); diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index bafd567e0..fed5205e1 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -211,6 +211,7 @@ public: 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 { @@ -222,11 +223,13 @@ public: 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;\n"); + Append(f, "SWIG_PYTHON_THREAD_END_ALLOW;"); } + Append(f, "\n}"); } } @@ -1070,7 +1073,7 @@ public: bool have_docstring(Node *n) { String *str = Getattr(n, "feature:docstring"); - return (str != NULL && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")); + return (str && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")); } /* ------------------------------------------------------------ @@ -1082,7 +1085,7 @@ public: String *docstring(Node *n, autodoc_t ad_type, const String *indent, bool use_triple = true) { String *str = Getattr(n, "feature:docstring"); - bool have_ds = (str != NULL && Len(str) > 0); + bool have_ds = (str && Len(str) > 0); bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")); const char *triple_double = use_triple ? "\"\"\"" : ""; String *autodoc = NULL; @@ -1098,7 +1101,7 @@ public: if (have_auto) { autodoc = make_autodoc(n, ad_type); - have_auto = (autodoc != NULL && Len(autodoc) > 0); + have_auto = (autodoc && Len(autodoc) > 0); } // If there is more than one line then make docstrings like this: // @@ -1113,14 +1116,14 @@ public: doc = NewString(""); Printv(doc, triple_double, "\n", pythoncode(autodoc, indent), "\n", pythoncode(str, indent), indent, triple_double, NIL); } else if (!have_auto && have_ds) { // only docstring - if (Strchr(str, '\n') == NULL) { + if (Strchr(str, '\n') == 0) { doc = NewStringf("%s%s%s", triple_double, str, triple_double); } else { doc = NewString(""); Printv(doc, triple_double, "\n", pythoncode(str, indent), indent, triple_double, NIL); } } else if (have_auto && !have_ds) { // only autodoc - if (Strchr(autodoc, '\n') == NULL) { + if (Strchr(autodoc, '\n') == 0) { doc = NewStringf("%s%s%s", triple_double, autodoc, triple_double); } else { doc = NewString(""); @@ -1358,7 +1361,7 @@ public: { // Only do the autodoc if there isn't a docstring for the class String *str = Getattr(n, "feature:docstring"); - if (str == NULL || Len(str) == 0) { + if (!str || Len(str) == 0) { if (CPlusPlus) { Printf(doc, "Proxy of C++ %s class", real_classname); } else { @@ -1554,7 +1557,7 @@ public: bool have_pythonprepend(Node *n) { String *str = Getattr(n, "feature:pythonprepend"); - return (str != NULL && Len(str) > 0); + return (str && Len(str) > 0); } /* ------------------------------------------------------------ @@ -1581,7 +1584,7 @@ public: String *str = Getattr(n, "feature:pythonappend"); if (!str) str = Getattr(n, "feature:addtofunc"); - return (str != NULL && Len(str) > 0); + return (str && Len(str) > 0); } /* ------------------------------------------------------------ @@ -1866,7 +1869,7 @@ public: && ((shadow & PYSHADOW_MEMBER))) { String *nname = Getattr(n, "sym:name"); String *sname = Getattr(getCurrentClass(), "sym:name"); - String *cname = Swig_name_construct(sname); + String *cname = Swig_name_construct(NSPACE_TODO, sname); handled_as_init = (Strcmp(nname, sname) == 0) || (Strcmp(nname, cname) == 0); Delete(cname); } @@ -2200,8 +2203,13 @@ public: Append(f->code, "try {\n"); } else { if (allow_thread) { - Append(f->code, "{\n"); - thread_begin_allow(n, f->code); + 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); } } @@ -2214,11 +2222,6 @@ public: Append(actioncode, "} catch (Swig::DirectorException&) {\n"); Append(actioncode, " SWIG_fail;\n"); Append(actioncode, "}\n"); - } else { - if (allow_thread) { - thread_end_allow(n, actioncode); - Append(actioncode, "}\n"); - } } /* This part below still needs cleanup */ @@ -2437,8 +2440,8 @@ public: } } - String *getname = Swig_name_get(iname); - String *setname = Swig_name_set(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); @@ -2718,15 +2721,15 @@ public: Printf(f_directors_h, "\n\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* name) const {\n"); - Printf(f_directors_h, " std::map::const_iterator iv = inner.find(name);\n"); - Printf(f_directors_h, " return (iv != inner.end() ? iv->second : false);\n"); + Printf(f_directors_h, " bool swig_get_inner(const char* protected_method_name) const {\n"); + Printf(f_directors_h, " std::map::const_iterator iv = swig_inner.find(protected_method_name);\n"); + Printf(f_directors_h, " return (iv != swig_inner.end() ? iv->second : false);\n"); Printf(f_directors_h, " }\n\n"); - Printf(f_directors_h, " void swig_set_inner(const char* name, bool val) const\n"); - Printf(f_directors_h, " { inner[name] = val;}\n\n"); + Printf(f_directors_h, " void swig_set_inner(const char* protected_method_name, bool val) const\n"); + Printf(f_directors_h, " { swig_inner[protected_method_name] = val;}\n\n"); Printf(f_directors_h, "private:\n"); - Printf(f_directors_h, " mutable std::map inner;\n"); + Printf(f_directors_h, " mutable std::map swig_inner;\n"); } if (director_method_index) { @@ -2738,7 +2741,7 @@ public: 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 == NULL) {\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"); @@ -2771,7 +2774,7 @@ public: shadow = oldshadow; if (shadow) { String *symname = Getattr(n, "sym:name"); - String *mrename = Swig_name_disown(symname); //Getattr(n, "name")); + String *mrename = Swig_name_disown(NSPACE_TODO, symname); //Getattr(n, "name")); Printv(f_shadow, tab4, "def __disown__(self):\n", NIL); #ifdef USE_THISOWN Printv(f_shadow, tab8, "self.thisown = 0\n", NIL); @@ -2901,7 +2904,7 @@ public: Printf(f_shadow, ":\n"); if (have_docstring(n)) { String *str = docstring(n, AUTODOC_CLASS, tab4); - if (str != NULL && Len(str)) + if (str && Len(str)) Printv(f_shadow, tab4, str, "\n", NIL); } if (!modern) { @@ -3029,7 +3032,7 @@ public: List *shadow_list = Getattr(n, "shadow_methods"); for (int i = 0; i < Len(shadow_list); ++i) { String *symname = Getitem(shadow_list, i); - Printf(f_shadow_file, "%s.%s = new_instancemethod(%s.%s,None,%s)\n", class_name, symname, module, Swig_name_member(class_name, symname), class_name); + Printf(f_shadow_file, "%s.%s = new_instancemethod(%s.%s,None,%s)\n", class_name, symname, module, Swig_name_member(NSPACE_TODO, class_name, symname), class_name); } } Printf(f_shadow_file, "%s_swigregister = %s.%s_swigregister\n", class_name, module, class_name); @@ -3093,7 +3096,7 @@ public: } if (Getattr(n, "feature:shadow")) { String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4); - String *pyaction = NewStringf("%s.%s", module, Swig_name_member(class_name, symname)); + String *pyaction = NewStringf("%s.%s", module, Swig_name_member(NSPACE_TODO, class_name, symname)); Replaceall(pycode, "$action", pyaction); Delete(pyaction); Printv(f_shadow, pycode, "\n", NIL); @@ -3105,7 +3108,7 @@ public: if (!have_addtofunc(n)) { if (!fastproxy || olddefs) { Printv(f_shadow, tab4, "def ", symname, "(", parms, ")", returnTypeAnnotation(n), ":", NIL); - Printv(f_shadow, " return ", funcCall(Swig_name_member(class_name, symname), callParms), "\n", NIL); + Printv(f_shadow, " return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL); } } else { Printv(f_shadow, tab4, "def ", symname, "(",parms , ")", returnTypeAnnotation(n), ":", NIL); @@ -3118,11 +3121,11 @@ public: } if (have_pythonappend(n)) { fproxy = 0; - Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(class_name, symname), callParms), "\n", NIL); + Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL); Printv(f_shadow, pythoncode(pythonappend(n), tab8), "\n", NIL); Printv(f_shadow, tab8, "return val\n\n", NIL); } else { - Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(class_name, symname), callParms), "\n\n", NIL); + Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n\n", NIL); } } } @@ -3163,11 +3166,11 @@ public: if (have_pythonprepend(n)) Printv(f_shadow, pythoncode(pythonprepend(n), tab8), "\n", NIL); if (have_pythonappend(n)) { - Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(class_name, symname), callParms), "\n", NIL); + Printv(f_shadow, tab8, "val = ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n", NIL); Printv(f_shadow, pythoncode(pythonappend(n), tab8), "\n", NIL); Printv(f_shadow, tab8, "return val\n\n", NIL); } else { - Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(class_name, symname), callParms), "\n\n", NIL); + Printv(f_shadow, tab8, "return ", funcCall(Swig_name_member(NSPACE_TODO, class_name, symname), callParms), "\n\n", NIL); } Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = staticmethod(", symname, ")\n", NIL); @@ -3177,10 +3180,10 @@ public: } else { if (!modern) { - Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", module, ".", Swig_name_member(class_name, symname), "\n", NIL); + Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), "\n", NIL); } if (!classic) { - Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = staticmethod(", module, ".", Swig_name_member(class_name, symname), ")\n", NIL); + Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = staticmethod(", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), ")\n", NIL); } } } @@ -3235,7 +3238,7 @@ public: if (!have_constructor) { String *nname = Getattr(n, "sym:name"); String *sname = Getattr(getCurrentClass(), "sym:name"); - String *cname = Swig_name_construct(sname); + String *cname = Swig_name_construct(NSPACE_TODO, sname); handled_as_init = (Strcmp(nname, sname) == 0) || (Strcmp(nname, cname) == 0); Delete(cname); } @@ -3243,7 +3246,7 @@ public: if (!have_constructor && handled_as_init) { if (Getattr(n, "feature:shadow")) { String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4); - String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(symname)); + String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(NSPACE_TODO, symname)); Replaceall(pycode, "$action", pyaction); Delete(pyaction); Printv(f_shadow, pycode, "\n", NIL); @@ -3254,6 +3257,7 @@ public: String *classname = Swig_class_name(parent); String *rclassname = Swig_class_name(getCurrentClass()); assert(rclassname); + String *parms = make_pyParmList(n, true, false, allow_kwargs); /* Pass 'self' only if using director */ @@ -3274,10 +3278,10 @@ public: Printv(f_shadow, pythoncode(pythonprepend(n), tab8), "\n", NIL); Printv(f_shadow, pass_self, NIL); if (fastinit) { - Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self,", funcCall(Swig_name_construct(symname), callParms), ")\n", NIL); + Printv(f_shadow, tab8, module, ".", class_name, "_swiginit(self,", funcCall(Swig_name_construct(NSPACE_TODO, symname), callParms), ")\n", NIL); } else { Printv(f_shadow, - tab8, "this = ", funcCall(Swig_name_construct(symname), callParms), "\n", + tab8, "this = ", funcCall(Swig_name_construct(NSPACE_TODO, symname), callParms), "\n", tab8, "try: self.this.append(this)\n", tab8, "except: self.this = this\n", NIL); } if (have_pythonappend(n)) @@ -3291,21 +3295,21 @@ public: if (Getattr(n, "feature:shadow")) { String *pycode = pythoncode(Getattr(n, "feature:shadow"), ""); - String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(symname)); + String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(NSPACE_TODO, symname)); Replaceall(pycode, "$action", pyaction); Delete(pyaction); Printv(f_shadow_stubs, pycode, "\n", NIL); Delete(pycode); } else { - String *parms = make_pyParmList(n, true, false, allow_kwargs); - String *callParms = make_pyParmList(n, true, true, allow_kwargs); + 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, pythoncode(pythonprepend(n), tab4), "\n", NIL); - Printv(f_shadow_stubs, tab4, "val = ", funcCall(Swig_name_construct(symname), callParms), "\n", NIL); + Printv(f_shadow_stubs, tab4, "val = ", funcCall(Swig_name_construct(NSPACE_TODO, symname), callParms), "\n", NIL); #ifdef USE_THISOWN Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL); #endif @@ -3335,13 +3339,13 @@ public: if (shadow) { if (Getattr(n, "feature:shadow")) { String *pycode = pythoncode(Getattr(n, "feature:shadow"), tab4); - String *pyaction = NewStringf("%s.%s", module, Swig_name_destroy(symname)); + 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(symname), "\n", NIL); + Printv(f_shadow, tab4, "__swig_destroy__ = ", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "\n", NIL); if (!have_pythonprepend(n) && !have_pythonappend(n)) { if (proxydel) { Printv(f_shadow, tab4, "__del__ = lambda self : None;\n", NIL); @@ -3355,7 +3359,7 @@ public: Printv(f_shadow, pythoncode(pythonprepend(n), tab8), "\n", NIL); #ifdef USE_THISOWN Printv(f_shadow, tab8, "try:\n", NIL); - Printv(f_shadow, tab8, tab4, "if self.thisown: ", module, ".", Swig_name_destroy(symname), "(self)\n", NIL); + Printv(f_shadow, tab8, tab4, "if self.thisown: ", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "(self)\n", NIL); Printv(f_shadow, tab8, "except: pass\n", NIL); #else #endif @@ -3382,9 +3386,9 @@ public: shadow = oldshadow; if (shadow) { - String *mname = Swig_name_member(class_name, symname); - String *setname = Swig_name_set(mname); - String *getname = Swig_name_get(mname); + 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); if (shadow) { int assignable = is_assignable(n); if (!modern) { @@ -3419,15 +3423,15 @@ public: if (shadow && !GetFlag(n, "wrappedasconstant")) { String *symname = Getattr(n, "sym:name"); if (GetFlag(n, "hasconsttype")) { - String *mname = Swig_name_member(class_name, symname); + 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(class_name, symname); - String *getname = Swig_name_get(mname); + 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(mname); + String *setname = Swig_name_set(NSPACE_TODO, mname); String *wrapsetname = Swig_name_wrapper(setname); String *varsetname = NewStringf("Swig_var_%s", setname); @@ -3490,7 +3494,7 @@ public: shadow = oldshadow; if (shadow) { - Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(class_name, symname), "\n", NIL); + Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(NSPACE_TODO, class_name, symname), "\n", NIL); } return SWIG_OK; } @@ -3719,7 +3723,7 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { idx = 0; p = l; int use_parse = 0; - while (p != NULL) { + while (p) { if (checkAttribute(p, "tmap:in:numinputs", "0")) { p = Getattr(p, "tmap:in:next"); continue; @@ -3906,13 +3910,13 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { if (tm) tm = Copy(tm); } - Append(w->code, "if (result == NULL) {\n"); + Append(w->code, "if (!result) {\n"); 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 != NULL) {\n"); + 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"); } diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index ad83d608a..749797c78 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -556,10 +556,10 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) { ParmList *parms = SwigType_function_parms(SwigType_del_pointer(Copy(t)), n); - // if (debugMode) { + if (debugMode) { Printf(stderr, "Type: %s\n", t); Printf(stderr, "Return type: %s\n", SwigType_base(t)); - //} + } bool isVoidType = Strcmp(rettype, "void") == 0; if (debugMode) @@ -1299,6 +1299,8 @@ void R::addAccessor(String *memberName, Wrapper *wrapper, String *name, Printf(stderr, "Adding accessor: %s (%s) => %s\n", memberName, name, tmp); } +#define Swig_overload_rank R_swig_overload_rank + #define MAX_OVERLOAD 256 struct Overloaded { @@ -1673,7 +1675,7 @@ int R::functionWrapper(Node *n) { } p = nextSibling(p); } - + String *unresolved_return_type = Copy(type); if (expandTypedef(type) && @@ -1731,7 +1733,7 @@ int R::functionWrapper(Node *n) { 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 @@ -2036,7 +2038,13 @@ int R::functionWrapper(Node *n) { Printv(f->code, cleanup, NIL); Delete(cleanup); - + /* Look to see if there is any newfree cleanup code */ + if (GetFlag(n, "feature:new")) { + if ((tm = Swig_typemap_lookup("newfree", n, "result", 0))) { + Replaceall(tm, "$source", "result"); /* deprecated */ + Printf(f->code, "%s\n", tm); + } + } Printv(f->code, UnProtectWrapupCode, NIL); @@ -2053,7 +2061,17 @@ int R::functionWrapper(Node *n) { Printv(sfun->code, ";", (Len(tm) ? "ans = " : ""), ".Call('", wname, "', ", sargs, "PACKAGE='", Rpackage, "');\n", NIL); if(Len(tm)) - Printf(sfun->code, "%s\n\nans;\n", 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, delete_%s)\n", finalizer); + } + Printf(sfun->code, "ans\n"); + } + if (destructor) Printv(f->code, "R_ClearExternalPtr(self);\n", NIL); @@ -2496,7 +2514,7 @@ int R::membervariableHandler(Node *n) { int status(Language::membervariableHandler(n)); - if(opaqueClassDeclaration == NULL && debugMode) + if(!opaqueClassDeclaration && debugMode) Printf(stderr, " %s %s\n", Getattr(n, "name"), Getattr(n, "type")); processing_member_access_function = 0; diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index 82808b154..bcdfd69d3 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -231,7 +231,7 @@ private: bool have_docstring(Node *n) { String *str = Getattr(n, "feature:docstring"); - return (str != NULL && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")); + return (str && Len(str) > 0) || (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")); } /* ------------------------------------------------------------ @@ -244,7 +244,7 @@ private: String *docstring(Node *n, autodoc_t ad_type) { String *str = Getattr(n, "feature:docstring"); - bool have_ds = (str != NULL && Len(str) > 0); + bool have_ds = (str && Len(str) > 0); bool have_auto = (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")); String *autodoc = NULL; String *doc = NULL; @@ -259,7 +259,7 @@ private: if (have_auto) { autodoc = make_autodoc(n, ad_type); - have_auto = (autodoc != NULL && Len(autodoc) > 0); + have_auto = (autodoc && Len(autodoc) > 0); } // If there is more than one line then make docstrings like this: // @@ -272,14 +272,14 @@ private: doc = NewString(""); Printv(doc, "\n", autodoc, "\n", str, NIL); } else if (!have_auto && have_ds) { // only docstring - if (Strchr(str, '\n') == NULL) { + if (Strchr(str, '\n') == 0) { doc = NewString(str); } else { doc = NewString(""); Printv(doc, str, NIL); } } else if (have_auto && !have_ds) { // only autodoc - if (Strchr(autodoc, '\n') == NULL) { + if (Strchr(autodoc, '\n') == 0) { doc = NewStringf("%s", autodoc); } else { doc = NewString(""); @@ -618,7 +618,7 @@ private: { // Only do the autodoc if there isn't a docstring for the class String *str = Getattr(n, "feature:docstring"); - if (counter == 0 && (str == NULL || Len(str) == 0)) { + if (counter == 0 && (str == 0 || Len(str) == 0)) { if (CPlusPlus) { Printf(doc, " Proxy of C++ %s class", full_name); } else { @@ -1248,7 +1248,11 @@ public: Iterator alias = First(aliases); while (alias.item) { if (Len(alias.item) > 0) { - Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias.item, "\", \"", iname, "\");\n", NIL); + 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); } @@ -2115,7 +2119,7 @@ public: /* create getter */ int addfail = 0; - String *getname = Swig_name_get(iname); + 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); @@ -2150,7 +2154,7 @@ public: Printf(f_wrappers, "%s", docs); Delete(docs); - String *setname = Swig_name_set(iname); + String *setname = Swig_name_set(NSPACE_TODO, iname); setfname = Swig_name_wrapper(setname); Setattr(n, "wrap:name", setfname); Printv(setf->def, "SWIGINTERN VALUE\n", setfname, "(VALUE self, ", NIL); @@ -2578,7 +2582,7 @@ public: /* First wrap the allocate method */ current = CONSTRUCTOR_ALLOCATE; - Swig_name_register("construct", "%c_allocate"); + Swig_name_register("construct", "%n%c_allocate"); Language::constructorHandler(n); @@ -2613,7 +2617,7 @@ public: Delete(docs); current = CONSTRUCTOR_INITIALIZE; - Swig_name_register("construct", "new_%c"); + Swig_name_register("construct", "new_%n%c"); Language::constructorHandler(n); /* Restore original parameter list */ @@ -2621,7 +2625,7 @@ public: Swig_restore(n); /* Done */ - Swig_name_unregister((const_String_or_char_ptr ) "construct"); + Swig_name_unregister("construct"); current = NO_CPP; klass->constructor_defined = 1; return SWIG_OK; @@ -2635,7 +2639,7 @@ public: /* First wrap the allocate method */ current = CONSTRUCTOR_ALLOCATE; - Swig_name_register("construct", "%c_allocate"); + Swig_name_register("construct", "%n%c_allocate"); return Language::copyconstructorHandler(n); } diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx index 1ed85e82e..86cccdf88 100644 --- a/Source/Modules/swigmain.cxx +++ b/Source/Modules/swigmain.cxx @@ -51,6 +51,7 @@ extern "C" { Language *swig_cffi(void); Language *swig_uffi(void); Language *swig_r(void); + Language *swig_go(void); } struct swig_module { @@ -69,6 +70,7 @@ static swig_module modules[] = { {"-clisp", swig_clisp, "CLISP"}, {"-cffi", swig_cffi, "CFFI"}, {"-csharp", swig_csharp, "C#"}, + {"-go", swig_go, "Go"}, {"-guile", swig_guile, "Guile"}, {"-java", swig_java, "Java"}, {"-lua", swig_lua, "Lua"}, diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index 813c56cb9..b0b488d6f 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -11,8 +11,6 @@ * Main header file for SWIG modules. * ----------------------------------------------------------------------------- */ -/* $Id$ */ - #ifndef SWIG_SWIGMOD_H_ #define SWIG_SWIGMOD_H_ @@ -267,7 +265,7 @@ protected: void allow_overloading(int val = 1); /* Wrapping class query */ - int is_wrapping_class(); + int is_wrapping_class() const; /* Return the node for the current class */ Node *getCurrentClass() const; @@ -275,6 +273,9 @@ protected: /* 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; @@ -343,6 +344,7 @@ void Swig_overload_check(Node *n); String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *); String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *); String *Swig_overload_dispatch_fast(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 */ diff --git a/Source/Modules/tcl8.cxx b/Source/Modules/tcl8.cxx index 94191abcc..b6b4c6965 100644 --- a/Source/Modules/tcl8.cxx +++ b/Source/Modules/tcl8.cxx @@ -573,7 +573,7 @@ public: /* Create a function for getting a variable */ int addfail = 0; getf = NewWrapper(); - String *getname = Swig_name_get(iname); + 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); @@ -605,7 +605,7 @@ public: /* Try to create a function setting a variable */ if (is_assignable(n)) { setf = NewWrapper(); - setname = Swig_name_set(iname); + setname = Swig_name_set(NSPACE_TODO, iname); setfname = Swig_name_wrapper(setname); Setattr(n, "wrap:name", setfname); if (setf) { @@ -951,7 +951,7 @@ public: 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(constructor_name))); + Printf(f_wrappers, "%s", Swig_name_wrapper(Swig_name_construct(NSPACE_TODO, constructor_name))); Delete(constructor_name); constructor_name = 0; } else { @@ -989,7 +989,7 @@ public: Language::memberfunctionHandler(n); realname = iname ? iname : name; - rname = Swig_name_wrapper(Swig_name_member(class_name, realname)); + 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); } @@ -1082,11 +1082,11 @@ public: Language::membervariableHandler(n); Printv(attr_tab, tab4, "{ \"-", symname, "\",", NIL); - rname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name, symname))); + 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(Swig_name_member(class_name, symname))); + 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 { diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx index 8d4ddda11..e0e06d54e 100644 --- a/Source/Modules/typepass.cxx +++ b/Source/Modules/typepass.cxx @@ -36,6 +36,7 @@ class TypePass:private Dispatcher { Node *module; int importmode; String *nsname; + String *nssymname; Hash *classhash; List *normalize; @@ -230,6 +231,37 @@ class TypePass:private Dispatcher { Node *bclass = n; /* Getattr(n,"class"); */ Hash *scopes = Getattr(bclass, "typescope"); SwigType_inherit(clsname, bname, cast, 0); + String *smartptr = Getattr(first, "feature:smartptr"); + if (smartptr) { + SwigType *smart = 0; + SwigType *spt = Swig_cparse_type(smartptr); + if (spt) { + smart = SwigType_typedef_resolve_all(spt); + Delete(spt); + /* 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); + SwigType *rclsname = SwigType_typedef_resolve_all(clsname); + SwigType *rbname = SwigType_typedef_resolve_all(bname); + Replaceall(bsmart, rclsname, rbname); + 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); + Delete(convcode); + Delete(bsmart); + Delete(smart); + } else { + Swig_error(Getfile(first), Getline(first), "Invalid type (%s) in 'smartptr' feature for class %s.\n", smartptr, clsname); + } + } if (!importmode) { String *btype = Copy(bname); SwigType_add_pointer(btype); @@ -296,6 +328,7 @@ class TypePass:private Dispatcher { inclass = 0; normalize = 0; nsname = 0; + nssymname = 0; classhash = Getattr(n, "classes"); emit_children(n); normalize_list(); @@ -415,6 +448,10 @@ class TypePass:private Dispatcher { 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")); @@ -535,7 +572,9 @@ class TypePass:private Dispatcher { } } 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); @@ -557,6 +596,8 @@ class TypePass:private Dispatcher { } normalize = olist; + Delete(nssymname); + nssymname = oldnssymname; Delete(nsname); nsname = oldnsname; return SWIG_OK; @@ -734,6 +775,11 @@ class TypePass:private Dispatcher { } 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! @@ -750,7 +796,7 @@ class TypePass:private Dispatcher { bool reset; String *enumvalue = Getattr(c, "enumvalue"); - if (GetFlag(c, "feature:ignore")) { + if (GetFlag(c, "feature:ignore") || !Getattr(c, "sym:name")) { reset = enumvalue ? true : false; previous_ignored = true; } else { @@ -792,11 +838,15 @@ class TypePass:private Dispatcher { value = name; if (Strcmp(value, name) == 0) { String *new_value; - if (((nsname) || (inclass)) && cparse_cplusplus) { + if ((nsname || inclass) && cparse_cplusplus) { new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value); } else { new_value = NewString(value); } + if ((nsname || inclass) && !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); } diff --git a/Source/Preprocessor/cpp.c b/Source/Preprocessor/cpp.c index feaa82ff8..5dd320994 100644 --- a/Source/Preprocessor/cpp.c +++ b/Source/Preprocessor/cpp.c @@ -191,7 +191,7 @@ void Preprocessor_init(void) { Preprocessor_expr_init(); /* Initialize the expression evaluator */ included_files = NewHash(); - id_scan = NewScanner();; + id_scan = NewScanner(); } diff --git a/Source/Preprocessor/preprocessor.h b/Source/Preprocessor/preprocessor.h index 8f98dae15..b08ff31b9 100644 --- a/Source/Preprocessor/preprocessor.h +++ b/Source/Preprocessor/preprocessor.h @@ -11,8 +11,6 @@ * SWIG preprocessor module. * ----------------------------------------------------------------------------- */ -/* $Id$ */ - #ifndef SWIG_PREPROCESSOR_H_ #define SWIG_PREPROCESSOR_H_ diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index 08cfdc008..4a461fce8 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -830,7 +830,7 @@ int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parm * Converts a C++ method node to a function accessor function. * ----------------------------------------------------------------------------- */ -int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *director_type, int is_director) { +int Swig_MethodToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int flags, SwigType *director_type, int is_director) { String *name, *qualifier; ParmList *parms; SwigType *type; @@ -878,7 +878,7 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc 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 happens in other target + This happens in python, but may also happen in other target languages. */ if (GetFlag(n, "feature:self:disown")) { @@ -944,7 +944,7 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc String *defaultargs = Getattr(n, "defaultargs"); String *code = Getattr(n, "code"); String *cname = Getattr(n, "classname") ? Getattr(n, "classname") : classname; - String *membername = Swig_name_member(cname, name); + String *membername = Swig_name_member(nspace, cname, name); String *mangled = Swig_name_mangle(membername); int is_smart_pointer = flags & CWRAP_SMART_POINTER; @@ -1057,7 +1057,7 @@ Node *Swig_directormap(Node *module, String *type) { * This function creates a C wrapper for a C constructor function. * ----------------------------------------------------------------------------- */ -int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags) { +int Swig_ConstructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags) { ParmList *parms; Parm *prefix_args; Parm *p; @@ -1097,7 +1097,7 @@ int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparis String *cres; String *defaultargs = Getattr(n, "defaultargs"); String *code = Getattr(n, "code"); - String *membername = Swig_name_construct(classname); + 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 @@ -1201,7 +1201,7 @@ int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparis * This function creates a C wrapper for a destructor function. * ----------------------------------------------------------------------------- */ -int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags) { +int Swig_DestructorToFunction(Node *n, const_String_or_char_ptr nspace, String *classname, int cplus, int flags) { SwigType *type; Parm *p; @@ -1218,7 +1218,7 @@ int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags) String *cres; String *call; String *membername, *mangled, *code; - membername = Swig_name_destroy(classname); + membername = Swig_name_destroy(nspace, classname); mangled = Swig_name_mangle(membername); code = Getattr(n, "code"); if (code) { @@ -1267,10 +1267,7 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { SwigType *ty; SwigType *type; SwigType *void_type = NewString("void"); - String *membername; - String *mangled; String *self = 0; - String *sname; int varcref = flags & CWRAP_NATURAL_VAR; @@ -1284,10 +1281,6 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { name = Getattr(n, "name"); type = Getattr(n, "type"); - sname = Swig_name_set(name); - membername = Swig_name_member(classname, sname); - mangled = Swig_name_mangle(membername); - t = NewString(classname); SwigType_add_pointer(t); parms = NewParm(t, "self", n); @@ -1310,6 +1303,11 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { 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"); @@ -1317,8 +1315,12 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { call = Swig_cfunction_call(mangled, parms); cres = NewStringf("%s;", call); Setattr(n, "wrap:action", cres); - Delete(call); + 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); @@ -1331,9 +1333,6 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { Delete(parms); Delete(ty); Delete(void_type); - Delete(membername); - Delete(sname); - Delete(mangled); Delete(self); return SWIG_OK; } @@ -1350,10 +1349,7 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { SwigType *t; SwigType *ty; SwigType *type; - String *membername; - String *mangled; String *self = 0; - String *gname; int varcref = flags & CWRAP_NATURAL_VAR; @@ -1373,10 +1369,6 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { name = Getattr(n, "name"); type = Getattr(n, "type"); - gname = Swig_name_get(name); - membername = Swig_name_member(classname, gname); - mangled = Swig_name_mangle(membername); - t = NewString(classname); SwigType_add_pointer(t); parms = NewParm(t, "self", n); @@ -1388,8 +1380,12 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { 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"); @@ -1397,8 +1393,12 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { call = Swig_cfunction_call(mangled, parms); cres = Swig_cresult(ty, "result", 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, "result", call); @@ -1410,9 +1410,6 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { Setattr(n, "parms", parms); Delete(parms); Delete(ty); - Delete(membername); - Delete(gname); - Delete(mangled); return SWIG_OK; } @@ -1438,7 +1435,7 @@ int Swig_VarsetToFunction(Node *n, int flags) { parms = NewParm(ty, name, n); if (flags & CWRAP_EXTEND) { - String *sname = Swig_name_set(name); + 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); @@ -1492,7 +1489,7 @@ int Swig_VargetToFunction(Node *n, int flags) { ty = Swig_wrapped_var_type(type, varcref); if (flags & CWRAP_EXTEND) { - String *sname = Swig_name_get(name); + String *sname = Swig_name_get(0, name); String *mangled = Swig_name_mangle(sname); call = Swig_cfunction_call(mangled, 0); cres = Swig_cresult(ty, "result", call); diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index 19050fd51..f0a9155eb 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -17,6 +17,15 @@ char cvsroot_misc_c[] = "$Id$"; #include #include #include +#include +#include + +#ifdef _WIN32 +#include +#ifndef S_ISDIR +#define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR) +#endif +#endif static char *fake_version = 0; @@ -135,11 +144,79 @@ String *Swig_strip_c_comments(const String *s) { 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 NULL or empty to indicate current directory. + * ----------------------------------------------------------------------------- */ + +String *Swig_new_subdirectory(String *basedirectory, String *subdirectory) { + String *error = 0; + struct stat st; + int current_directory = basedirectory ? (Len(basedirectory) == 0 ? 1 : 0) : 0; + + if (current_directory || is_directory(basedirectory)) { + Iterator it; + String *dir = basedirectory ? NewString(basedirectory) : NewString(""); + List *subdirs = Split(subdirectory, SWIG_FILE_DELIMITER[0], INT_MAX); + + for (it = First(subdirs); it.item; it = Next(it)) { + int statdir; + String *subdirectory = it.item; + Printf(dir, "%s", subdirectory); + statdir = stat(Char(dir), &st); + if (statdir == 0) { + Printf(dir, SWIG_FILE_DELIMITER); + if (S_ISDIR(st.st_mode)) { + continue; + } else { + error = NewStringf("Cannot create directory %s", dir); + break; + } + } else { +#ifdef _WIN32 + int result = _mkdir(Char(dir)); +#else + int result = mkdir(Char(dir), 0777); +#endif + Printf(dir, SWIG_FILE_DELIMITER); + if (result != 0 && errno != EEXIST) { + error = NewStringf("Cannot create directory %s", dir); + break; + } + } + } + } 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 filenames on non-unix systems + * Corrects filename paths by removing duplicate delimeters and on non-unix + * systems use the correct delimeter across the whole name. * ----------------------------------------------------------------------------- */ void Swig_filename_correct(String *filename) { @@ -152,6 +229,9 @@ void Swig_filename_correct(String *filename) { /* 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)) { + } } /* ----------------------------------------------------------------------------- @@ -163,7 +243,9 @@ void Swig_filename_correct(String *filename) { String *Swig_filename_escape(String *filename) { String *adjusted_filename = Copy(filename); #if defined(_WIN32) /* Note not on Cygwin else filename is displayed with double '/' */ - Replaceall(adjusted_filename, "\\\\", "\\"); /* remove double '\' in case any already present */ + /* remove all double '\' in case any already present */ + while (Replaceall(adjusted_filename, "\\\\", "\\")) { + } Replaceall(adjusted_filename, "\\", "\\\\"); #endif return adjusted_filename; @@ -1010,7 +1092,7 @@ String *Swig_string_strip(String *s) { } else { const char *cs = Char(s); const char *ce = Strchr(cs, ']'); - if (*cs != '[' || ce == NULL) { + if (*cs != '[' || !ce) { ns = NewString(s); } else { String *fmt = NewStringf("%%.%ds", ce-cs-1); diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index 08c4f6b5d..07e42f2d4 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -9,6 +9,15 @@ * 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 * ----------------------------------------------------------------------------- */ char cvsroot_naming_c[] = "$Id$"; @@ -125,6 +134,23 @@ static int name_mangle(String *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() * @@ -172,7 +198,7 @@ String *Swig_name_wrapper(const_String_or_char_ptr fname) { * Returns the name of a class method. * ----------------------------------------------------------------------------- */ -String *Swig_name_member(const_String_or_char_ptr classname, const_String_or_char_ptr mname) { +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 *f; String *rclassname; @@ -184,7 +210,7 @@ String *Swig_name_member(const_String_or_char_ptr classname, const_String_or_cha naming_hash = NewHash(); f = Getattr(naming_hash, "member"); if (!f) { - Append(r, "%c_%m"); + Append(r, "%n%c_%m"); } else { Append(r, f); } @@ -192,8 +218,9 @@ String *Swig_name_member(const_String_or_char_ptr classname, const_String_or_cha 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", mname, DOH_REPLACE_ANY); + Replace(r, "%m", membername, DOH_REPLACE_ANY); /* name_mangle(r); */ Delete(rclassname); return r; @@ -205,7 +232,7 @@ String *Swig_name_member(const_String_or_char_ptr classname, const_String_or_cha * Returns the name of the accessor function used to get a variable. * ----------------------------------------------------------------------------- */ -String *Swig_name_get(const_String_or_char_ptr vname) { +String *Swig_name_get(const_String_or_char_ptr nspace, const_String_or_char_ptr vname) { String *r; String *f; @@ -218,10 +245,12 @@ String *Swig_name_get(const_String_or_char_ptr vname) { naming_hash = NewHash(); f = Getattr(naming_hash, "get"); if (!f) { - Append(r, "%v_get"); + Append(r, "%n%v_get"); } else { Append(r, f); } + + replace_nspace(r, nspace); Replace(r, "%v", vname, DOH_REPLACE_ANY); /* name_mangle(r); */ return r; @@ -233,7 +262,7 @@ String *Swig_name_get(const_String_or_char_ptr vname) { * Returns the name of the accessor function used to set a variable. * ----------------------------------------------------------------------------- */ -String *Swig_name_set(const_String_or_char_ptr vname) { +String *Swig_name_set(const_String_or_char_ptr nspace, const_String_or_char_ptr vname) { String *r; String *f; @@ -242,10 +271,12 @@ String *Swig_name_set(const_String_or_char_ptr vname) { naming_hash = NewHash(); f = Getattr(naming_hash, "set"); if (!f) { - Append(r, "%v_set"); + Append(r, "%n%v_set"); } else { Append(r, f); } + + replace_nspace(r, nspace); Replace(r, "%v", vname, DOH_REPLACE_ANY); /* name_mangle(r); */ return r; @@ -257,7 +288,7 @@ String *Swig_name_set(const_String_or_char_ptr vname) { * Returns the name of the accessor function used to create an object. * ----------------------------------------------------------------------------- */ -String *Swig_name_construct(const_String_or_char_ptr classname) { +String *Swig_name_construct(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { String *r; String *f; String *rclassname; @@ -269,7 +300,7 @@ String *Swig_name_construct(const_String_or_char_ptr classname) { naming_hash = NewHash(); f = Getattr(naming_hash, "construct"); if (!f) { - Append(r, "new_%c"); + Append(r, "new_%n%c"); } else { Append(r, f); } @@ -278,6 +309,8 @@ String *Swig_name_construct(const_String_or_char_ptr classname) { 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; @@ -290,7 +323,7 @@ String *Swig_name_construct(const_String_or_char_ptr classname) { * Returns the name of the accessor function used to copy an object. * ----------------------------------------------------------------------------- */ -String *Swig_name_copyconstructor(const_String_or_char_ptr classname) { +String *Swig_name_copyconstructor(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { String *r; String *f; String *rclassname; @@ -302,7 +335,7 @@ String *Swig_name_copyconstructor(const_String_or_char_ptr classname) { naming_hash = NewHash(); f = Getattr(naming_hash, "copy"); if (!f) { - Append(r, "copy_%c"); + Append(r, "copy_%n%c"); } else { Append(r, f); } @@ -312,6 +345,7 @@ String *Swig_name_copyconstructor(const_String_or_char_ptr classname) { cname = strchr(cname, ' ') + 1; } + replace_nspace(r, nspace); Replace(r, "%c", cname, DOH_REPLACE_ANY); Delete(rclassname); return r; @@ -323,7 +357,7 @@ String *Swig_name_copyconstructor(const_String_or_char_ptr classname) { * Returns the name of the accessor function used to destroy an object. * ----------------------------------------------------------------------------- */ -String *Swig_name_destroy(const_String_or_char_ptr classname) { +String *Swig_name_destroy(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { String *r; String *f; String *rclassname; @@ -334,7 +368,7 @@ String *Swig_name_destroy(const_String_or_char_ptr classname) { naming_hash = NewHash(); f = Getattr(naming_hash, "destroy"); if (!f) { - Append(r, "delete_%c"); + Append(r, "delete_%n%c"); } else { Append(r, f); } @@ -343,6 +377,8 @@ String *Swig_name_destroy(const_String_or_char_ptr classname) { 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; @@ -355,7 +391,7 @@ String *Swig_name_destroy(const_String_or_char_ptr classname) { * Returns the name of the accessor function used to disown an object. * ----------------------------------------------------------------------------- */ -String *Swig_name_disown(const_String_or_char_ptr classname) { +String *Swig_name_disown(const_String_or_char_ptr nspace, const_String_or_char_ptr classname) { String *r; String *f; String *rclassname; @@ -366,7 +402,7 @@ String *Swig_name_disown(const_String_or_char_ptr classname) { naming_hash = NewHash(); f = Getattr(naming_hash, "disown"); if (!f) { - Append(r, "disown_%c"); + Append(r, "disown_%n%c"); } else { Append(r, f); } @@ -375,6 +411,8 @@ String *Swig_name_disown(const_String_or_char_ptr classname) { 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; diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c index 0eb82651a..446a68eb7 100644 --- a/Source/Swig/scanner.c +++ b/Source/Swig/scanner.c @@ -1390,6 +1390,10 @@ int Scanner_skip_balanced(Scanner * s, int startchar, int endchar) { state = 11; else if (c == '*') state = 12; + else if (c == startchar) { + state = 0; + num_levels++; + } else state = 0; break; diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index 989d59259..32946ead5 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -279,233 +279,187 @@ int SwigType_issimple(SwigType *t) { } /* ----------------------------------------------------------------------------- - * SwigType_default() + * SwigType_default_create() * - * Create the default string for this datatype. This takes a type and strips it - * down to its most primitive form--resolving all typedefs and removing operators. + * 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: a().SWIGTYPE - * Types: SWIGTYPE - * MemberPointer: m(CLASS).SWIGTYPE - * Enums: enum SWIGTYPE + * 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 * - * Note: if this function is applied to a primitive type, it returns NULL. This - * allows recursive application for special types like arrays. + * 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 * ----------------------------------------------------------------------------- */ -#ifdef SWIG_DEFAULT_CACHE -static Hash *default_cache = 0; -#endif +SwigType *SwigType_default_create(SwigType *ty) { + SwigType *r = 0; + List *l; + Iterator it; + int numitems; -#define SWIG_NEW_TYPE_DEFAULT -/* The new default type resolution method: + if (!SwigType_isvarargs(ty)) { + SwigType *t = SwigType_typedef_resolve_all(ty); + r = NewStringEmpty(); + l = SwigType_split(t); + numitems = Len(l); -1.- It preserves the original mixed types, then it goes 'backward' - first deleting the qualifier, then the inner types - - 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 + 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); + } + } - 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 + Delete(l); + Delete(t); + } - 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 -*/ + return r; +} -static -void SwigType_add_default(String *def, SwigType *nr) { - if (Strcmp(nr, "SWIGTYPE") == 0) { - Append(def, "SWIGTYPE"); - } else { - String *q = SwigType_isqualifier(nr) ? SwigType_pop(nr) : 0; - if (q && strstr(Char(nr), "SWIGTYPE")) { - Append(def, nr); - } else { - String *nd = SwigType_default(nr); - if (nd) { - String *bdef = nd; - if (q) { - bdef = NewStringf("%s%s", q, nd); - if ((Strcmp(nr, bdef) == 0)) { - Delete(bdef); - bdef = nd; +/* ----------------------------------------------------------------------------- + * 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 unless 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 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(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 { - Delete(nd); + assert(0); } + Setitem(l, numitems-2, deduced_subtype); } - Append(def, bdef); - Delete(bdef); + } 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 { - Append(def, nr); + /* simple type deduction, eg, r.p.p. => r.p. */ + /* also function pointers eg, p.f(ANY). => p. */ + Delitem(l, numitems-2); } - } - Delete(q); - } -} - - -SwigType *SwigType_default(SwigType *t) { - String *r1, *def; - String *r = 0; - char *cr; - -#ifdef SWIG_DEFAULT_CACHE - if (!default_cache) - default_cache = NewHash(); - - r = Getattr(default_cache, t); - if (r) { - return Copy(r); - } -#endif - - if (SwigType_isvarargs(t)) { - return 0; - } - - r = t; - while ((r1 = SwigType_typedef_resolve(r))) { - if (r != t) - Delete(r); - r = r1; - } - if (SwigType_isqualifier(r)) { - String *q; - if (r == t) - r = Copy(t); - q = SwigType_pop(r); - if (strstr(Char(r), "SWIGTYPE")) { - Delete(q); - def = r; - return def; - } - Delete(q); - } - cr = Char(r); - if (strcmp(cr, "p.SWIGTYPE") == 0) { - def = NewString("SWIGTYPE"); - } else if (SwigType_ispointer(r)) { -#ifdef SWIG_NEW_TYPE_DEFAULT - SwigType *nr = Copy(r); - SwigType_del_pointer(nr); - def = SwigType_isfunction(nr) ? NewStringEmpty() : NewString("p."); - SwigType_add_default(def, nr); - Delete(nr); -#else - def = NewString("p.SWIGTYPE"); -#endif - } else if (strcmp(cr, "r.SWIGTYPE") == 0) { - def = NewString("SWIGTYPE"); - } else if (SwigType_isreference(r)) { -#ifdef SWIG_NEW_TYPE_DEFAULT - SwigType *nr = Copy(r); - SwigType_del_reference(nr); - def = NewString("r."); - SwigType_add_default(def, nr); - Delete(nr); -#else - def = NewString("r.SWIGTYPE"); -#endif - } else if (SwigType_isrvalue_reference(r)) { -#ifdef SWIG_NEW_TYPE_DEFAULT - SwigType *nr = Copy(r); - SwigType_del_rvalue_reference(nr); - def = NewString("z."); - SwigType_add_default(def, nr); - Delete(nr); -#else - def = NewString("z.SWIGTYPE"); -#endif - } else if (SwigType_isarray(r)) { - if (strcmp(cr, "a().SWIGTYPE") == 0) { - def = NewString("p.SWIGTYPE"); - } else if (strcmp(cr, "a(ANY).SWIGTYPE") == 0) { - def = NewString("a().SWIGTYPE"); } else { - int i, empty = 0; - int ndim = SwigType_array_ndim(r); - SwigType *nr = Copy(r); - for (i = 0; i < ndim; i++) { - String *dim = SwigType_array_getdim(r, i); - if (!Len(dim)) { - char *c = Char(nr); - empty = strstr(c, "a(ANY).") != c; - } - Delete(dim); - } - if (empty) { - def = NewString("a()."); + if (is_enum) { + /* enum deduction, enum SWIGTYPE => SWIGTYPE */ + Setitem(l, numitems-1, NewString("SWIGTYPE")); } else { - def = NewString("a(ANY)."); + /* delete the only item, we are done with deduction */ + Delitem(l, 0); } -#ifdef SWIG_NEW_TYPE_DEFAULT - SwigType_del_array(nr); - SwigType_add_default(def, nr); -#else - Append(def, "SWIGTYPE"); -#endif - Delete(nr); - } - } else if (SwigType_ismemberpointer(r)) { - if (strcmp(cr, "m(CLASS).SWIGTYPE") == 0) { - def = NewString("p.SWIGTYPE"); - } else { - def = NewString("m(CLASS).SWIGTYPE"); - } - } else if (SwigType_isenum(r)) { - if (strcmp(cr, "enum SWIGTYPE") == 0) { - def = NewString("SWIGTYPE"); - } else { - def = NewString("enum SWIGTYPE"); - } - } else if (SwigType_isfunction(r)) { - if (strcmp(cr, "f(ANY).SWIGTYPE") == 0) { - def = NewString("p.SWIGTYPE"); - } else { - def = NewString("p.f(ANY).SWIGTYPE"); } } else { - def = NewString("SWIGTYPE"); + assert(0); } - if (r != t) + + for (it = First(l); it.item; it = Next(it)) { + Append(r, it.item); + } + + if (Len(r) == 0) { Delete(r); - if (Equal(def, t)) { - Delete(def); - def = 0; + r = 0; } -#ifdef SWIG_DEFAULT_CACHE - /* The cache produces strange results, see enum_template.i case */ - if (def) { - String *cdef = Copy(def); - Setattr(default_cache, t, cdef); - Delete(cdef); - } -#endif - /* Printf(stderr,"type : def %s : %s\n", t, def); */ - - return def; + Delete(l); + return r; } + /* ----------------------------------------------------------------------------- * SwigType_namestr() * diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 8d66b6672..dc65d9b0d 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -11,8 +11,6 @@ * Header file for the SWIG core. * ----------------------------------------------------------------------------- */ -/* $Id$ */ - #ifndef SWIGCORE_H_ #define SWIGCORE_H_ @@ -37,6 +35,10 @@ extern "C" { #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; @@ -162,6 +164,7 @@ extern "C" { extern int SwigType_isenum(SwigType *t); extern int SwigType_check_decl(SwigType *t, const_String_or_char_ptr decl); extern SwigType *SwigType_strip_qualifiers(SwigType *t); + extern SwigType *SwigType_strip_single_qualifier(SwigType *t); extern SwigType *SwigType_functionpointer_decompose(SwigType *t); extern String *SwigType_base(const SwigType *t); extern String *SwigType_namestr(const SwigType *t); @@ -175,6 +178,8 @@ extern "C" { extern void SwigType_array_setdim(SwigType *t, int n, const_String_or_char_ptr rep); extern SwigType *SwigType_array_type(SwigType *t); extern String *SwigType_default(SwigType *t); + extern SwigType *SwigType_default_create(SwigType *ty); + extern SwigType *SwigType_default_deduce(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(SwigType *t, int ltmap); @@ -219,6 +224,7 @@ extern "C" { 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); @@ -266,13 +272,13 @@ extern int ParmList_is_compactdefargs(ParmList *p); 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 classname, const_String_or_char_ptr mname); - extern String *Swig_name_get(const_String_or_char_ptr vname); - extern String *Swig_name_set(const_String_or_char_ptr vname); - extern String *Swig_name_construct(const_String_or_char_ptr classname); - extern String *Swig_name_copyconstructor(const_String_or_char_ptr classname); - extern String *Swig_name_destroy(const_String_or_char_ptr classname); - extern String *Swig_name_disown(const_String_or_char_ptr classname); + 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); @@ -303,6 +309,7 @@ extern int ParmList_is_compactdefargs(ParmList *p); 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 void Swig_filename_unescape(String *filename); @@ -353,9 +360,9 @@ extern int ParmList_is_compactdefargs(ParmList *p); /* --- Transformations --- */ - extern int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *director_type, int is_director); - extern int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags); - extern int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags); + 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); + 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); diff --git a/Source/Swig/swigfile.h b/Source/Swig/swigfile.h index 632e821e2..cdf23cddc 100644 --- a/Source/Swig/swigfile.h +++ b/Source/Swig/swigfile.h @@ -11,8 +11,6 @@ * File handling functions in the SWIG core * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9603 2006-12-05 21:47:01Z beazley $ */ - 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); diff --git a/Source/Swig/swigopt.h b/Source/Swig/swigopt.h index 586f8bbc4..543bfb819 100644 --- a/Source/Swig/swigopt.h +++ b/Source/Swig/swigopt.h @@ -11,8 +11,6 @@ * Header file for the SWIG command line processing functions * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9622 2006-12-19 03:49:17Z beazley $ */ - extern void Swig_init_args(int argc, char **argv); extern void Swig_mark_arg(int n); extern int Swig_check_marked(int n); diff --git a/Source/Swig/swigparm.h b/Source/Swig/swigparm.h index 060225f6b..70a39390e 100644 --- a/Source/Swig/swigparm.h +++ b/Source/Swig/swigparm.h @@ -12,8 +12,6 @@ * parameter lists. * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9629 2006-12-30 18:27:47Z beazley $ */ - /* Individual parameters */ extern Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *file_line_node); extern Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name); diff --git a/Source/Swig/swigscan.h b/Source/Swig/swigscan.h index d52124c60..b07812fbe 100644 --- a/Source/Swig/swigscan.h +++ b/Source/Swig/swigscan.h @@ -11,8 +11,6 @@ * C/C++ scanner. * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9633 2007-01-10 23:43:07Z beazley $ */ - typedef struct Scanner Scanner; extern Scanner *NewScanner(void); diff --git a/Source/Swig/swigtree.h b/Source/Swig/swigtree.h index 6799398c9..5decb79e3 100644 --- a/Source/Swig/swigtree.h +++ b/Source/Swig/swigtree.h @@ -13,8 +13,6 @@ * and function names are meant to be similar. * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9622 2006-12-19 03:49:17Z beazley $ */ - /* Macros to traverse the DOM tree */ #define nodeType(x) Getattr(x,"nodeType") diff --git a/Source/Swig/swigwrap.h b/Source/Swig/swigwrap.h index b1f596f72..e44cb5344 100644 --- a/Source/Swig/swigwrap.h +++ b/Source/Swig/swigwrap.h @@ -11,8 +11,6 @@ * Functions related to wrapper objects. * ----------------------------------------------------------------------------- */ -/* $Id: swig.h 9635 2007-01-12 01:44:16Z beazley $ */ - typedef struct Wrapper { Hash *localh; String *def; diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index 73a136a4a..b5e114683 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -353,6 +353,21 @@ String *Swig_symbol_qualifiedscopename(Symtab *symtab) { 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() * diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 47e833bb6..5c8735e46 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -674,7 +674,7 @@ static Hash *typemap_search_helper(int debug_display, Hash *tm, const String *tm 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 match */ + 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) @@ -698,11 +698,11 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type Hash *backup = 0; SwigType *primitive = 0; SwigType *ctype = 0; + SwigType *ctype_unstripped = 0; int ts; int isarray; const String *cname = 0; const String *cqualifiedname = 0; - SwigType *unstripped = 0; String *tm_method = typemap_method_name(tmap_method); int debug_display = (in_typemap_search_multi == 0) && typemap_search_debug; @@ -718,12 +718,13 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type Delete(typestr); } while (ts >= 0) { - ctype = type; + ctype = Copy(type); + ctype_unstripped = Copy(ctype); while (ctype) { /* Try to get an exact type-match */ tm = get_typemap(ts, ctype); result = typemap_search_helper(debug_display, tm, tm_method, ctype, cqualifiedname, cname, &backup); - if (result) + if (result && Getattr(result, "code")) goto ret_result; { @@ -733,7 +734,7 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type tm = get_typemap(ts, template_prefix); result = typemap_search_helper(debug_display, tm, tm_method, template_prefix, cqualifiedname, cname, &backup); Delete(template_prefix); - if (result) + if (result && Getattr(result, "code")) goto ret_result; } } @@ -747,47 +748,43 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type tm = get_typemap(ts, noarrays); result = typemap_search_helper(debug_display, tm, tm_method, noarrays, cqualifiedname, cname, &backup); Delete(noarrays); - if (result) + if (result && Getattr(result, "code")) goto ret_result; } - /* No match so far. If the type is unstripped, we'll strip its - qualifiers and check. Otherwise, we'll try to resolve a typedef */ - - if (!unstripped) { - unstripped = ctype; - ctype = SwigType_strip_qualifiers(ctype); - if (!Equal(ctype, unstripped)) - continue; /* Types are different */ - Delete(ctype); - ctype = unstripped; - unstripped = 0; - } + /* 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. */ { - String *octype; - if (unstripped) { - Delete(ctype); - ctype = unstripped; - unstripped = 0; + SwigType *oldctype = ctype; + ctype = SwigType_strip_single_qualifier(oldctype); + if (!Equal(ctype, oldctype)) { + Delete(oldctype); + continue; } - octype = ctype; - ctype = SwigType_typedef_resolve(ctype); - if (octype != type) - Delete(octype); + Delete(oldctype); + } + + /* Once all qualifiers are stripped try resolve a typedef */ + { + SwigType *oldctype = ctype; + ctype = SwigType_typedef_resolve(ctype_unstripped); + Delete(oldctype); + 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(type); + primitive = SwigType_default_create(type); while (primitive) { tm = get_typemap(ts, primitive); result = typemap_search_helper(debug_display, tm, tm_method, primitive, cqualifiedname, cname, &backup); - if (result) + if (result && Getattr(result, "code")) goto ret_result; { - SwigType *nprim = SwigType_default(primitive); + SwigType *nprim = SwigType_default_deduce(primitive); Delete(primitive); primitive = nprim; } @@ -802,12 +799,10 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type ret_result: Delete(primitive); - if ((unstripped) && (unstripped != type)) - Delete(unstripped); if (matchtype) *matchtype = Copy(ctype); - if (type != ctype) - Delete(ctype); + Delete(ctype); + Delete(ctype_unstripped); return result; } @@ -1945,10 +1940,16 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper #ifdef SWIG_DEBUG Printf(stdout, "Swig_typemap_attach_parms: embedded\n"); #endif - if (!already_substituting) { - already_substituting = 1; + if (already_substituting < 10) { + 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); + } Swig_typemap_attach_parms(tmap_method, to_match_parms, f); - already_substituting = 0; + already_substituting--; /* Look for the typemap code */ attr = NewStringf("tmap:%s", tmap_method); @@ -1979,10 +1980,11 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper } Delete(attr); } else { - /* simple recursive call check, but prevents using an embedded typemap that contains another embedded typemap */ + /* 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), "Recursive $typemap calls not supported - %s\n", dtypemap); + Swig_error(Getfile(s), Getline(s), "Likely recursive $typemap calls containing %s. Use -debug-tmsearch to debug.\n", dtypemap); Delete(dtypemap); } syntax_error = 0; diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c index 23bc7b924..ffb802089 100644 --- a/Source/Swig/typeobj.c +++ b/Source/Swig/typeobj.c @@ -51,6 +51,9 @@ char cvsroot_typeobj_c[] = "$Id$"; * 'q(str).' = Qualifier (such as const or volatile) (const, volatile) * 'm(qual).' = Pointer to member (qual::*) * + * 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". @@ -181,6 +184,9 @@ SwigType *SwigType_del_element(SwigType *t) { * SwigType_pop() * * Pop one type element off the type. + * Example: t in: q(const).p.Integer + * t out: p.Integer + * result: q(const). * ----------------------------------------------------------------------------- */ SwigType *SwigType_pop(SwigType *t) { @@ -1158,3 +1164,62 @@ SwigType *SwigType_strip_qualifiers(SwigType *t) { } 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(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/Source/Swig/typesys.c b/Source/Swig/typesys.c index 3e9429f75..a72ce5198 100644 --- a/Source/Swig/typesys.c +++ b/Source/Swig/typesys.c @@ -79,7 +79,7 @@ char cvsroot_typesys_c[] = "$Id$"; * * class Bar : public Foo { * void blah(Integer x); - * } + * }; * * The argument type of Bar::blah will be set to Foo::Integer. * @@ -1782,7 +1782,7 @@ void SwigType_inherit_equiv(File *out) { continue; } - /* This type has subclasses. We now need to walk through these subtypes and generate pointer converion functions */ + /* This type has subclasses. We now need to walk through these subtypes and generate pointer conversion functions */ rh = Getattr(r_resolved, rk.key); rlist = NewList(); diff --git a/Tools/WAD/CHANGES b/Tools/WAD/CHANGES deleted file mode 100644 index 186d15e7b..000000000 --- a/Tools/WAD/CHANGES +++ /dev/null @@ -1,25 +0,0 @@ -WAD 0.3 - June 2, 2002 - - - Added to the SWIG distribution. - -WAD 0.2 - June 24, 2001 - - - Minor changes. Added the wadtrace file - - - Put everything under the LGPL. - -WAD 0.1 - March 23, 2001 - - - Extensive changes to WAD core. WAD now builds an exception - object that can be queried and manipulated after a fault - occurs. - - - Better collection of debugging information. WAD is now - able to determine basic datatypes and other information - from stabs data. - - - Better reliability overall. - -WAD 0.0 - January, 2001 - -beazley - Initial "release". Not much of a release really. diff --git a/Tools/WAD/COPYING b/Tools/WAD/COPYING deleted file mode 100644 index b1e3f5a26..000000000 --- a/Tools/WAD/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -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 this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser 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 Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/Tools/WAD/HACK b/Tools/WAD/HACK deleted file mode 100644 index dfece608d..000000000 --- a/Tools/WAD/HACK +++ /dev/null @@ -1,78 +0,0 @@ -The WAD Developers Guide - -David Beazley (beazley@cs.uchicago.edu) - -$Id$ - -1. Introduction - -This short document is intended for anyone who feels inclined to work -on WAD and make improvements. It is by no means complete. However, -it contains random commentary on the current implementation. - -2. A brief word on the execution environment - -Because WAD is embedded in the same application it is intended to -debug, it must take an extremely conservative approach to its own -execution environment. Specifically, it can not rely upon the correct -operation of C library--especially with respect to memory management -and other basic operations. Because of this, the implementation of -WAD makes every effort to be as self-contained as possible--thus -minimizing its exposure to corrupted libraries in the faulting -application. Closely related to this, WAD does not rely on any -third-party libraries (e.g., libbfd) since it is almost impossible to -fully verify the way in which such libraries might use other programming -libraries. - -With that said, you might keep the following rules in mind: - - rule 1: Trust nothing--it might be broken. - rule 2: When in doubt, see rule 1. - -(Of course, we can probably get away with assuming that the OS isn't -hosed). - -3. Memory management - -There are two problems here: first, the dynamic memory -allocator may be corrupted or broken (e.g., as might occur when -you double-free memory or free memory not allocated by malloc). -Second, the WAD signal handler prefers to execute own on its own -signal handling stack. This stack is of limited size so it is not -a reliable place to put large amounts of data. - -Small buffers and scratch areas are managed through the use of static -variables allocated in the WAD data-segment. - -For dynamic memory management, WAD provides its own memory allocator -in the function wad_malloc(). This function allocates memory by using -mmap() to grab anonymous memory regions (mapped to /dev/zero). This -memory is currently allocated in chunks of 64Kbytes as needed. - -To simplify the implementation and prevent potential memory problems -in WAD itself, WAD never releases the memory that it allocates. There -is no wad_free() operation nor is there any way to release all of the -memory previously allocated. - -Although memory is never released, WAD tries to intern commonly used -strings. An internal string hash is built as WAD runs and in most -cases, each string is mapped to a single instance of the string in -this hash table. The function wad_string_lookup(char *s) is used to -return a pointer to the string s in the hash table. If no entry -exists, it is created and a pointer is returned. - -4. I/O - -It is probably a bad idea to use buffered I/O with WAD. This may -result in implicit calls to malloc() and related functions. - - - - - - - - - - - diff --git a/Tools/WAD/Include/wad.h b/Tools/WAD/Include/wad.h deleted file mode 100644 index 9a5007394..000000000 --- a/Tools/WAD/Include/wad.h +++ /dev/null @@ -1,269 +0,0 @@ -/* ----------------------------------------------------------------------------- - * wad.h - * - * WAD header file (obviously) - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2001. University of Chicago. All rights reserved. - * - * $Id$ - * ----------------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WAD_SOLARIS -#include - -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - /* Core datatypes */ - - typedef int int32; - typedef unsigned uint32; - typedef short int16; - typedef unsigned short uint16; - typedef signed char int8; - typedef unsigned char uint8; - - -#ifndef MAX_PATH -#define MAX_PATH 1024 -#endif - -#define WAD_SRC_WINDOW 2 - -/* --- Low level memory management functions --- */ - -extern int wad_memory_init(); -extern void *wad_malloc(int nbytes); -extern char *wad_strdup(const char *c); -extern void wad_memory_debug(); -extern void wad_memcpy(void *t, const void *s, unsigned len); - - /* --- Low level string handling --- */ - -extern char *wad_string_lookup(char *s); -extern void wad_string_debug(); -extern char *wad_strcpy(char *t, const char *s); -extern char *wad_strcat(char *t, const char *s); -extern int wad_strlen(const char *s); - -/* --- I/O, Debugging --- */ - -extern void wad_printf(const char *fmt, ...); -extern char *wad_format_hex(unsigned long u, int leading); -extern char *wad_format_unsigned(unsigned long u, int width); -extern char *wad_format_signed(long s, int width); - -/* --- Memory segments --- */ -typedef struct WadSegment { - char *base; /* Base address for symbol lookup */ - char *vaddr; /* Virtual address start */ - unsigned long size; /* Size of the segment (bytes) */ - unsigned long offset; /* Offset into mapped object */ - char *mapname; /* Filename mapped to this region */ - char *mappath; /* Full path to mapname */ - struct WadSegment *next; /* Next segment */ -} WadSegment; - -extern int wad_segment_read(); -extern WadSegment *wad_segment_find(void *vaddr); -extern int wad_segment_valid(void *vaddr); - -/* --- Object files --- */ -typedef struct WadObjectFile { - void *ptr; /* Pointer to data */ - int len; /* Length of data */ - int type; /* Type of the object file */ - char *path; /* Path name of this object */ - struct WadObjectFile *next; -} WadObjectFile; - -extern void wad_object_reset(); -extern WadObjectFile *wad_object_load(const char *path); -extern int wad_file_check(void *); - -#define SYM_LOCAL 1 -#define SYM_GLOBAL 2 - -/* Signal handling */ -extern void wad_init(); -extern void wad_signalhandler(int, siginfo_t *, void *); -extern void wad_signal_init(); -extern void wad_signal_clear(); -extern void wad_set_return(const char *name, long value); -extern void wad_set_return_value(long value); -extern void wad_set_return_func(void (*f)(void)); - -typedef struct WadLocal { - char *name; /* Name of the local */ - void *ptr; /* Pointer to the actual data (if known) */ - int size; /* Size of the data (if known) */ - int type; /* Data type */ - - /* Debugging information */ - - int loc; /* Location: register or stack */ - int stack; /* location on the stack */ - int reg; /* Register number */ - int line; /* Line number where defined */ - struct WadLocal *next; -} WadLocal; - -#define PARM_REGISTER 1 -#define PARM_STACK 2 - -/* Type codes for local variables */ - -#define WAD_TYPE_UNKNOWN 0 -#define WAD_TYPE_INT32 1 -#define WAD_TYPE_INT16 2 -#define WAD_TYPE_INT8 3 -#define WAD_TYPE_INT64 4 -#define WAD_TYPE_UINT32 5 -#define WAD_TYPE_UINT16 6 -#define WAD_TYPE_UINT8 7 -#define WAD_TYPE_UINT64 8 -#define WAD_TYPE_FLOAT 9 -#define WAD_TYPE_DOUBLE 10 -#define WAD_TYPE_POINTER 11 -#define WAD_TYPE_CHAR 12 - -extern long wad_local_as_long(WadLocal *loc); -extern double wad_local_as_double(WadLocal *loc); - -/* Data structure containing information about each stack frame */ - -typedef struct WadFrame { - long frameno; /* Frame number */ - struct WadFrame *next; /* Next frame up the stack */ - struct WadFrame *prev; /* Previous frame down the stack */ - - /* Stack context information */ - long pc; /* Real PC */ - long sp; /* Real SP */ - long fp; /* Real FP */ - char *stack; /* Pointer to where a copy of the stack frame is stored */ - int stack_size; /* Stack frame size (fp-sp) */ - - /* Loading information. Contains information from /proc as well as a pointer to - the executable or shared library in which the PC is located */ - - WadSegment *segment; /* Memory segment corresponding to PC */ - WadObjectFile *object; /* Object file corresponding to PC */ - - /* Symbol table information for PC */ - - char *sym_name; /* Symbol name */ - int sym_nlen; /* Symbol name length */ - char *sym_file; /* Source file (if any) */ - unsigned long sym_base; /* Symbol base address */ - unsigned long sym_size; /* Symbol size */ - int sym_type; /* Symbol type */ - int sym_bind; /* Symbol binding */ - - /* Location information */ - char *loc_objfile; /* Object filename */ - char *loc_srcfile; /* Source filename */ - int loc_line; /* Source line */ - - /* Debugging information */ - int debug_check; /* Checked debugging information */ - int debug_nargs; /* Number of arguments */ - WadLocal *debug_args; /* Arguments */ - WadLocal *debug_lastarg; /* Last argument */ - int debug_nlocals; /* Number of locals */ - WadLocal *debug_locals; /* Local variables */ - WadLocal *debug_lastlocal; /* Last local */ - - /* Output strings */ - char *debug_str; /* Debugging string */ - char *debug_srcstr; /* Source string */ - - int last; /* Last frame flag */ -} WadFrame; - -extern WadFrame *wad_stack_trace(unsigned long, unsigned long, unsigned long); -extern void wad_stack_debug(WadFrame *f); - -extern char *wad_strip_dir(char *); -extern void wad_default_callback(int signo, WadFrame *frame, char *ret); -extern void wad_dump_trace(int fd, int signo, WadFrame *frame, char *ret); - -extern void wad_set_callback(void (*h)(int, WadFrame *, char *)); -extern char *wad_load_source(char *, int line); -extern void wad_release_source(); -extern void wad_release_trace(); -extern long wad_steal_arg(WadFrame *f, char *symbol, int argno, int *error); -extern long wad_steal_outarg(WadFrame *f, char *symbol, int argno, int *error); - -extern char *wad_arg_string(WadFrame *f); - -typedef struct { - char name[128]; - long value; -} WadReturnFunc; - -extern void wad_set_returns(WadReturnFunc *rf); -extern WadReturnFunc *wad_check_return(const char *name); - -extern int wad_search_stab(void *stab, int size, char *stabstr, WadFrame *f); - -extern void wad_find_object(WadFrame *f); -extern void wad_find_symbol(WadFrame *f); -extern void wad_find_debug(WadFrame *f); -extern void wad_build_vars(WadFrame *f); -extern char *wad_format_var(WadLocal *l); - -extern void wad_debug_make_strings(WadFrame *f); - -/* --- Debugging Interface --- */ - -#define DEBUG_SEGMENT 0x1 -#define DEBUG_SYMBOL 0x2 -#define DEBUG_STABS 0x4 -#define DEBUG_OBJECT 0x8 -#define DEBUG_FILE 0x10 -#define DEBUG_HOLD 0x20 -#define DEBUG_RETURN 0x40 -#define DEBUG_SYMBOL_SEARCH 0x80 -#define DEBUG_INIT 0x100 -#define DEBUG_NOSTACK 0x200 -#define DEBUG_ONESHOT 0x400 -#define DEBUG_STACK 0x800 -#define DEBUG_UNWIND 0x1000 -#define DEBUG_SIGNAL 0x2000 -#define DEBUG_STRING 0x4000 -#define DEBUG_MEMORY 0x8000 - -extern int wad_debug_mode; -extern int wad_heap_overflow; - -#ifdef WAD_LINUX -#define WAD_LITTLE_ENDIAN -#endif -#ifdef WAD_SOLARIS -#define WAD_BIG_ENDIAN -#endif - -#ifdef __cplusplus -} -#endif - - - - diff --git a/Tools/WAD/Makefile.in b/Tools/WAD/Makefile.in deleted file mode 100644 index d76f1179c..000000000 --- a/Tools/WAD/Makefile.in +++ /dev/null @@ -1,46 +0,0 @@ -# Generated automatically from Makefile.in by configure. - -SHELL = /bin/sh -prefix = @prefix@ -execprefix= @exec_prefix@ -LIB = $(execprefix)/lib - -# Location of your Python installation -PYINCLUDE = @PYINCLUDE@ - -# Location of your Tcl installation -TCLINCLUDE = @TCLINCLUDE@ - -# Location of your Perl installation -PERLINCLUDE = @PERL5EXT@ - -all: wad @MAKEPYTHON@ @MAKETCL@ #@MAKEPERL@ - -wad: - @cd Wad; $(MAKE) wad - -python: - @cd Python; $(MAKE) SINCLUDE='$(PYINCLUDE)' python - -tcl: - @cd Tcl; $(MAKE) SINCLUDE='$(TCLINCLUDE)' tcl - -perl: - @cd Wad; $(MAKE) SINCLUDE='$(PERLINCLUDE)' perl - -install: - cp libwad*.so $(LIB) - chmod a+rx $(LIB)/libwad*.so - -semi: - @cd Wad; $(MAKE) semi - @cd Python; $(MAKE) semi - @cd Tcl; $(MAKE) semi - -clean: - @cd Wad; $(MAKE) clean - @cd Python; $(MAKE) clean - @cd Tcl; $(MAKE) clean - @cd Test; $(MAKE) clean - rm *.so - diff --git a/Tools/WAD/Misc/fileheader b/Tools/WAD/Misc/fileheader deleted file mode 100644 index 7b82e9e05..000000000 --- a/Tools/WAD/Misc/fileheader +++ /dev/null @@ -1,28 +0,0 @@ -/* ----------------------------------------------------------------------------- - * segment.c - * - * This file provides access to the virtual memory map of a process - * including the location of the executable, data segments, shared - * libraries, and memory mapped regions. This information is - * obtained through /proc. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ diff --git a/Tools/WAD/Papers/README b/Tools/WAD/Papers/README deleted file mode 100644 index 8eb7b81d1..000000000 --- a/Tools/WAD/Papers/README +++ /dev/null @@ -1,5 +0,0 @@ -Papers about WAD can be obtained at: - - http://systems.cs.uchicago.edu/wad - - diff --git a/Tools/WAD/Prebuilt/linux/Makefile.in b/Tools/WAD/Prebuilt/linux/Makefile.in deleted file mode 100644 index 074e65452..000000000 --- a/Tools/WAD/Prebuilt/linux/Makefile.in +++ /dev/null @@ -1,11 +0,0 @@ -# Generated automatically from Makefile.in by configure. - -SHELL = /bin/sh -prefix = @prefix@ -execprefix= @exec_prefix@ -LIB = $(execprefix)/lib - -install: - cp libwad*.so $(LIB) - chmod a+rx $(LIB)/libwad*.so - diff --git a/Tools/WAD/Prebuilt/solaris/Makefile.in b/Tools/WAD/Prebuilt/solaris/Makefile.in deleted file mode 100644 index 074e65452..000000000 --- a/Tools/WAD/Prebuilt/solaris/Makefile.in +++ /dev/null @@ -1,11 +0,0 @@ -# Generated automatically from Makefile.in by configure. - -SHELL = /bin/sh -prefix = @prefix@ -execprefix= @exec_prefix@ -LIB = $(execprefix)/lib - -install: - cp libwad*.so $(LIB) - chmod a+rx $(LIB)/libwad*.so - diff --git a/Tools/WAD/Python/Makefile.in b/Tools/WAD/Python/Makefile.in deleted file mode 100644 index 2859039af..000000000 --- a/Tools/WAD/Python/Makefile.in +++ /dev/null @@ -1,54 +0,0 @@ -####################################################################### -# WAD Makefile -# -# David Beazley -# January 1, 2001 -####################################################################### - -# These are the files that make up the WAD core -SRCS = type.c python.c -OBJS = type.o python.o -INCLUDE = -I../Include -I. $(SINCLUDE) -WADOPT = @WADOPT@ - -# Location of your Python installation -PYINCLUDE = @PYINCLUDE@ -PYSRCS = wadpyinit.cxx -PYOBJS = wadpyinit.o - -# C Compiler -CC = @CC@ -CFLAGS = #@CCSHARED@ - -# C++ Compiler -CXX = @CXX@ -CXXFLAGS = #@CXXSHARED@ - -# Linking options -CLINK = -CXXLINK = @CXXLINK@ - -# Rules for creation of a .o file from .cxx -.SUFFIXES: .cxx -.cxx.o: - $(CXX) $(CXXFLAGS) $(WADOPT) $(INCLUDE) -c -o $*.o $< - -.c.o: - $(CC) $(CFLAGS) $(PYINCLUDE) $(WADOPT) $(INCLUDE) -c -o $*.o $< - -python: $(OBJS) $(PYOBJS) - $(CXXLINK) $(OBJS) $(PYOBJS) -o libwadpy.so -L.. -lwadcore - cp libwadpy.so .. - -wc:: - wc $(SRCS) - -semi:: - @egrep ";" $(SRCS) $(PYSRCS) | wc - -clean:: - rm -f *.o *.so *~ - - - - diff --git a/Tools/WAD/Python/python.c b/Tools/WAD/Python/python.c deleted file mode 100644 index 9f4686587..000000000 --- a/Tools/WAD/Python/python.c +++ /dev/null @@ -1,221 +0,0 @@ -/* ----------------------------------------------------------------------------- - * python.c - * - * Dynamically loadable python module for wad. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "Python.h" -#include "wad.h" - -static char cvs[] = "$Id$"; - -/* These are the python exception objects we will add - SegFault, BusError, AbortError */ - -static PyObject *segfault_exc = 0; -static PyObject *buserror_exc = 0; -static PyObject *abort_exc = 0; -static PyObject *illegal_exc = 0; - -extern PyObject *new_wadobject(WadFrame *f,int); - -/* Function return points and values */ - -static WadReturnFunc retpts[] = { - {"call_builtin", 0}, - {"_PyImport_LoadDynamicModule", 0}, - {"PyEval_EvalCode", 0}, - {"PyObject_GetAttrString", 0}, - {"PyObject_SetAttrString", -1}, - {"PyObject_Repr", 0}, - {"PyObject_Print", -1}, - {"PyObject_CallFunction", 0}, - {"PyObject_CallMethod", 0}, - {"PyObject_CallObject", 0}, - {"PyObject_Cmp", -1}, - {"PyObject_Compare", -1}, - {"PyObject_DelAttrString",-1}, - {"PyObject_DelItem",-1}, - {"PyObject_GetItem",0}, - {"PyObject_SetItem",-1}, - {"PyObject_HasAttrString",-1}, - {"PyObject_Hash",-1}, - {"PyObject_Length",-1}, - {"PyObject_Str",0}, - {"PyObject_Type", 0}, - - {"PyNumber_Absolute", 0}, - {"PyNumber_Add",0}, - {"PyNumber_And",0}, - {"PyNumber_Coerce",0}, - {"PyNumber_Divide",0}, - {"PyNumber_Divmod",0}, - {"PyNumber_Float",0}, - {"PyNumber_Int",0}, - {"PyNumber_Invert",0}, - {"PyNumber_Long",0}, - {"PyNumber_Lshift",0}, - {"PyNumber_Multiply", 0}, - {"PyNumber_Negative", 0}, - {"PyNumber_Or",0}, - {"PyNumber_Positive", 0}, - {"PyNumber_Power",0}, - {"PyNumber_Remainder",0}, - {"PyNumber_Rshift",0}, - {"PyNumber_Subtract",0}, - {"PyNumber_Xor",0}, - - {"PySequence_Concat",0}, - {"PySequence_Count",-1}, - {"PySequence_Delitem",-1}, - {"PySequence_DelSlice",-1}, - {"PySequence_Getitem",0}, - {"PySequence_GetSlice",0}, - {"PySequence_In",-1}, - {"PySequence_Index",-1}, - {"PySequence_Repeat",0}, - {"PySequence_SetItem",-1}, - {"PySequence_SetSlice",-1}, - {"PySequence_Tuple",0}, - - {"PyMapping_Clear",-1}, - {"PyMapping_DelItem",-1}, - {"PyMapping_DelItemString",-1}, - {"PyMapping_GetItemString",0}, - {"PyMapping_HasKey",-1}, - {"PyMapping_HasKeyString",-1}, - {"PyMapping_Items",0}, - {"PyMapping_Keys",0}, - {"PyMapping_Length", -1}, - {"PyMapping_SetItemString", -1}, - {"PyMapping_Values", 0}, - {"",0}}; - -/* Handler function */ -static void handler(int signo, WadFrame *frame, char *ret) { - static char message[65536]; - static char temp[1024]; - int len = 0; - PyObject *type; - char *name; - WadFrame *f; - WadFrame *fline = 0; - char *srcstr = 0; - - /* printf("python handler.\n"); */ - if (!ret) { - wad_default_callback(signo, frame, ret); - return; - } - - strcpy(message,"[ C stack trace ]\n\n"); - switch(signo) { - case SIGSEGV: - type = segfault_exc; - break; - case SIGBUS: - type = buserror_exc; - break; - case SIGABRT: - type = abort_exc; - break; - case SIGFPE: - type = PyExc_FloatingPointError; - break; - case SIGILL: - type = illegal_exc; - break; - default: - type = PyExc_RuntimeError; - break; - } - -#ifdef OLD - f = frame; - /* Find the last exception frame */ - while (!f->last) { - f= f->next; - } - /* Now work backwards */ - f = f->prev; - while (f) { - strcat(message, f->debug_str); - if (f->debug_srcstr) srcstr = f->debug_srcstr; - f = f->prev; - } - if (srcstr) { - strcat(message,"\n"); - strcat(message, srcstr); - strcat(message,"\n"); - } -#endif - - if (wad_heap_overflow) { - write(2, "WAD: Heap overflow detected.\n", 30); - wad_default_callback(signo, frame, ret); - } - - /* Note: if the heap is blown, there is a very good chance that this - function will not succeed and we'll dump core. However, the check - above should dump a stack trace to stderr just in case we don't make it - back. */ - -#ifdef OLD - PyErr_SetString(type, message); -#endif - PyErr_SetObject(type, new_wadobject(frame,0)); - -} - -void pywadinit() { - PyObject *d, *m; - m = PyImport_ImportModule((char *)"__builtin__"); - d = PyModule_GetDict(m); - printf("WAD Enabled\n"); - - segfault_exc = PyErr_NewException((char *)"exceptions.SegFault", NULL, NULL); - PyDict_SetItemString(d,(char *)"SegFault",segfault_exc); - - buserror_exc = PyErr_NewException((char *)"exceptions.BusError", NULL, NULL); - PyDict_SetItemString(d,(char *)"BusError",buserror_exc); - - abort_exc = PyErr_NewException((char*)"exceptions.AbortError", NULL, NULL); - PyDict_SetItemString(d,(char *)"AbortError",abort_exc); - - illegal_exc = PyErr_NewException((char *)"exceptions.IllegalInstruction", NULL, NULL); - PyDict_SetItemString(d,(char *)"IllegalInstruction",illegal_exc); - - wad_init(); - wad_set_callback(handler); - wad_set_returns(retpts); -} - -static PyMethodDef wadmethods[] = { - {0,0}, -}; - -void initlibwadpy() { - Py_InitModule((char *)"libwadpy",wadmethods); -} - - diff --git a/Tools/WAD/Python/type.c b/Tools/WAD/Python/type.c deleted file mode 100644 index 7d8248e0b..000000000 --- a/Tools/WAD/Python/type.c +++ /dev/null @@ -1,277 +0,0 @@ -/* ----------------------------------------------------------------------------- - * type.c - * - * This file defines a new python type that contains information from - * the WAD stack trace. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - - -#include "wad.h" -#include "Python.h" - -static char cvs[] = "$Id$"; - -typedef struct { - PyObject_HEAD - WadFrame *frame; /* Wad Stack frame object */ - int count; /* Number of frames */ -} wadobject; - -staticforward PyTypeObject WadObjectType; - - -PyObject * -new_wadobject(WadFrame *f, int count) { - wadobject *self; - self = PyObject_NEW(wadobject, &WadObjectType); - if (self == NULL) return NULL; - - self->frame = f; - if (count > 0) { - self->count = count; - } else { - self->count = 0; - while (f) { - self->count++; - f = f->next; - } - } - return (PyObject *) self; -} - -/* release a wad object */ -static void -wadobject_dealloc(wadobject *self) { - PyObject_Del(self); -} - -static char message[65536]; -static PyObject * -wadobject_repr(wadobject *self) { - char *srcstr = 0; - WadFrame *fp = 0; - int n; - WadFrame *f = self->frame; - - message[0] = 0; - /* Find the last exception frame */ - n = self->count; - while (f && n) { - fp = f; - f= f->next; - n--; - } - - if (fp) { - /* Now work backwards */ - f = fp; - while (f) { - strcat(message, f->debug_str); - if (f->debug_srcstr) srcstr = f->debug_srcstr; - if (f == self->frame) break; - f = f->prev; - } - if (srcstr) { - strcat(message,"\n"); - strcat(message, srcstr); - strcat(message,"\n"); - } - } - return PyString_FromString(message); -} - -static PyObject * -wadobject_str(wadobject *self) { - char *srcstr = 0; - int n; - - WadFrame *f = self->frame; - n = self->count; - strcpy(message,"[ C stack trace ]\n\n"); - /* Find the last exception frame */ - while (!f->last && n) { - f= f->next; - n--; - } - /* Now work backwards */ - if (n <= 0) { - f = f->prev; - } - while (f) { - strcat(message, f->debug_str); - if (f->debug_srcstr) srcstr = f->debug_srcstr; - if (self->frame == f) break; - f = f->prev; - } - if (srcstr) { - strcat(message,"\n"); - strcat(message, srcstr); - strcat(message,"\n"); - } - return PyString_FromString(message); -} - -static int -wadobject_len(wadobject *self) { - int n = 0; - WadFrame *f = self->frame; - while (f) { - n++; - f = f->next; - } - return n; -} - -static PyObject * -wadobject_getitem(wadobject *self, int n) { - int i; - WadFrame *f; - if (n < 0) { - n = self->count + n; - } - if ((n < 0) || (n >= self->count)) { - PyErr_SetString(PyExc_IndexError,"Stack frame out of range"); - return NULL; - } - f = self->frame; - for (i = 0; i next; - } - return new_wadobject(f,1); -} - -static PyObject * -wadobject_getslice(wadobject *self, int start, int end) { - int i; - WadFrame *f; - - f = self->frame; - for (i = 0; i < start; i++) { - f = f->next; - } - return new_wadobject(f,(end-start)); -} - -static PyObject * -wadobject_getattr(wadobject *self, char *name) { - if (strcmp(name,"__NAME__") == 0) { - return Py_BuildValue("z", self->frame->sym_name); - } else if (strcmp(name,"__EXE__") == 0) { - return Py_BuildValue("z", self->frame->object->path); - } else if (strcmp(name,"__FILE__") == 0) { - return Py_BuildValue("z", self->frame->loc_srcfile); - } else if (strcmp(name,"__OBJECT__") == 0) { - return Py_BuildValue("z", self->frame->loc_objfile); - } else if (strcmp(name,"__LINE__") == 0) { - return Py_BuildValue("i", self->frame->loc_line); - } else if (strcmp(name,"__SOURCE__") == 0) { - return Py_BuildValue("z",self->frame->debug_srcstr); - } else if (strcmp(name,"__PC__") == 0) { - return PyLong_FromUnsignedLong(self->frame->pc); - } else if (strcmp(name,"__SP__") == 0) { - return PyLong_FromUnsignedLong(self->frame->sp); - } else if (strcmp(name,"__FP__") == 0) { - return PyLong_FromUnsignedLong(self->frame->fp); - } else if (strcmp(name,"__STACK__") == 0) { - return PyString_FromStringAndSize(self->frame->stack, self->frame->stack_size); - } else if (strcmp(name,"__NARGS__") == 0) { - return PyInt_FromLong(self->frame->debug_nargs); - } else if (strcmp(name,"__LAST__") == 0) { - return PyInt_FromLong(self->frame->last); - } else if (strcmp(name,"__WHERE__") == 0) { - return Py_BuildValue("z",self->frame->debug_str); - } else if (strcmp(name,"__WAD__") == 0) { - return PyInt_FromLong(1); - } - - - /* Put a check for local variables */ - { - int i; - for (i = 0; i < 2; i++) { - WadLocal *loc; - if (i == 0) loc = self->frame->debug_locals; - else loc = self->frame->debug_args; - while (loc) { - if (strcmp(name,loc->name) == 0) { - switch(loc->type) { - case WAD_TYPE_INT32: - case WAD_TYPE_INT16: - case WAD_TYPE_INT8: - return PyLong_FromLong(wad_local_as_long(loc)); - break; - case WAD_TYPE_UINT8: - case WAD_TYPE_UINT16: - case WAD_TYPE_UINT32: - return PyLong_FromUnsignedLong((unsigned long) wad_local_as_long(loc)); - break; - case WAD_TYPE_CHAR: - return Py_BuildValue("c", (char) (PyLong_FromLong(wad_local_as_long(loc)))); - break; - case WAD_TYPE_FLOAT: - case WAD_TYPE_DOUBLE: - return PyFloat_FromDouble(wad_local_as_double(loc)); - break; - default: - return PyLong_FromUnsignedLong((unsigned long) wad_local_as_long(loc)); - } - } - loc = loc->next; - } - } - } - - PyErr_SetString(PyExc_NameError,"Unknown attribute."); - return NULL; -} -static PySequenceMethods wadobject_as_sequence = { - (inquiry) wadobject_len, - 0, - 0, - (intargfunc) wadobject_getitem, /* get item */ - (intintargfunc) wadobject_getslice, /* get slice */ - 0, - 0 -}; - -static PyTypeObject WadObjectType = { - PyObject_HEAD_INIT(&PyType_Type) - 0, - "WadObject", - sizeof(wadobject), - 0, - (destructor) wadobject_dealloc, - 0, /* printfunc */ - (getattrfunc) wadobject_getattr, - (setattrfunc) 0, - (cmpfunc) 0, - (reprfunc) wadobject_repr, - - 0, /* number */ - &wadobject_as_sequence, /* sequence */ - 0, /* mapping */ - 0, /* hash */ - 0, /* call */ - (reprfunc) wadobject_str, /* str */ -}; - diff --git a/Tools/WAD/Python/wadpyinit.cxx b/Tools/WAD/Python/wadpyinit.cxx deleted file mode 100644 index b97009402..000000000 --- a/Tools/WAD/Python/wadpyinit.cxx +++ /dev/null @@ -1,45 +0,0 @@ -/* ----------------------------------------------------------------------------- - * wadpyinit.cxx - * - * C++ automatic initializer for Python module. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -extern "C" void pywadinit(); - -/* This hack is used to auto-initialize wad regardless of whether we are - used as an imported module or as a link-library for another module */ - -class wadinitializer { -public: - wadinitializer() { - pywadinit(); - } -}; - -static wadinitializer wi; - - diff --git a/Tools/WAD/README b/Tools/WAD/README deleted file mode 100644 index c777c4efb..000000000 --- a/Tools/WAD/README +++ /dev/null @@ -1,376 +0,0 @@ -WAD (Wrapped Application Debugger) - -Author(s): - David M. Beazley (beazley@cs.uchicago.edu) - -Copyright (C) 2001 -University of Chicago - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library 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 -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -See the file COPYING for a complete copy of the LGPL. - -$Id$ - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!!!!!!!! DISCLAIMER !!!!!!!! -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -THIS IS EXPERIMENTAL UNMAINTAINED RESEARCH SOFTWARE THAT REPRESENTS -WORK IN PROGRESS. IT IS NOT PORTABLE, IT HAS NOT BEEN EXHAUSTIVELY -TESTED, AND IT MIGHT NOT WORK AT ALL. PLEASE KEEP AWAY FROM SMALL -CHILDREN, PETS, NUCLEAR REACTORS, AIR-TRAFFIC CONTROL, AND VOTING -MACHINES. - -0. Supported Platforms - -This software is currently only known to work with 32-bit applications -on Sun Sparc Solaris 2.8 and recent i386-Linux systems. In addition, -there are numerous issues concerning the interaction of this software -with signal handling, thread libraries, and compilers. Please read -this entire document before proceeding. - -1. Introduction - -WAD is an embedded error-recovery mechanism that attempts to convert -fatal errors such as SIGSEGV, SIGBUS, and SIGFPE into sensible error -messages and exceptions. It is primarily designed to support -scripting language extension programming although it can also be used -with stand-alone C programs. - -The primary goal of this system is to explore an alternative approach -to mixed scripting-compiled debugging. It requires no modifications -or recompilation of existing software. Therefore, it should be -relatively easy to try out. Feedback is welcome. Contributions and -modifications are even more welcome. - -2. Compilation and Installation - -WAD is not particularly portable and at this time, only two platforms -are supported: Sun Sparc Solaris and i386-Linux. - -Installation is as follows: - - ./configure - make - make install - -The build process creates the following shared libraries: - - libwad.so - Standalone WAD. Can be linked with C/C++ - programs. - - libwadpy.so - Python WAD. Can be linked to Python extension - modules or imported on its own as 'import libwadpy' - - libwadtcl.so - Tcl WAD. Can be linked to Tcl extension - modules or loaded as 'load libwadtcl.so'. - - libwadpl.so - Perl WAD. Can be linked to Perl extension - modules or loaded as 'libwadpl'. - -To install the libraries, simply type 'make install'. This copies the libraries -to /usr/local/lib (unless you modify the makefile). - -Notes: - - - The Sun version of WAD has only been tested when compiled with the - Sun Workshop C/C++ compilers. However WAD works with other programs - that have been compiled with gcc. If gcc is installed on your - machine, you may want to set the following environment variables - before running configure: - - setenv CC cc - setenv CXX CC - ./configure - - - You may need to modify the Makefile to point to the installed locations - of various scripting language libraries if you have installed - them in non-traditional locations. - - - The Linux version has only been tested with 2.2-12 and 2.2-14 kernels - and the RedHat 6.x distribution. Your mileage may vary. There - may be some compatibility issues related to glibc and other parts - of the system as well. - -3. Using WAD - -WAD has no functional API nor does it have any command line options so -it's pretty easy to describe---simply link the appropriate WAD library with -your C code. For example: - - % cc blah.c -lwad - -Once linked, fatal errors will now produce stack traces. For example: - -% ./a.out seg -starting. -Segmentation fault. -#2 0x400571eb in __libc_start_main() in 'libc-start.c', line 90 -#1 0x08048b39 in main(argc=0x2,argv=0xbffffce4) in 'debug.c', line 62 -#0 0x080489b3 in seg_crash(n=0x0) in 'debug.c', line 9 - -/r0/beazley/Projects/WAD/Wad/debug.c, line 9 - - int *a = 0; - if (n > 0) seg_crash(n-1); - => *a = 3; - return 1; - } - -For scripting languages, WAD works in a similar manner--simply link -your scripting language extension module with the appropriate WAD library -(wadpy, wadtcl, wadpl). For example: - - % ld -G $(OBJS) -lwadpy -o pymodule.so - -When the scripting module is loaded into the interpreter, WAD should -automatically initialize. - -4. Debugging Modes - -Due to WAD's experimental nature, a number of debugging modes can be set -through the use of environment variables. These variables control WAD's -runtime behavior and cause the system to dump debugging information for -various stages of error recovery. A lot of this data is pretty ugly and -probably only of interest to you if you are trying to debug WAD itself. - -WAD_DEBUG_SEGMENT - Displays information about the virtual memory - map and mapping of addresses to segments. - -WAD_DEBUG_SYMBOL - Symbol table mapping. - -WAD_DEBUG_OBJECT - Loading/Unloading of object files. - -WAD_DEBUG_FILE - Loading/Unloading of raw files. - -WAD_DEBUG_HOLD - Freezes WAD before it returns from the signal handler. - Useful if you need to attach a debugger to WAD itself. - -WAD_DEBUG_STABS - Display stabs data. - -WAD_DEBUG_RETURN - Display information about WAD return points. - -WAD_DEBUG_SYMBOL_SEARCH - Display all symbols in the symbol table that are - searched. - -WAD_DEBUG_UNWIND - Display information about stack unwinding. - -WAD_DEBUG_SIGNAL - Display information about signal handling. - -WAD_DEBUG_INIT - Print initialization information. - -WAD_NOSTACK - Do NOT use an alternative signal handling stack. - This may be necessary on certain Linux systems when - threads are being used. - -WAD_ONESHOT - Disable WAD signal handler after first signal has - been received. - -WAD_DEBUG_MEMORY - Print information about WAD memory use. - -WAD_DEBUG_STRINGS - Print information about WAD string manager. - -5. Platform Specific Issues - -General: - - - WAD does not gracefully recover from errors that corrupt the call - stack (i.e., buffer overlow). - - - Errors that destroy the process heap may or may not be recoverable - depending on what has been destroyed. - - - WAD does not currently support 64 bit applications on any platform. - - - If executables have been stripped, their symbol tables might not - have enough information to recover from errors. Therefore, if you - are using Python, Tcl, or Perl from a binary distribution, you - may want to rebuild non-stripped versions of these packages yourself. - - - WAD only works with programs that utilize the ELF32 linking format - and stabs debugging data. Newer formats such as DWARF2 are not - supported at this time. - - - WAD does not correctly report argument values for structures or - floating point numbers yet. - - - Overly aggressive compiler optimization may lead to very strange - WAD output. - -Solaris: - - - WAD is extremely slow at collecting debugging information - from large applications. - -Linux: - - - The interaction of threads and signals are particularly problematic - on this platform and may cause WAD not to work at all. Here are - some specific thread-based issues that may arise: - - 1. WAD causes the program to crash immediately upon startup. - This appears to be caused by a bug in in the implementation - of sigaction() and the initialization of signals. This - only occurs if WAD is directly linked to an executable - using threads. It does not occur when WAD is dynamically - loaded into a threaded application. - - 2. Programs may lock up when an error occurs. This is sometimes - caused by an apparently broken implementation of sigaltstack(). - One solution to this is to set the following environment - variable: - - setenv WAD_NOSTACK - - in which case the WAD signal handler will use the same - stack as the thread/process that generates the error. - - 3. WAD just crashes altogether and doesn't seem to do anything. - It appears that some versions of Linux threads do *not* - pass CPU context information correctly to signal handlers - defined in threaded programs. There is no known fix to - this at this time. Upgrade your system. - - - WAD does not work if it is compiled as PIC code. The WAD libraries - should be compiled *without* the -fpic option. - - - WAD has to rely upon a heuristic register recovery scheme when it - returns to scripting language interpreters. It seems to - work, but it relies upon a very specific compiler code generation - convention for saving registers in function prologues. It also - relies upon the register save conventions described in the Linux - Assembly HOWTO. - - - If you are using WAD with pre-installed binaries for Python, Tcl, - and other scripting languages, it may not work correctly due to - stripped symbol tables. Most Linux installs such as Redhat strip - symbol tables from executables. This makes it difficult for WAD - to determine context correctly (although it may still work since - the dynamic loading symbol table is still available in most cases). - -6. Language specific issues - -If WAD is linked with a normal C/C++ program, errors simply produce a stack trace -that is printed on standard error. - -Python: - -WAD tries to raise a Python exception and return. At this time, the exception -merely contains a traceback string. However, in future versions, it may be -possible to access a complete exception object. - -Tcl: - -WAD returns a Tcl and places the stack trace into the Tcl variable $errorInfo. -The wish shell uses this to dump error information. - -Perl: - -Perl doesn't seem to have a very well-defined exception handling -mechanism. Standard functions tend to just exit. The WAD handler -produces a C stack trace and produces a Perl stack trace using some -code derived from the sigtrap module. - -Note: 3/23/01 - Perl support is currently broken. - -7. Testing and Examples - -The Test directory contains some very simple code for testing WAD. In the -most simple form, compile the stand-along test program 'debug' as follows: - -% cd Test -% make - -Now, running it: - -% debug -WAD debug program. - -Usage: debug type - seg - Fail with an uninitialized pointer. - bus - Fail with a bus error. - abort - Fail with an assertion error. - math - Fail with a math error. - heap - Blow the process heap. - overflow - Buffer overflow on the stack. - -% debug seg -WAD debug program. -Segmentation fault. -#2 0x400581eb in __libc_start_main() in 'libc-start.c', line 90 -#1 0x08048b61 in main(argc=0x2,argv=0xbffffc54) in 'debug.c', line 85 -#0 0x080489d0 in seg_crash() in 'debug.c', line 15 - -/r0/beazley/Projects/WAD/Test/debug.c, line 15 - - int seg_crash() { - int *a = 0; - => *a = 3; - return 1; - } - -Additional targets 'make python', 'make tcl', and 'make perl' are also available. -The scripts debug.py, debug.tcl, debug.pl can be used to test these extensions. - -8. Documentation - -No official documentation exists at this time. However, details -of WAD's design and implementation can be found in papers presented -at the Ninth International Python Conference and the 2000 USENIX -Technical Conference. Both papers can be obtained at: - - http://systems.cs.uchicago.edu/wad - - -9. To-Do - -If you find WAD to be interesting or useful, there are a variety of -ways to contribute. Here is the short to-do list: - - - Better register management. Try to implement in a more portable - way. Add some support code for recovering local variables - that happen to be stored in registers. - - - Add heuristic for recovering functions called through an - -fomit-frame-pointer compiler optimization scheme. This - can probably be determined by looking at the function preamble - machine code. Then one can back-trace to the calling function - and look at it's preamble. - - - Continued clean up and modularization of the core. Many of the - internal APIs could be greatly improved. - - - Support for ELF64 linking format. - - - Support for DWARF2 debugging data. - - - Improved support for stack-overflow and heap-corruption. Although WAD - probably won't be able to recover, it still might be able to produce some - informative diagnostics. - - - Removal of printf() and other high-level library calls which may not - operate with a corrupted heap. - - - Better integration with scripting languages. - - - Support for new platforms. - - - Support for new scripting languages. - -Please contact me if you are interested in working on any of these projects. - -Dave Beazley (beazley@cs.uchicago.edu) -June 24, 2001 diff --git a/Tools/WAD/Tcl/Makefile.in b/Tools/WAD/Tcl/Makefile.in deleted file mode 100644 index b734a8c5f..000000000 --- a/Tools/WAD/Tcl/Makefile.in +++ /dev/null @@ -1,54 +0,0 @@ -####################################################################### -# WAD Makefile -# -# David Beazley -# January 1, 2001 -####################################################################### - -# These are the files that make up the WAD core -SRCS = wadtcl.c -OBJS = wadtcl.o -INCLUDE = -I../Include -I. $(SINCLUDE) -WADOPT = @WADOPT@ - -# Location of your Tcl installation -TCLINCLUDE = @TCLINCLUDE@ -TCLSRCS = wadtclinit.cxx -TCLOBJS = wadtclinit.o - -# C Compiler -CC = @CC@ -CFLAGS = #@CCSHARED@ - -# C++ Compiler -CXX = @CXX@ -CXXFLAGS = #@CXXSHARED@ - -# Linking options -CLINK = -CXXLINK = @CXXLINK@ - -# Rules for creation of a .o file from .cxx -.SUFFIXES: .cxx -.cxx.o: - $(CXX) $(CXXFLAGS) $(WADOPT) $(INCLUDE) -c -o $*.o $< - -.c.o: - $(CC) $(CFLAGS) $(TCLINCLUDE) $(WADOPT) $(INCLUDE) -c -o $*.o $< - -tcl: $(OBJS) $(TCLOBJS) - $(CXXLINK) $(OBJS) $(TCLOBJS) -o libwadtcl.so -L.. -lwadcore - cp libwadtcl.so .. - -wc:: - wc $(SRCS) - -semi:: - @egrep ";" $(SRCS) $(TCLSRCS) | wc - -clean:: - rm -f *.o *.so *~ - - - - diff --git a/Tools/WAD/Tcl/wadtcl.c b/Tools/WAD/Tcl/wadtcl.c deleted file mode 100644 index df68f7473..000000000 --- a/Tools/WAD/Tcl/wadtcl.c +++ /dev/null @@ -1,122 +0,0 @@ -/* ----------------------------------------------------------------------------- - * wadtcl.c - * - * Dynamically loadable Tcl module for wad. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include -#include "wad.h" -#include - -static char cvs[] = "$Id$"; - -/* Handler function */ -static void handler(int signo, WadFrame *frame, char *ret) { - static char message[65536]; - static char temp[1024]; - int len = 0; - char *name; - WadFrame *f; - WadFrame *fline = 0; - char *srcstr= 0; - Tcl_Interp *interp; - int err; - char *type; - - if (!ret) { - wad_default_callback(signo, frame, ret); - return; - } - - strcpy(message,"[ C stack trace ]\n\n"); - switch(signo) { - case SIGSEGV: - type = (char*)"Segmentation fault."; - break; - case SIGBUS: - type = (char*)"Bus error."; - break; - case SIGABRT: - type = (char*)"Abort."; - break; - case SIGFPE: - type = (char*)"Floating point exception."; - break; - default: - type = (char*)"Unknown."; - break; - } - - f = frame; - /* Find the last exception frame */ - while (!f->last) { - f= f->next; - } - /* Now work backwards */ - f = f->prev; - while (f) { - strcat(message, f->debug_str); - if (f->debug_srcstr) srcstr = f->debug_srcstr; - f = f->prev; - } - if (srcstr) { - strcat(message,"\n"); - strcat(message, srcstr); - strcat(message,"\n"); - } - - if (wad_heap_overflow) { - write(2, "WAD: Heap overflow detected.\n", 30); - wad_default_callback(signo, frame, ret); - } - - /* Note: if the heap is blown, there is a very good chance that this - function will not succeed and we'll dump core. However, the check - above should dump a stack trace to stderr just in case we don't make it - back. */ - - /* Try to get the Tcl interpreter through magic */ - if (ret) { - interp = (Tcl_Interp *) wad_steal_outarg(frame,ret,1,&err); - if (err == 0) { - Tcl_SetResult(interp,type,TCL_STATIC); - Tcl_AddErrorInfo(interp,message); - } - } -} - -void tclwadinit() { - printf("WAD Enabled\n"); - wad_init(); - wad_set_callback(handler); - wad_set_return("TclExecuteByteCode", TCL_ERROR); - wad_set_return("EvalObjv", TCL_ERROR); -} - -int Wad_Init(Tcl_Interp *interp) { - return TCL_OK; -} - -int Wadtcl_Init(Tcl_Interp *interp) { - return TCL_OK; -} diff --git a/Tools/WAD/Tcl/wadtclinit.cxx b/Tools/WAD/Tcl/wadtclinit.cxx deleted file mode 100644 index 30c288cea..000000000 --- a/Tools/WAD/Tcl/wadtclinit.cxx +++ /dev/null @@ -1,38 +0,0 @@ -/* ----------------------------------------------------------------------------- - * wadtclinit.cxx - * - * C++ initializer for Tcl wad. - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ -static char cvs[] = "$Id$"; - -extern "C" void tclwadinit(); - -/* This hack is used to auto-initialize wad regardless of whether we are - used as an imported module or as a link-library for another module */ - -class wadinitializer { -public: - wadinitializer() { - tclwadinit(); - } -}; - -static wadinitializer wi; diff --git a/Tools/WAD/Test/Makefile.in b/Tools/WAD/Test/Makefile.in deleted file mode 100644 index c6e808275..000000000 --- a/Tools/WAD/Test/Makefile.in +++ /dev/null @@ -1,44 +0,0 @@ -####################################################################### -# WAD Test makefile -# -# Build some WAD test programs. -####################################################################### - -CC= @CC@ -CCSHARED = @CCSHARED@ -LDSHARED = @LDSHARED@ -RPATH = @RPATH@ - -PYINCLUDE = @PYINCLUDE@ -TCLINCLUDE = @TCLINCLUDE@ -PERLINCLUDE = @PERL5EXT@ -INCLUDE = -I../Include -WADLIB = .. -WADLINK = -L$(WADLIB) $(RPATH)$(WADLIB) - -test: - $(CC) -g -DNEED_MAIN debug.c $(INCLUDE) $(WADLINK) -lwad -o debug - -python: pydebug.c - $(CC) $(CCSHARED) -c -g debug.c pydebug.c $(PYINCLUDE) - $(LDSHARED) debug.o pydebug.o $(WADLINK) -lwadpy -o debugmodule.so - -tcl: tcldebug.c - $(CC) $(CCSHARED) -c -g debug.c tcldebug.c $(TCLINCLUDE) - $(LDSHARED) debug.o tcldebug.o $(WADLINK) -lwadtcl -o debug.so - -perl: pldebug.c - $(CC) $(CCSHARED) -c -Dbool=char -g debug.c pldebug.c $(PERLINCLUDE) - $(LDSHARED) debug.o pldebug.o $(WADLINK) -lwadpl -o debug.so - -pydebug.c: - swig -python -o pydebug.c debug.i - -tcldebug.c: - swig -tcl -o tcldebug.c debug.i - -pldebug.c: - swig -perl5 -o pldebug.c debug.i - -clean: - rm -f *.so *.o debug *_wrap* diff --git a/Tools/WAD/Test/README b/Tools/WAD/Test/README deleted file mode 100644 index 6a04a7e8a..000000000 --- a/Tools/WAD/Test/README +++ /dev/null @@ -1,5 +0,0 @@ -Simple test programs for WAD. This is currently incomplete. - -Note: To completely rebuild the Python, Perl, and Tcl tests, -you need to have SWIG installed (www.swig.org). - diff --git a/Tools/WAD/Test/death.py b/Tools/WAD/Test/death.py deleted file mode 100644 index ba1de20a3..000000000 --- a/Tools/WAD/Test/death.py +++ /dev/null @@ -1,65 +0,0 @@ -import debug -from Tkinter import * - -def death_by_segmentation(): - debug.seg_crash() - -def death_by_bus(): - debug.bus_crash() - -def death_by_abort(): - debug.abort_crash(-1) - -def death_by_math(): - debug.math_crash(37,0) - -def death_by_buffer(): - debug.overflow_crash() - -def death(f): - ty = f.tvar.get() - if ty == 1: - death_by_segmentation() - elif ty == 2: - death_by_abort() - elif ty == 3: - death_by_math() - elif ty == 4: - death_by_bus() - elif ty == 5: - death_by_buffer() - -class death_options(Frame): - def __init__(self): - Frame.__init__(self) - tvar = IntVar() - Radiobutton(self,text="Segmentation fault", variable=tvar, value=1).pack(anchor=W) - Radiobutton(self,text="Failed assertion", variable=tvar, value=2).pack(anchor=W) - Radiobutton(self,text="Math error", variable=tvar, value=3).pack(anchor=W) - Radiobutton(self,text="Bus error", variable=tvar, value=4).pack(anchor=W) - Radiobutton(self,text="Stack overflow", variable=tvar, value=5).pack(anchor=W) - Button(self,text="Die", command=lambda x=self: death(x)).pack(expand=1, fill=BOTH) - self.tvar = tvar - tvar.set(1) - -def death_wizard(): - root = Tk() - l = Label(text="How would you like to die today?") - l.pack() - death_options().pack() - root.title("Death Wizard") -death_wizard() - -#root.mainloop() - - - - - - - - - - - - diff --git a/Tools/WAD/Test/death.tcl b/Tools/WAD/Test/death.tcl deleted file mode 100644 index e52fa9ec2..000000000 --- a/Tools/WAD/Test/death.tcl +++ /dev/null @@ -1,65 +0,0 @@ -load ./debug[info sharedlibextension] - -proc death_by_segmentation { } { - seg_crash -} - -proc death_by_bus { } { - bus_crash -} - -proc death_by_abort { } { - abort_crash -1 -} - -proc death_by_math { } { - math_crash 37 0 -} - -proc death_by_buffer { } { - overflow_crash -} - -set method 1 -proc death {} { - global method - if { $method == 1 } { - death_by_segmentation - } - if { $method == 2 } { - death_by_abort - } - if { $method == 3 } { - death_by_math - } - if { $method == 4 } { - death_by_bus - } - if { $method == 5 } { - death_by_buffer - } -} - -label .l -text "How would you like to die today?" -pack .l - -radiobutton .r1 -text "Segmentation fault" -variable method -value 1 -pack .r1 -anchor w - -radiobutton .r2 -text "Failed assertion" -variable method -value 2 -pack .r2 -anchor w - -radiobutton .r3 -text "Math error" -variable method -value 3 -pack .r3 -anchor w - -radiobutton .r4 -text "Bus error" -variable method -value 4 -pack .r4 -anchor w - -radiobutton .r5 -text "Stack overflow" -variable method -value 5 -pack .r5 -anchor w - -button .b -text "Die" -command death -pack .b -fill both -expand 1 - -wm title . "Death Wizard" - diff --git a/Tools/WAD/Test/debug.c b/Tools/WAD/Test/debug.c deleted file mode 100644 index b95b539f0..000000000 --- a/Tools/WAD/Test/debug.c +++ /dev/null @@ -1,119 +0,0 @@ -/* ----------------------------------------------------------------------------- - * debug.c - * - * This file contains a variety of different programming errors to test with - * WAD. - * ----------------------------------------------------------------------------- */ - -#include -#include -#include - -typedef double Real; -typedef Real Float; - -char buffer[256]; - -/* A simple segmentation fault on an uninitialized pointer */ -int seg_crash() { - int *a = 0; - *a = 3; - return 1; -} - -/* Blow the process heap */ - -int blowheap_crash() { - int i; - int *a = (int *) malloc(sizeof(int)); - - for (i = 0;; i++) { - a[i] = i; - } -} - -/* Buffer overflow crash on the stack */ -int overflow_crash() { - int a[512]; - int i; - - for (i = 0; i < 1024; i++) { - a[i] = i; - } -} - -/* A simple bus error. */ -int bus_crash() { - double *a = (double *) (buffer+1); - *a = 3.4; - return 1; -} - -/* An assertion */ -int abort_crash(int n) { - assert(n > 0); - return 1; -} - -/* A math error (maybe) */ -int math_crash(int x, int y) { - return x/y; -} - -void type_crash(int a, short b, char c, unsigned long d, float f, double g) { - int la; - short lb; - char lc; - long ld; - float lf; - double lg; - long ll; - - la = a; - lb = b; - lc = c; - ld = ld; - lf = lf; - lg = lg; - assert(0); -} - -#ifdef NEED_MAIN - -static const char *usage="\n\ -Usage: debug type\n\ - seg - Fail with an uninitialized pointer.\n\ - bus - Fail with a bus error.\n\ - abort - Fail with an assertion error.\n\ - math - Fail with a math error.\n\ - heap - Blow the process heap.\n\ - overflow - Buffer overflow on the stack.\n\ -"; - -int main(int argc, char **argv) { - int n; - - printf("WAD debug program.\n"); - - if (argc < 2) { - printf("%s\n", usage); - exit(0); - } - if (strcmp(argv[1],"abort") == 0) { - abort_crash(-4); - } else if (strcmp(argv[1],"seg") ==0) { - seg_crash(); - } else if (strcmp(argv[1],"bus") == 0) { - bus_crash(); - } else if (strcmp(argv[1],"math") == 0) { - math_crash(3,0); - } else if (strcmp(argv[1],"heap") == 0) { - blowheap_crash(); - } else if (strcmp(argv[1],"overflow") == 0) { - overflow_crash(); - } else if (strcmp(argv[1],"type") == 0) { - type_crash(0,2,'x',420000,3.14159,2.1828); - } -} - -#endif diff --git a/Tools/WAD/Test/debug.i b/Tools/WAD/Test/debug.i deleted file mode 100644 index 1823161fc..000000000 --- a/Tools/WAD/Test/debug.i +++ /dev/null @@ -1,9 +0,0 @@ -%module debug - -extern int seg_crash(); -extern int bus_crash(); -extern int blowheap_crash(); -extern int overflow_crash(); -extern int abort_crash(int); -extern int math_crash(int x, int y); -extern void type_crash(int, short, char, unsigned long, float, double); diff --git a/Tools/WAD/Test/debug.py b/Tools/WAD/Test/debug.py deleted file mode 100644 index 07d9453a8..000000000 --- a/Tools/WAD/Test/debug.py +++ /dev/null @@ -1,35 +0,0 @@ -# WAD debugging module for python - -import debug -import sys - -try: - name = sys.argv[1] -except: - print """ -usage: debug.py test - - seg - Segmentation fault due to uninitialized pointer. - bus - Bus error. - abort - Failed assertion. - math - Math error. - heap - Blown heap. - overflow - Buffer overflow. -""" - sys.exit(1) - -if name == "seg": - debug.seg_crash() -elif name == "bus": - debug.bus_crash() -elif name == "abort": - debug.abort_crash(-2) -elif name == "math": - debug.math_crash(3,0) -elif name == "heap": - debug.blowheap_crash() -elif name == "overflow": - debug.overflow_crash() -elif name == "type": - debug.type_crash(37,42, 'x', 420000, 3.14159, 2.1828) - diff --git a/Tools/WAD/Test/debug.tcl b/Tools/WAD/Test/debug.tcl deleted file mode 100644 index ab5cd16aa..000000000 --- a/Tools/WAD/Test/debug.tcl +++ /dev/null @@ -1,25 +0,0 @@ -# WAD debugging module for Tcl. This should be executed with wish - -load ./debug[info sharedlibextension] - -message .t -text "This program tests various program faults. Note: Not all of these errors can be gracefully handled." - -button .b1 -text "Segmentation fault" -command "seg_crash" -button .b2 -text "Bus error (not on Linux)" -command "bus_crash" -button .b3 -text "Abort" -command "abort_crash -1" -button .b4 -text "Math" -command "math_crash 3 0" -button .b5 -text "Blow Heap" -command "blowheap_crash" -button .b6 -text "Buffer overflow" -command "overflow_crash" -button .q -text "Quit" -command "exit" - -pack .t -fill x - -pack .b1 -fill x -pack .b2 -fill x -pack .b3 -fill x -pack .b4 -fill x -pack .b5 -fill x -pack .b6 -fill x -pack .q -fill x - - diff --git a/Tools/WAD/Test/foo.py b/Tools/WAD/Test/foo.py deleted file mode 100644 index dee2e7d57..000000000 --- a/Tools/WAD/Test/foo.py +++ /dev/null @@ -1,31 +0,0 @@ -import debug - -def foo(): - debug.abort_crash(-1) - -def bar(): - foo() - -def spam(): - bar() - -from Tkinter import * - -root = Tk() - -button = Button(text="Press me", command=spam) -button.pack() - -#root.mainloop() - - - - - - - - - - - - diff --git a/Tools/WAD/Test/wadpm.py b/Tools/WAD/Test/wadpm.py deleted file mode 100644 index 8a633129e..000000000 --- a/Tools/WAD/Test/wadpm.py +++ /dev/null @@ -1,49 +0,0 @@ -# ----------------------------------------------------------------------------- -# Wad port-mortem debugger -# -# David Beazley -# ----------------------------------------------------------------------------- - -import sys - -_last_exc = None -_last_level = 0 - -print "WAD port-mortem" - -class where_impl: - def __repr__(self): - global _last_exc, _last_level - if sys.last_value: - if sys.last_value[0] != _last_exc: - _last_exc = sys.last_value[0] - _last_level = 0 - else: - raise RuntimeError,"No pending error." - print repr(_last_exc) - return "" - -where = where_impl() - -class up_impl: - def __repr__(self): - global _last_exc, _last_level - if not _last_exc: - return "" - _last_level += 1 - print repr(_last_exc[_last_level]) - return "" - -up = up_impl() - -class down_impl: - def __repr__(self): - global _last_exc, _last_level - if not _last_exc: - return "" - _last_level -= 1 - print repr(_last_exc[_last_level]) - return "" - -down = down_impl() - diff --git a/Tools/WAD/Test/wpm.py b/Tools/WAD/Test/wpm.py deleted file mode 100644 index f849e3167..000000000 --- a/Tools/WAD/Test/wpm.py +++ /dev/null @@ -1,280 +0,0 @@ -# ----------------------------------------------------------------------------- -# WAD Post-mortem debugger -# -# This program can be used to walk up and down the call stack of a mixed -# Python-C program. The following commands are supported: -# -# w - A stack traceback -# u - Go up the call stack -# d - Go down the call stack -# e - Edit a file -# c - Clear the debugger. -# -# David Beazley -# Copyright (C) 2001 -# University of Chicago -# All Rights Reserved -# ----------------------------------------------------------------------------- - -import sys -import os -import traceback -import types -import linecache - - -print "**************************************************" -print "* WAD Debugger *" -print "**************************************************" - -# Save a local copy of the last exception and value objects from sys - -_last_type = sys.last_type -_last_value = sys.last_value -_last_traceback = sys.last_traceback -_last_level = 0 - -_cstack = None # Stack of C-only code -_pystack = None # Stack of Python only code -_combined_stack = None # Combined C-python stack - -_allmode = 0 # Show entire C stack - -# Generalized object for holding stack frames - -class wad_frame: - def __init__(self,frame, n = 0): - if isinstance(frame,types.TupleType): - # A Python traceback object - self.__FILE__ = frame[0] - self.__LINE__ = frame[1] - self.__NAME__ = frame[2] - self.__ARGSTR__ = frame[3] - self.__FRAMENO__ = n - # Make the debugging string - self.__DEBUGSTR__ = "#%-3d [ Python ] in %s in %s, line %d" % (self.__FRAMENO__, self.__ARGSTR__, self.__FILE__, self.__LINE__) - - # Try to get source data - self.__SOURCE__ = "%s, Line %d\n\n" % (self.__FILE__, self.__LINE__) - for i in range(self.__LINE__-2,self.__LINE__+3): - l = linecache.getline(self.__FILE__,i) - if not l: l = '\n' - if (i == self.__LINE__): - self.__SOURCE__ += " => " - else: - self.__SOURCE__ += " " - self.__SOURCE__ += l - self.__frame__ = None - - elif hasattr(frame,"__WAD__"): - # A WAD traceback object - self.__FILE__ = frame.__FILE__ - self.__LINE__ = frame.__LINE__ - self.__NAME__ = frame.__NAME__ - self.__DEBUGSTR__ = frame.__WHERE__ - self.__SOURCE__ = frame.__SOURCE__ - self.__frame__ = frame - - def __str__(self): - return self.__DEBUGSTR__.strip() - - def __getattr__(self,name): - if self.__frame__: - return getattr(self.__frame__,name) - raise AttributeError - - def output(self): - print self - if self.__SOURCE__: - print "\n%s" % (self.__SOURCE__) - - -def wad_build_info(): - global _last_type,_last_value, _last_traceback, _cstack, _combined_stack,_pystack - - _last_type = None - _last_value = None - _last_traceback = None - _cstack = None - _combined_stack = [] - - # Check to see if any exception is defined - if not sys.last_type: - print "No exception has occurred." - return - - # Save a copy of previous exception - _last_type = sys.last_type - _last_value = sys.last_value - _last_traceback = sys.last_traceback - _last_level = 0 - - start_frame = 0 - # Test to see what kind of object it is - if issubclass(_last_type,StandardError): - # Python exception - print "Python exception" - elif hasattr(_last_value[0],"__WAD__"): - # A wad exception frame object - w = sys.last_value[0] - i = 0 - _cstack = [] - while not w[i].__LAST__: - start_frame += 1 - wf = wad_frame(w[i]) - _cstack.append(wf) - i = i + 1 - -# wf = wad_frame(w[i]) -# _cstack.append(wf) -# start_frame += 1 - - # Build the rest of the c stack - _combined_stack = _cstack[:] - while i < len(w): - wf = wad_frame(w[i]) - _cstack.append(wf) - i = i + 1 - - else: - print "Unknown error" - - # Build the Python call stack - _pystack = [] - t = sys.last_traceback - tp = None - while hasattr(t,"tb_frame"): - tp = t - t = t.tb_next - - fr = traceback.extract_stack(tp.tb_frame) - for i in range(len(fr),0,-1): - f = wad_frame(fr[i-1], start_frame) - start_frame += 1 - _pystack.append(f) - _combined_stack.extend(_pystack) - - -wad_build_info() - -class where_impl: - def __init__(self): - self.all = 0; - self.cstack = 0 - - def __repr__(self): - global _combined_stack, _cstack, _last_level - if (self.cstack): - stack = _cstack - else: - stack = _combined_stack - - if not stack: - print "No current exception." - return "" - - last_source = None - for i in range(len(stack),0,-1): - f = stack[i-1] - print f - if (f.__SOURCE__): - last_source = f.__SOURCE__ - _last_level = i-1 - if last_source: print "\n%s" % last_source - return "" - - def __getitem__(self,n): - global _last_level, _cstack, _combined_stack - if (self.cstack): - stack = _cstack - else: - stack = _combined_stack - _last_level = n - stack[_last_level].output() - return None - - def __len__(self): - return len(frame) - - -where = where_impl() -w = where - -class up_impl: - def __repr__(self): - global _last_level, _combined_stack, _cstack - if where.cstack: - stack = _cstack - else: - stack = _combined_stack - - if not stack: - return "" - _last_level += 1 - stack[_last_level].output() - return "" - -up = up_impl() -u = up - -class down_impl: - def __repr__(self): - global _last_level, _combined_stack, _cstack - if where.cstack: - stack = _cstack - else: - stack = _combined_stack - - if not stack: - return "" - _last_level -= 1 - stack[_last_level].output() - return "" - -down = down_impl() -d = down - -class clear_impl: - def __repr__(self): - global _last_exc, _last_level, frame - _last_exc = None - frame = None - -clear = clear_impl() -c = clear - -class edit_impl: - def __repr__(self): - global _last_level, _combined_stack, _cstack - if where.cstack: - stack = _cstack - else: - stack = _combined_stack - - if not stack: - return "" - f = stack[_last_level] - e = os.getenv("EDITOR","vi") - if f.__FILE__: - os.system("%s +%d %s" % (e,f.__LINE__,f.__FILE__)) - return "" - -edit = edit_impl() -e = edit - -class var_impl: - def __getattr__(self,name): - if (w.cstack): - stack = _cstack - else: - stack = _combined_stack - - return getattr(stack[_last_level],name) - - -v = var_impl() - - -repr(w) - - diff --git a/Tools/WAD/Wad/Makefile.in b/Tools/WAD/Wad/Makefile.in deleted file mode 100644 index b933dfa23..000000000 --- a/Tools/WAD/Wad/Makefile.in +++ /dev/null @@ -1,73 +0,0 @@ -####################################################################### -# WAD Makefile -# -# David Beazley -# January 1, 2001 -####################################################################### - -# These are the files that make up the WAD core -WADSRCS = string.c vars.c io.c memory.c return.c default.c stack.c stab.c elf.c object.c init.c segment.c signal.c -WADOBJS = string.o vars.o io.o memory.o return.o default.o stack.o stab.o elf.o object.o signal.o segment.o init.o -INCLUDE = -I../Include -I. $(SINCLUDE) -WADOPT = @WADOPT@ - - -# Location of your Perl installation -PERLINCLUDE = @PERL5EXT@ -PERLSRCS = wadpl.cxx -PERLOBJS = wadpl.o - -# C Compiler -CC = @CC@ -CFLAGS = #@CCSHARED@ - -# C++ Compiler -CXX = @CXX@ -CXXFLAGS = #@CXXSHARED@ - -# Linking options -CLINK = -CXXLINK = @CXXLINK@ - -# AR -AR = @AR@ - -# Rules for creation of a .o file from .cxx -.SUFFIXES: .cxx -.cxx.o: - $(CXX) $(CXXFLAGS) $(WADOPT) $(INCLUDE) -c -o $*.o $< - -.c.o: - $(CC) $(CFLAGS) $(WADOPT) $(INCLUDE) -c -o $*.o $< - -wad: $(WADOBJS) main.o - $(CXXLINK) $(WADOBJS) main.o -o libwad.so - $(AR) cr libwadcore.a $(WADOBJS) - cp libwad.so .. - cp libwadcore.a .. - -perl: wad_perl_handler.c $(WADOBJS) $(PERLOBJS) - $(CXXLINK) $(WADOBJS) $(PERLOBJS) -o libwadpl.so - cp libwadpl.so .. - -wad_perl_handler.c: - python makehandler.py - -debug:: - cc -g debug.c $(INCLUDE) -L. -R. -lwad - -plus:: - CC -g debug.cxx $(INCLUDE) -L. -R. -lwad - -wc:: - wc $(SRCS) - -semi:: - @egrep ";" $(WADSRCS) plat/*.c | wc - -clean:: - rm -f *.o *.so *~ - - - - diff --git a/Tools/WAD/Wad/debug.c b/Tools/WAD/Wad/debug.c deleted file mode 100644 index fcdb87a60..000000000 --- a/Tools/WAD/Wad/debug.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include "wad.h" -#include - -typedef struct Foo { - double a; - double b; - float c; -} Foo; - -static int type_crash(int n, short m, char c, double x, float y, Foo f, void *ptr) { - int *a = 0; - *a = 3; - return 1; -} -static int seg_crash(int n, double x, - float y) { - int *a = 0; - if (n > 0) seg_crash(n-1,x,y); - *a = 3; - return 1; -} - -int bus_crash(int n) { - int b; - int *a = &b; - a = (int *) ((int) a | 0x1); - if (n > 0) bus_crash(n-1); - *a = 3; - printf("well, well, well.\n"); - return 1; -} - -int abort_crash(int n) { - assert(n > 0); - abort_crash(n-1); - return 1; -} - -double double_crash(double a, double b) { - double *c; - *c = a+b; - return *c; -} - -int math_crash(int x, int y) { - return x/y; -} - -int call_func(int n, int (*f)(int)) { - - int ret; - ret = (*f)(n); - if (ret <= 0) { - printf("An error occurred!\n"); - } - return 0; -} - -static int multi(char a, short b, int c, double d) { - a = 'x'; - b = 15236; - c = 12345678; - d = 3.14159; - return c; -} - -static int test(int x, int (*f)(int)) { - return (*f)(-x); -} - -int main(int argc, char **argv) { - int n; - int (*f)(int); - Foo foo = { 3.14, 28.18, 1.0 }; - - printf("starting.\n"); - - if (strcmp(argv[1],"abort") == 0) { - abort_crash(0); - } else if (strcmp(argv[1],"seg") ==0) { - seg_crash(0,1,2); - } else if (strcmp(argv[1],"bus") == 0) { - bus_crash(0); - } else if (strcmp(argv[1],"ret") == 0) { - call_func(4,abort_crash); - } else if (strcmp(argv[1],"test") == 0) { - test(-1000,abort_crash); - } else if (strcmp(argv[1],"double") == 0) { - double_crash(3.14159,2.1828); - } else if (strcmp(argv[1],"math") == 0) { - math_crash(3,0); - } else if (strcmp(argv[1],"type") == 0) { - type_crash(34,42,17, 3.14159, 2.1828, foo, &foo); - } - multi(3,5,10,3.14); -} diff --git a/Tools/WAD/Wad/default.c b/Tools/WAD/Wad/default.c deleted file mode 100644 index fc72a9e08..000000000 --- a/Tools/WAD/Wad/default.c +++ /dev/null @@ -1,311 +0,0 @@ -/* ----------------------------------------------------------------------------- - * default.c - * - * Default signal handler. Just prints a stack trace and returns. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -#include - - -/* This function tries to produce some kind of sensible argument - string for a stack frame. If no debugging information is available, - we'll just dump the %i0-%i5 registers in hex. If debugging information - is available, we'll try to do something a little more sensible */ - -char *wad_arg_string(WadFrame *frame) { - static char str[1024]; - WadLocal *wp; - long *stack; - long *nextstack; - long *prevstack; - int i; - WadFrame *nf; - WadFrame *pf; - - nf = frame->next; - if (nf) - nextstack = (long *) nf->stack; - else - nextstack = 0; - - pf = frame->prev; - if (pf) - prevstack = (long *) pf->stack; - else - prevstack = 0; - - str[0] = 0; - stack = (long *) frame->stack; - - -#ifdef WAD_LINUX - if (!nf) { - return ""; - } -#endif - - if ((frame->debug_nargs < 0) || (0)){ - /* No argument information is available. If we are on SPARC, we'll dump - the %in registers since these usually hold input parameters. On - Linux, we do nothing */ - -#ifdef WAD_SOLARIS - for (i = 0; i < 6; i++) { - wad_strcat(str,"0x"); - wad_strcat(str,wad_format_hex((unsigned long) stack[8+i],0)); - if (i < 5) - wad_strcat(str,","); - } -#endif - } else { - /* We were able to get some argument information out the debugging table */ - wp = frame->debug_args; - for (i = 0; i < frame->debug_nargs; i++, wp = wp->next) { - wad_strcat(str,wp->name); - wad_strcat(str,"="); - wad_strcat(str,wad_format_var(wp)); - if (i < (frame->debug_nargs-1)) wad_strcat(str,","); - } - } - return str; - -} - -char *wad_strip_dir(char *name) { - char *c; - /* printf("strip: '%s'\n", name); */ - c = name + strlen(name); - while (c != name) { - if (*c == '/') { - c++; - return c; - } - c--; - } - return name; -} - - - -static char *src_file = 0; -static int src_len = 0; -static char src_path[1024] = ""; - -/* Opens up a source file and tries to locate a specific line number */ - -char *wad_load_source(char *path, int line) { - int fd; - char *c; - char *start; - int n; - - if (strcmp(src_path,path)) { - if (src_file) { - munmap(src_file, src_len); - src_file = 0; - src_len = 0; - } - fd = open(path, O_RDONLY); - if (fd < 0) return 0; - src_len = lseek(fd, 0, SEEK_END); - lseek(fd,0,SEEK_SET); - src_file = (char *)mmap(NULL,src_len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - if (src_file == MAP_FAILED) { - close(fd); - return 0; - } - close(fd); - wad_strcpy(src_path,path); - } - n = 0; - start = src_file; - c = src_file; - while (n < src_len) { - if (*c == '\n') { - line--; - if (line == 0) { - return start; - } - start = c+1; - } - c++; - n++; - } - return 0; -} - -void wad_release_source() { - if (src_file) { - munmap(src_file,src_len); - src_file = 0; - src_len = 0; - src_path[0] = 0; - } -} - -/* ----------------------------------------------------------------------------- - * wad_debug_src_code(WadFrame *f) - * - * Get source code for a frame - * ----------------------------------------------------------------------------- */ - -char *wad_debug_src_string(WadFrame *f, int window) { - static char temp[16384]; - - if (f->loc_srcfile && strlen(f->loc_srcfile) && (f->loc_line > 0)) { - char *line, *c; - int i; - int first, last; - first = f->loc_line - window; - last = f->loc_line + window; - if (first < 1) first = 1; - line = wad_load_source(f->loc_srcfile,first); - if (line) { - wad_strcpy(temp,f->loc_srcfile); - wad_strcat(temp,", line "); - wad_strcat(temp,wad_format_signed(f->loc_line,-1)); - wad_strcat(temp,"\n\n"); - for (i = first; i <= last; i++) { - if (i == f->loc_line) wad_strcat(temp," => "); - else wad_strcat(temp," "); - c = strchr(line,'\n'); - if (c) { - *c = 0; - wad_strcat(temp,line); - wad_strcat(temp,"\n"); - *c = '\n'; - } else { - wad_strcat(temp,line); - wad_strcat(temp,"\n"); - break; - } - line = c+1; - } - f->debug_srcstr = wad_strdup(temp); - return f->debug_srcstr; - } - } - f->debug_srcstr = 0; - return 0; -} - -/* ----------------------------------------------------------------------------- - * wad_debug_make_strings(WadFrame *f) - * - * This function walks the stack trace and tries to generate a debugging string - * ----------------------------------------------------------------------------- */ - -void -wad_debug_make_strings(WadFrame *f) { - static char msg[16384]; - while (f) { - wad_strcpy(msg,"#"); - wad_strcat(msg,wad_format_signed(f->frameno,3)); - wad_strcat(msg," 0x"); - wad_strcat(msg,wad_format_hex(f->pc,1)); - wad_strcat(msg," in "); - wad_strcat(msg, f->sym_name ? f->sym_name : "?"); - wad_strcat(msg,"("); - wad_strcat(msg,wad_arg_string(f)); - wad_strcat(msg,")"); - if (f->loc_srcfile && strlen(f->loc_srcfile)) { - wad_strcat(msg," in '"); - wad_strcat(msg, wad_strip_dir(f->loc_srcfile)); - wad_strcat(msg,"'"); - if (f->loc_line > 0) { - wad_strcat(msg,", line "); - wad_strcat(msg,wad_format_signed(f->loc_line,-1)); - /* Try to locate the source file */ - wad_debug_src_string(f, WAD_SRC_WINDOW); - } - } else { - if (f->loc_objfile && strlen(f->loc_objfile)) { - wad_strcat(msg," from '"); - wad_strcat(msg, wad_strip_dir(f->loc_objfile)); - wad_strcat(msg,"'"); - } - } - wad_strcat(msg,"\n"); - f->debug_str = wad_strdup(msg); - f = f->next; - } -} - -/* Dump trace to a file */ -void wad_dump_trace(int fd, int signo, WadFrame *f, char *ret) { - static char buffer[128]; - char *srcstr = 0; - - switch(signo) { - case SIGSEGV: - write(fd,"WAD: Segmentation fault.\n", 25); - break; - case SIGBUS: - write(fd,"WAD: Bus error.\n",17); - break; - case SIGABRT: - write(fd,"WAD: Abort.\n",12); - break; - case SIGFPE: - write(fd,"WAD: Floating point exception.\n", 31); - break; - case SIGILL: - write(fd,"WAD: Illegal instruction.\n", 26); - break; - default: - sprintf(buffer,"WAD: Signal %d\n", signo); - write(fd,buffer,strlen(buffer)); - break; - } - /* Find the last exception frame */ - - while (f && !(f->last)) { - f = f->next; - } - - while (f) { - write(fd,f->debug_str,strlen(f->debug_str)); - if (f->debug_srcstr) { - srcstr = f->debug_srcstr; - } - f = f->prev; - } - if (srcstr) { - write(fd,"\n",1); - write(fd,srcstr,strlen(srcstr)); - write(fd,"\n",1); - } -} - -/* ----------------------------------------------------------------------------- - * Default callback - * ----------------------------------------------------------------------------- */ - -void wad_default_callback(int signo, WadFrame *f, char *ret) { - wad_dump_trace(2,signo,f,ret); -} - diff --git a/Tools/WAD/Wad/demangle.c b/Tools/WAD/Wad/demangle.c deleted file mode 100644 index 6b8b541a2..000000000 --- a/Tools/WAD/Wad/demangle.c +++ /dev/null @@ -1,36 +0,0 @@ -/* ----------------------------------------------------------------------------- - * demangle.c - * - * This file performs C++ partial name demangling to the extent that it - * seems reasonable. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -char *wad_cplus_demangle(WadSymbol *ws) { - static char buffer[4096]; - strcpy(buffer,ws->name); - return buffer; -} diff --git a/Tools/WAD/Wad/elf.c b/Tools/WAD/Wad/elf.c deleted file mode 100644 index 5a2947b02..000000000 --- a/Tools/WAD/Wad/elf.c +++ /dev/null @@ -1,428 +0,0 @@ -/* ----------------------------------------------------------------------------- - * elf.c - * - * ELF file management. This file contains functions for accessing ELF - * file data from a raw memory mapped ELF file (as performed by the - * functions in object.c). - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -#ifdef WAD_SOLARIS -#include -#endif -#ifdef WAD_LINUX -#include -#endif - -/* --- What's needed here (high level interface) : - - Mapping of addresses to symbols - - Mapping of symbols to file+line -*/ - - -/* ----------------------------------------------------------------------------- - * wad_elf_check() - * - * Checks to see if an object file is an ELF file. Returns 1 on success and - * changes the type flag of wo to indicate the type of ELF file. - * ----------------------------------------------------------------------------- */ - -int -wad_elf_check(WadObjectFile *wo) { - if (strncmp((char *)wo->ptr,ELFMAG, SELFMAG) != 0) - return 0; - - /* Probably need to put some kind of 32/64 bit check here */ - return 1; -} - -/* ----------------------------------------------------------------------------- - * wad_elf_phdrcnt() - * - * Return number of entries in the ELF program header section - * ----------------------------------------------------------------------------- */ - -int -wad_elf_phdrcnt(WadObjectFile *wo) { - Elf32_Ehdr *eh; - - eh = (Elf32_Ehdr *) wo->ptr; - return eh->e_phnum; -} - -/* ----------------------------------------------------------------------------- - * wad_elf_phdrpos() - * - * Return the location of the ELF program header. - * ----------------------------------------------------------------------------- */ - -void * -wad_elf_phdrpos(WadObjectFile *wo) { - Elf32_Ehdr *eh; - char *c; - eh = (Elf32_Ehdr *) wo->ptr; - c = (char *) wo->ptr; - return (void *) (c+eh->e_phoff); -} - -/* ----------------------------------------------------------------------------- - * wad_elf_shdrcnt() - * - * Return number of entries in the ELF section header - * ----------------------------------------------------------------------------- */ - -int -wad_elf_shdrcnt(WadObjectFile *wo) { - Elf32_Ehdr *eh; - - eh = (Elf32_Ehdr *) wo->ptr; - return eh->e_shnum; -} - - -/* ----------------------------------------------------------------------------- - * wad_elf_shdrpos() - * - * Return the location of the section headers - * ----------------------------------------------------------------------------- */ - -void * -wad_elf_shdrpos(WadObjectFile *wo) { - Elf32_Ehdr *eh; - char *c; - eh = (Elf32_Ehdr *) wo->ptr; - c = (char *) wo->ptr; - return (void *) (c+eh->e_shoff); -} - -/* ----------------------------------------------------------------------------- - * wad_elf_section_header() - * - * Get a specific section number - * ----------------------------------------------------------------------------- */ - -void *wad_elf_section_header(WadObjectFile *wo, int sn) { - Elf32_Ehdr *eh; - char *r; - - eh = (Elf32_Ehdr *) wo->ptr; - if ((sn < 0) || (sn >= eh->e_shnum)) return 0; - - r = (char *) wad_elf_shdrpos(wo) + (sn*eh->e_shentsize); - return (void *) r; -} - -/* ----------------------------------------------------------------------------- - * wad_elf_section_data() - * - * Get section data - * ----------------------------------------------------------------------------- */ - -void *wad_elf_section_data(WadObjectFile *wo, int sn) { - Elf32_Shdr *sh; - char *r; - - sh = (Elf32_Shdr *) wad_elf_section_header(wo,sn); - if (!sh) return 0; - - r = ((char *) wo->ptr) + sh->sh_offset; - return r; -} - -/* ----------------------------------------------------------------------------- - * wad_elf_section_size() - * Return section size - * ----------------------------------------------------------------------------- */ - -int wad_elf_section_size(WadObjectFile *wo, int sn) { - Elf32_Shdr *sh; - - sh = (Elf32_Shdr *) wad_elf_section_header(wo,sn); - if (!sh) return -1; - return sh->sh_size; -} - -/* ----------------------------------------------------------------------------- - * wad_elf_section_name() - * - * Returns the name of an ELF section - * ----------------------------------------------------------------------------- */ - -char *wad_elf_section_name(WadObjectFile *wo, int sn) { - Elf32_Ehdr *eh; - Elf32_Shdr *sh; - char *sectionstr; - - eh = (Elf32_Ehdr *) wo->ptr; - - /* Get the string table */ - sectionstr = (char *) wad_elf_section_data(wo,eh->e_shstrndx); - if (!sectionstr) { - return 0; - } - - /* Get the section header for the section */ - sh = (Elf32_Shdr *) wad_elf_section_header(wo,sn); - if (!sh) return 0; - return sectionstr + sh->sh_name; -} - -/* ----------------------------------------------------------------------------- - * wad_elf_section_byname() - * - * Get section data given a section name - * ----------------------------------------------------------------------------- */ - -int -wad_elf_section_byname(WadObjectFile *wo, char *name) { - int i; - char *sn; - int n; - - n = wad_elf_shdrcnt(wo); - for (i = 0; i pc; - base = (unsigned long) f->segment->base; - - nsymtab = wad_elf_section_byname(f->object,secname); - if (nsymtab < 0) return 0; - nstrtab = wad_elf_section_byname(f->object,strname); - if (nstrtab < 0) return 0; - - symtab_size = wad_elf_section_size(f->object,nsymtab); - sym = (Elf32_Sym *) wad_elf_section_data(f->object,nsymtab); - str = (char *) wad_elf_section_data(f->object,nstrtab); - - nsym = (symtab_size/sizeof(Elf32_Sym)); - for (i = 0; i < nsym; i++) { - name = str + sym[i].st_name; - /* Look for filename in case the symbol maps to a local symbol */ - if (ELF32_ST_TYPE(sym[i].st_info) == STT_FILE) { - localfile = name; - } - if (wad_debug_mode & DEBUG_SYMBOL_SEARCH) { - wad_printf("%x(%x): %s %x + %x, %x, %x\n", base, vaddr, name, sym[i].st_value, sym[i].st_size, sym[i].st_info, sym[i].st_shndx); - } - if (((base + sym[i].st_value) <= vaddr) && (vaddr <= (base+sym[i].st_value + sym[i].st_size))) { -#ifdef WAD_LINUX - /* If the section index is 0, the symbol is undefined */ - if (sym[i].st_shndx == 0) continue; -#endif - f->sym_name = name; - f->sym_nlen = strlen(name); - f->sym_base = base + sym[i].st_value; - f->sym_size = sym[i].st_size; - if (ELF32_ST_BIND(sym[i].st_info) == STB_LOCAL) { - f->sym_file = localfile; - f->sym_bind = SYM_LOCAL; - } else { - f->sym_bind = SYM_GLOBAL; - } - return 1; - } - } - return 0; -} - -void -wad_elf_find_symbol(WadFrame *f) { - /* We simply try a few possible sections */ - if (elf_search_section_sym(f,".symtab",".strtab")) return; - if (elf_search_section_sym(f,".dynsym",".dynstr")) return; - - /* Hmmm. No match found. Oh well */ - return; -} - -/* ----------------------------------------------------------------------------- - * wad_elf_debug_info() - * - * Gather debugging information about a function (if possible) - * ----------------------------------------------------------------------------- */ - -int -wad_elf_debug_info(WadFrame *f) { - int nstab, nstabstr, nstabindex, nstabindexstr, nstabexcl, nstabexclstr; - int ret; - void *stab; - char *stabstr; - int stabsize; - - nstab = wad_elf_section_byname(f->object,".stab"); - nstabstr = wad_elf_section_byname(f->object,".stabstr"); - nstabindex = wad_elf_section_byname(f->object,".stab.index"); - nstabindexstr = wad_elf_section_byname(f->object,".stab.indexstr"); - nstabexcl = wad_elf_section_byname(f->object,".stab.excl"); - nstabexclstr = wad_elf_section_byname(f->object,".stab.exclstr"); - -#ifdef DEBUG_DEBUG - wad_printf("nstab = %d\n", nstab); - wad_printf("nstabstr = %d\n", nstabstr); - wad_printf("nstabindex = %d\n", nstabindex); - wad_printf("nstabindexstr = %d\n", nstabindexstr); - wad_printf("nstabexcl = %d\n", nstabexcl); - wad_printf("nstabexclstr = %d\n", nstabexclstr); -#endif - - /* Now start searching stabs */ - - /* Look in the .stab section */ - if (nstab > 0) { - stab = wad_elf_section_data(f->object,nstab); - stabsize = wad_elf_section_size(f->object,nstab); - stabstr = (char *) wad_elf_section_data(f->object,nstabstr); - - - if (wad_search_stab(stab,stabsize,stabstr, f)) return 1; - } - - /* Look in the .stab.excl section. A solaris oddity? */ - - if (nstabexcl > 0) { - stab = wad_elf_section_data(f->object,nstabexcl); - stabsize = wad_elf_section_size(f->object, nstabexcl); - stabstr = (char *) wad_elf_section_data(f->object, nstabexclstr); - - if (wad_search_stab(stab,stabsize,stabstr, f)) return 1; - } - - /* Look in the .stab.index section. A Solaris oddity? */ - if (nstabindex > 0) { - - stab = wad_elf_section_data(f->object,nstabindex); - stabsize = wad_elf_section_size(f->object, nstabindex); - stabstr = (char *) wad_elf_section_data(f->object, nstabindexstr); - - if (wad_search_stab(stab,stabsize,stabstr, f)) { - /* Hmmm. Might be in a different file */ - WadObjectFile *wo1, *wold; - char objfile[MAX_PATH]; - /* printf("DEBUG %s\n", f->sym_name); */ - wad_strcpy(objfile, f->loc_objfile); - wo1 = wad_object_load(objfile); - if (wo1) { - wold = f->object; - f->object = wo1; - wad_find_debug(f); - f->object = wold; - return ret; - } else { - /* wad_printf("couldn't load %s\n", objfile); */ - } - /* if (!ret) return wad_search_stab(stab,stabsize,stabstr,f);*/ - return ret; - } - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * wad_elf_debug() - * - * Print some debugging information about an object - * ----------------------------------------------------------------------------- */ - -void -wad_elf_debug(WadObjectFile *wo) { - int i; - wad_printf("ELF Debug : obj = %x (%s)\n", wo, wo->path); - wad_printf(" phdrcnt = %d\n", wad_elf_phdrcnt(wo)); - wad_printf(" phdrpos = %x\n", wad_elf_phdrpos(wo)); - wad_printf(" shdrcnt = %d\n", wad_elf_shdrcnt(wo)); - wad_printf(" shdrpos = %x\n", wad_elf_shdrpos(wo)); - for (i = 0; i < wad_elf_shdrcnt(wo); i++) { - wad_printf(" section '%s': data = 0x%x, size = %d\n", - wad_elf_section_name(wo,i), - wad_elf_section_data(wo,i), - wad_elf_section_size(wo,i)); - } -} - -/* general purpose functions exposed to the outside world */ - -/* ----------------------------------------------------------------------------- - * wad_find_symbol() - * ----------------------------------------------------------------------------- */ - -void -wad_find_symbol(WadFrame *f) { - if (wad_debug_mode & DEBUG_SYMBOL) { - wad_printf("wad: Searching for 0x%08x --> ", f->pc); - } - if (f->object) - wad_elf_find_symbol(f); - if (wad_debug_mode & DEBUG_SYMBOL) { - if (f->sym_name) { - wad_printf("%s", f->sym_name); - if (f->sym_file) - wad_printf(" in '%s'\n", f->sym_file); - else - wad_printf("\n"); - } else { - wad_printf("?\n"); - } - } -} - -void -wad_find_debug(WadFrame *f) { - /* if (f->debug_check) return; */ - if (f->object) { - wad_elf_debug_info(f); - } - /* f->debug_check = 1; */ -} - - - diff --git a/Tools/WAD/Wad/init.c b/Tools/WAD/Wad/init.c deleted file mode 100644 index fb44b8d1c..000000000 --- a/Tools/WAD/Wad/init.c +++ /dev/null @@ -1,113 +0,0 @@ -/* ----------------------------------------------------------------------------- - * init.c - * - * Initialize the wad system. This sets up a signal handler for catching - * SIGSEGV, SIGBUS, and SIGABRT. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -/* Debugging flag */ -int wad_debug_mode = 0; - -/* Initialize wad */ -void wad_init() { - static int init = 0; - - wad_memory_init(); - if (getenv("WAD_DEBUG_SEGMENT")) { - wad_debug_mode |= DEBUG_SEGMENT; - } - if (getenv("WAD_DEBUG_SYMBOL")) { - wad_debug_mode |= DEBUG_SYMBOL; - } - - if (getenv("WAD_DEBUG_OBJECT")) { - wad_debug_mode |= DEBUG_OBJECT; - } - - if (getenv("WAD_DEBUG_FILE")) { - wad_debug_mode |= DEBUG_FILE; - } - - if (getenv("WAD_DEBUG_HOLD")) { - wad_debug_mode |= DEBUG_HOLD; - } - - if (getenv("WAD_DEBUG_STABS")) { - wad_debug_mode |= DEBUG_STABS; - } - - if (getenv("WAD_DEBUG_RETURN")) { - wad_debug_mode |= DEBUG_RETURN; - } - - if (getenv("WAD_DEBUG_SYMBOL_SEARCH")) { - wad_debug_mode |= DEBUG_SYMBOL_SEARCH; - } - - if (getenv("WAD_DEBUG_INIT")) { - wad_debug_mode |= DEBUG_INIT; - } - - if (getenv("WAD_DEBUG_STACK")) { - wad_debug_mode |= DEBUG_STACK; - } - - if (getenv("WAD_DEBUG_UNWIND")) { - wad_debug_mode |= DEBUG_UNWIND; - } - - if (getenv("WAD_DEBUG_SIGNAL")) { - wad_debug_mode |= DEBUG_SIGNAL; - } - - if (getenv("WAD_NOSTACK")) { - wad_debug_mode |= DEBUG_NOSTACK; - } - - if (getenv("WAD_ONESHOT")) { - wad_debug_mode |= DEBUG_ONESHOT; - } - - if (getenv("WAD_DEBUG_STRING")) { - wad_debug_mode |= DEBUG_STRING; - } - - if (getenv("WAD_DEBUG_MEMORY")) { - wad_debug_mode |= DEBUG_MEMORY; - } - - if (wad_debug_mode & DEBUG_INIT) { - wad_printf("WAD: initializing\n"); - } - - - if (!init) { - wad_signal_init(); - wad_object_reset(); - } - init = 1; -} diff --git a/Tools/WAD/Wad/io.c b/Tools/WAD/Wad/io.c deleted file mode 100644 index afbb3093a..000000000 --- a/Tools/WAD/Wad/io.c +++ /dev/null @@ -1,107 +0,0 @@ -/* ----------------------------------------------------------------------------- - * io.c - * - * This file provides some I/O routines so that WAD can produce - * debugging output without using buffered I/O. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" -#include - -static char cvs[] = "$Id$"; - -/* Utility functions used to generate strings that are guaranteed not to - rely upon malloc() and related functions */ - -char *wad_format_hex(unsigned long u, int leading) { - static char result[64]; - int i; - char *c; - c = &result[63]; - *c = 0; - for (i = 0; i < (sizeof(unsigned long)*2); i++) { - int d; - d = (int) (u & 0xf); - c--; - if (d < 10) { - *c = '0' + d; - } else { - *c = 'a' + (d-10); - } - if (!u && !leading) break; - u = u >> 4; - } - return c; -} - -char *wad_format_unsigned(unsigned long u, int width) { - static char result[128]; - static char digits[] = "0123456789"; - char *c, *w; - int count = 0; - int i; - c = &result[64]; - while (u) { - int digit = u % 10; - *(--c) = digits[digit]; - count++; - u = u / 10; - } - if (!count) { - *(--c) = '0'; - count++; - } - w = &result[64]; - for (i = count; i < width; i++) { - *(w++) = ' '; - } - *w = 0; - return c; -} - -char *wad_format_signed(signed long s, int width) { - static char result[128]; - unsigned long u; - char *c = result; - if (s < 0) { - *(c++) = '-'; - width--; - u = (unsigned long) (-s); - if (u == 0) { - u = (unsigned long) s; - } - } else { - u = (unsigned long) s; - } - *c = 0; - wad_strcat(result, wad_format_unsigned(u,width)); - return result; -} - - -void wad_printf(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - vfprintf(stderr,fmt,ap); - va_end(ap); -} diff --git a/Tools/WAD/Wad/libwadpl.pm b/Tools/WAD/Wad/libwadpl.pm deleted file mode 100644 index 21a01db46..000000000 --- a/Tools/WAD/Wad/libwadpl.pm +++ /dev/null @@ -1,8 +0,0 @@ -package libwadpl; -require Exporter; -require DynaLoader; -@ISA = qw(Exporter DynaLoader); -package libwadpl; -bootstrap libwadpl; -@EXPORT = qw( ); -1; diff --git a/Tools/WAD/Wad/main.cxx b/Tools/WAD/Wad/main.cxx deleted file mode 100644 index 1cf5ce958..000000000 --- a/Tools/WAD/Wad/main.cxx +++ /dev/null @@ -1,14 +0,0 @@ -extern "C" { -#include "wad.h" -} - -/* This is a sick hack to force initialization upon loading */ - -class StartDebug { -public: - StartDebug() { - wad_init(); - } -}; - -static StartDebug s; diff --git a/Tools/WAD/Wad/makehandler.py b/Tools/WAD/Wad/makehandler.py deleted file mode 100755 index c4e23a654..000000000 --- a/Tools/WAD/Wad/makehandler.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/local/bin/python -import string -f = open("wadhandler.pl") -data = f.read() -f.close() - -data = string.replace(data,"\\", "\\\\") -data = string.replace(data,"\"", "\\\"") -data = string.replace(data,"\n", "\\n\\\n") - -f = open("wad_perl_handler.c","w") - -f.write("static char wad_perl_handler[] = \"") -f.write(data) -f.write("\";\n"); -f.close() - - - - diff --git a/Tools/WAD/Wad/memory.c b/Tools/WAD/Wad/memory.c deleted file mode 100644 index 0260cb89e..000000000 --- a/Tools/WAD/Wad/memory.c +++ /dev/null @@ -1,174 +0,0 @@ -/* ----------------------------------------------------------------------------- - * memory.c - * - * This file provides simple mmap() based memory management for WAD. Since - * the process heap-allocator might be corrupted when WAD is invoked, we - * have to do all of our own memory management. However, since WAD mostly - * just collects data, we only provide the function wad_malloc(). To - * release all allocated memory, the wad_release_memory() function should - * be used. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -typedef struct _WadMemory { - int npages; /* Number of pages */ - int last; /* Last offset in page */ - struct _WadMemory *next; /* Pointer to next allocation */ -} WadMemory; - -static WadMemory *current = 0; /* Current memory block */ -static int pagesize = 0; /* System page size */ -static int devzero = 0; -static int npalloc = 8; /* Number of pages per alloc */ - -/* ----------------------------------------------------------------------------- - * wad_memory_init() - * - * Initialize the WAD allocator. - * ----------------------------------------------------------------------------- */ - -int wad_memory_init() { - pagesize = getpagesize(); - devzero = open("/dev/zero", O_RDWR); - if (devzero < 0) { - wad_printf("WAD: couldn't open /dev/zero.\n"); - return -1; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * wad_page_alloc() - * - * Allocate pages using mmap - * ----------------------------------------------------------------------------- */ - -void *wad_page_alloc(int npages) { - void *m; - m = mmap(NULL, npages*pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE, devzero, 0); - if (((long) m) == -1) return 0; - /* printf("page_alloc: %x - %x\n", m, ((char *) m) + npages*pagesize); */ - return m; -} - -/* ----------------------------------------------------------------------------- - * wad_malloc() - * - * Allocate memory using mmap(). If the allocation is smaller than half a page, - * We'll look at current to see if there is enough space. If so, we'll just - * use that memory. Otherwise, we'll allocate a new page. If the allocation - * request is larger than a page, we'll round up to the nearest page size and - * do a special allocation. - * ----------------------------------------------------------------------------- */ - -void *wad_malloc(int nbytes) { - void *ptr; - WadMemory *wm; - char *c; - int npages; - /* wad_printf("wad_malloc: %d\n", nbytes); */ - if (nbytes >= ((npalloc*pagesize) >> 2)) { - /* Large allocation. */ - npages = ((nbytes + sizeof(WadMemory))/pagesize) + 1; - ptr = wad_page_alloc(npages); - if (!ptr) return 0; - wm = (WadMemory *)ptr; - wm->npages = npages; - wm->last = sizeof(WadMemory) + 8; - wm->next = current; - current = wm; - c = (char *) current + (current->last); - current->last += ((nbytes & ~0x7) + 8); - return c; - } - /* Small allocation. See if there are any regions big enough */ - wm = current; - while (wm) { - if (((wm->npages*pagesize) - wm->last) > nbytes) { - /* Yep. Found a region */ - break; - } - wm = wm->next; - } - if (!wm) { - /* wad_printf("wad_malloc: new page\n", nbytes);*/ - wm = (WadMemory *) wad_page_alloc(npalloc); - if (!wm) return 0; - wm->npages = npalloc; - wm->last = sizeof(WadMemory) + 8; - wm->next = current; - current = wm; - } - c = ((char *) wm) + (wm->last); - wm->last += ((nbytes & ~0x7) + 8); - return c; -} - -/* ----------------------------------------------------------------------------- - * wad_strdup() - * - * Duplicate a string - * ----------------------------------------------------------------------------- */ - -char *wad_strdup(const char *c) { - char *t; - if (!c) c = ""; - t = (char *) wad_malloc(strlen(c)+1); - wad_strcpy(t,c); - return t; -} - -/* ----------------------------------------------------------------------------- - * wad_memcpy() - * ----------------------------------------------------------------------------- */ - -void wad_memcpy(void *t, const void *s, unsigned len) { - char *tc, *sc; - int i; - tc = (char *) t; - sc = (char *) s; - for (i = 0; i < len; i++, tc++, sc++) - *tc = *sc; -} - -/* ----------------------------------------------------------------------------- - * wad_memory_debug() - * ----------------------------------------------------------------------------- */ - -void wad_memory_debug() { - int total_alloc = 0; - int inuse = 0; - WadMemory *m; - if (wad_debug_mode & DEBUG_MEMORY) { - m = current; - while (m) { - total_alloc += (m->npages)*pagesize; - inuse += m->last; - m = m->next; - } - wad_printf("WAD: memory allocated %d bytes (%d bytes used).\n", total_alloc, inuse); - } -} diff --git a/Tools/WAD/Wad/object.c b/Tools/WAD/Wad/object.c deleted file mode 100644 index f13d6b320..000000000 --- a/Tools/WAD/Wad/object.c +++ /dev/null @@ -1,303 +0,0 @@ -/* ----------------------------------------------------------------------------- - * object.c - * - * This file provides access to raw object files, executables, and - * library files. Memory management is handled through mmap() to - * avoid the use of heap/stack space. - * - * All of the files and objects created by this module persist - * until the process exits. Since WAD may be invoked multiple times - * over the course of program execution, it makes little sense to keep - * loading and unloading files---subsequent invocations of the handler - * can simply used previously loaded copies. Caveat: things probably - * won't work right if a program is doing lots of low-level manipulation - * of the dynamic loader. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -#include - -typedef struct WadFile { - void *addr; /* Base address of the file */ - int size; /* Size in bytes */ - char *path; /* Path name */ - struct WadFile *next; /* Next file */ -} WadFile; - -static WadFile *wad_files = 0; /* Linked list of loaded files */ - -/* private function to manage the loading of raw files into memory */ -static WadFile * -load_file(const char *path) { - int fd; - WadFile *wf = wad_files; - - if (wad_debug_mode & DEBUG_FILE) { - wad_printf("wad: Loading file '%s' ... ", path); - } - while (wf) { - if (strcmp(wf->path,path) == 0) { - if (wad_debug_mode & DEBUG_FILE) wad_printf("cached.\n"); - return wf; - } - wf = wf->next; - } - fd = open(path, O_RDONLY); - if (fd < 0) { - if (wad_debug_mode & DEBUG_FILE) wad_printf("not found!\n"); - return 0; /* Doesn't exist. Oh well */ - } - if (wad_debug_mode & DEBUG_FILE) wad_printf("loaded.\n"); - wf = (WadFile *) wad_malloc(sizeof(WadFile)); - wf->path = wad_strdup(path); - - /* Get file length */ - wf->size = lseek(fd,0,SEEK_END); - lseek(fd,0,SEEK_SET); - - /* Try to mmap the file */ - wf->addr = mmap(NULL,wf->size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); - close(fd); - if (wf->addr == MAP_FAILED) { - if (wad_debug_mode & DEBUG_FILE) wad_printf("wad: Couldn't mmap '%s'\n", path); - return 0; - } - wf->next = wad_files; - wad_files = wf; - return wf; -} - -static WadObjectFile *wad_objects = 0; /* Linked list of object files */ - -/* ----------------------------------------------------------------------------- - * wad_object_cleanup() - * - * Reset the object file loader. This unmaps the files themselves, but - * memory will leak for object files pointers themselves. - * ----------------------------------------------------------------------------- */ - -void -wad_object_reset() { - WadFile *f = wad_files; - if (wad_debug_mode & DEBUG_OBJECT) { - wad_printf("wad: Releasing all files.\n"); - } - /* Unmap all of the loaded files */ - while (f) { - if (f->addr) { - munmap(f->addr, f->size); - } - f = f->next; - } - /* Reset the linked lists */ - wad_files = 0; - wad_objects = 0; -} - -/* ----------------------------------------------------------------------------- - * wad_object_load() - * - * Load an object file into memory using mmap. Returns 0 if the object does - * not exist or if we're out of memory. - * ----------------------------------------------------------------------------- */ - -WadObjectFile * -wad_object_load(const char *path) { - WadObjectFile *wo; - WadFile *wf; - WadObjectFile *wad_arobject_load(const char *path, const char *name); - - if (wad_debug_mode & DEBUG_OBJECT) { - wad_printf("wad: Loading object '%s'", path); - } - for (wo = wad_objects; wo; wo=wo->next) { - if (strcmp(wo->path,path) == 0) { - if (wad_debug_mode & DEBUG_OBJECT) { - wad_printf(" (cached)\n"); - } - return wo; - } - } - if (wad_debug_mode & DEBUG_OBJECT) { - wad_printf("\n"); - } - /* Didn't find it. Now we need to go load some files */ - - /* If this is an archive reference like /path/libfoo.a(blah.o), we need to - split up the name a little bit */ - { - char realfile[MAX_PATH]; - char *objfile; - char *c; - c = strchr(path,'('); - if (c) { - wad_strcpy(realfile,path); - c = strchr(realfile,'('); - *c = 0; - objfile = c+1; - c = strchr(objfile,')'); - *c = 0; - - /* Okay, I'm going to attempt to map this as a library file */ - wo = wad_arobject_load(realfile,objfile); - if (wo) { - /* Reset the path */ - wo->path = wad_strdup(path); - wo->next = wad_objects; - wad_objects = wo; - return wo; - } - } - } - wf = load_file(path); - if (!wf) return 0; - - wo = (WadObjectFile *) wad_malloc(sizeof(WadObjectFile)); - wo->path = wad_strdup(path); - wo->ptr = wf->addr; - wo->len = wf->size; - wo->next = wad_objects; - wad_objects = wo; - return wo; -} - -/* ----------------------------------------------------------------------------- - * wad_arobject_load() - * - * Load an object file stored in an archive file created with an archive. The - * pathname should be the path of the .a file and robjname should be the name - * of the object file stored in the object file. - * ----------------------------------------------------------------------------- */ - -WadObjectFile * -wad_arobject_load(const char *arpath, const char *robjname) { - WadObjectFile *wo; - WadFile *wf; - int arlen; - char *arptr; - struct ar_hdr *ah; - int offset; - int msize; - char *strtab = 0; - int sobjname; - char objname[MAX_PATH]; - - wad_strcpy(objname,robjname); - wad_strcat(objname,"/"); - sobjname = strlen(objname); - - wf = load_file(arpath); - if (!wf) return 0; /* Doesn't exit */ - - arptr = (char *) wf->addr; - arlen = wf->size; - - /* Now take a look at the archive */ - if (strncmp(arptr,ARMAG,SARMAG) == 0) { - /* printf("Got an archive\n"); */ - } else { - return 0; - } - - /* Search the archive for the request member */ - strtab = 0; - offset = SARMAG; - while (offset < arlen) { - char mname[MAX_PATH]; - ah = (struct ar_hdr *) (arptr + offset); - if (strncmp(ah->ar_name,"// ", 3) == 0) { - strtab = arptr + offset + sizeof(struct ar_hdr); - } - msize = atoi(ah->ar_size); - - offset += sizeof(struct ar_hdr); - /* Try to figure out the filename */ - if ((ah->ar_name[0] == '/') && (isdigit(ah->ar_name[1]))) { - int soff; - char *e; - /* Must be in the string offset table */ - soff = atoi(ah->ar_name+1); - if (!strtab) { - /* No offset table */ - return 0; - } - e = strchr(strtab+soff,'\n'); - if (e) { - strncpy(mname, strtab+soff, (e - (strtab+soff))); - mname[e-(strtab+soff)] = 0; - } else { - mname[0] = 0; - } - } else { - /* Name must be in the name field */ - strncpy(mname,ah->ar_name,16); - mname[16] = 0; - } - /* Compare the names */ - if (strncmp(mname,objname,sobjname) == 0) { - /* Found the archive */ - wo = (WadObjectFile *) wad_malloc(sizeof(WadObjectFile)); - wo->ptr = (void *) (arptr + offset); - wo->len = msize; - wo->path = 0; - return wo; - } - offset += msize; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * wad_find_object(WadFrame *f) - * - * Given a stack frame. Try to locate the object file - * ----------------------------------------------------------------------------- */ - -void wad_find_object(WadFrame *f) { - if (f->segment) { - f->object = wad_object_load(f->segment->mappath); - } -} - -/* ----------------------------------------------------------------------------- - * wad_file_check(void *addr) - * - * Given an address, this function checks to see if it corresponds to a file - * we already mapped. - * ----------------------------------------------------------------------------- */ - -int -wad_file_check(void *addr) { - WadFile *f = wad_files; - while (f) { - if ((((char *) f->addr) <= ((char *) addr)) && - (((char *) addr) < (((char *) f->addr) + f->size))) { - return 1; - } - f = f->next; - } - return 0; -} diff --git a/Tools/WAD/Wad/return.c b/Tools/WAD/Wad/return.c deleted file mode 100644 index 909cba314..000000000 --- a/Tools/WAD/Wad/return.c +++ /dev/null @@ -1,69 +0,0 @@ -/* ----------------------------------------------------------------------------- - * return.c - * - * This file manages the set of return-points for the WAD signal handler. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -/* Maximum number of return points */ -#define WAD_NUMBER_RETURN 128 - -static WadReturnFunc return_points[WAD_NUMBER_RETURN]; -static int num_return = 0; - -void wad_set_return(const char *name, long value) { - WadReturnFunc *rp; - rp = &return_points[num_return]; - wad_strcpy(rp->name,name); - rp->value = value; - num_return++; - if (wad_debug_mode & DEBUG_RETURN) { - printf("wad: Setting return ('%s', %d)\n", name,value); - } -} - -void wad_set_returns(WadReturnFunc *rf) { - int i = 0; - while (strlen(rf[i].name)) { - wad_set_return(rf[i].name, rf[i].value); - i++; - } -} - -WadReturnFunc *wad_check_return(const char *name) { - int i; - if (!name) return 0; - for (i = 0; i < num_return; i++) { - if (strcmp(name,return_points[i].name) == 0) { - if (wad_debug_mode & DEBUG_RETURN) { - printf("wad: Found return ('%s', %d)\n", return_points[i].name, return_points[i].value); - } - return &return_points[i]; - } - } - return 0; -} - diff --git a/Tools/WAD/Wad/segment.c b/Tools/WAD/Wad/segment.c deleted file mode 100644 index ec4cf134f..000000000 --- a/Tools/WAD/Wad/segment.c +++ /dev/null @@ -1,227 +0,0 @@ -/* ----------------------------------------------------------------------------- - * segment.c - * - * This file provides access to the virtual memory map of a process - * including the location of the executable, data segments, shared - * libraries, and memory mapped regions. - * - * The primary purpose of this module is to collect this information - * and store it in a form that hides platform specific details (the - * WadSegment structure). - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -/* Include the proper code for reading the segment map */ - -#ifdef WAD_SOLARIS - -/* This code is used to read the process virtual memory map on Solaris machines */ - -static int -segment_open() { - int f; - f = open("/proc/self/map", O_RDONLY); - return f; -} - -static int -segment_read(int fs, WadSegment *s) { - int dz; - int n; - prmap_t pmap; - - n = read(fs, &pmap, sizeof(prmap_t)); - if (n <= 0) return 0; - s->mapname = wad_strdup(pmap.pr_mapname); - s->mappath = (char *) wad_malloc(20+strlen(pmap.pr_mapname)); - wad_strcpy(s->mappath,"/proc/self/object/"); - strcat(s->mappath,pmap.pr_mapname); - s->vaddr = (char *) pmap.pr_vaddr; - - /* This is a solaris oddity. a.out section starts 1 page up, but - symbols are relative to a base of 0 */ - - if (strcmp(s->mapname,"a.out") == 0) s->base = 0; - else s->base = s->vaddr; - - s->size = pmap.pr_size; - s->offset = pmap.pr_offset; - return 1; -} - -#endif /* WAD_SOLARIS */ - -#ifdef WAD_LINUX -static char linux_firstsegment[1024]; -static int linux_first = 1; - -static int -segment_open() { - FILE *f; - f = fopen("/proc/self/maps", "r"); - linux_first =1; - return (int) f; -} - -static int -segment_read(int fd, WadSegment *s) -{ - char pbuffer[1024]; - char *c; - int len; - FILE *fs = (FILE *) fd; - c = fgets(pbuffer,1024,fs); - if (!c) return 0; - - pbuffer[strlen(pbuffer)-1] = 0; /* Chop off endline */ - - /* Break up the field into records */ - /* 0-8 : Starting address - 9-17 : Ending Address - 18 : r - 19 : w - 20 : x - 21 : p - 23-31 : Offset - 49- : Filename */ - - len = strlen(pbuffer); - pbuffer[8] = 0; - pbuffer[17] = 0; - pbuffer[31] = 0; - if (len >= 49) { - s->mapname = wad_strdup(pbuffer+49); - s->mappath = s->mapname; - } else { - s->mapname = ""; - s->mappath = s->mapname; - } - if (linux_first) { - wad_strcpy(linux_firstsegment, s->mappath); - linux_first = 0; - } - s->vaddr = (char *) strtoul(pbuffer,NULL,16); - s->size = strtoul(pbuffer+9,NULL,16) - (long) (s->vaddr); - s->offset = strtoul(pbuffer+23,NULL,16); - if (strcmp(linux_firstsegment, s->mappath) == 0) { - s->base = 0; - } else { - s->base = s->vaddr; - } - s++; - return 1; -} - -#endif /* WAD_LINUX */ - -static WadSegment *segments = 0; /* Linked list of segments */ - -/* ----------------------------------------------------------------------------- - * wad_segment_read() - * - * Read all of the memory segments into a linked list. Any previous segment - * map is simply lost. The only way to reclaim this memory is to call - * wad_release_memory(). - * ----------------------------------------------------------------------------- */ - -int -wad_segment_read() { - int fs; - int n; - WadSegment *s, *lasts; - - segments = 0; - lasts = 0; - fs = segment_open(); - - while (1) { - s = (WadSegment *) wad_malloc(sizeof(WadSegment)); - skip: - n = segment_read(fs,s); - if (n <= 0) break; - if (wad_file_check(s->vaddr)) goto skip; /* Skip files we already loaded */ - s->next = 0; - if (!lasts) { - segments = s; - lasts = s; - } else { - lasts->next = s; - lasts = s; - } - if (wad_debug_mode & DEBUG_SEGMENT) { - wad_printf("wad_segment: read : %08x-%08x, base=%x in %s\n", s->vaddr, ((char *) s->vaddr) + s->size, s->base, s->mappath); - } - } - close(fs); - return 0; -} - -/* ----------------------------------------------------------------------------- - * wad_segment_find() - * - * Try to find the virtual memory segment corresponding to a virtual address. - * If a segment is mapped to a file, this function actually returns the *first* - * segment that is mapped. This is because symbol relocations are always - * performed relative to the beginning of the file (so we need the base address) - * ----------------------------------------------------------------------------- */ - -WadSegment * -wad_segment_find(void *vaddr) { - WadSegment *ls; - WadSegment *s; - char *addr = (char *)vaddr; - - s = segments; - ls = segments; - while (s) { - if (strcmp(s->mapname,ls->mapname) || (!strlen(ls->mapname))) { - ls = s; /* First segment for a given name */ - } - if ((addr >= s->vaddr) && (addr < (s->vaddr + s->size))) { - if (wad_debug_mode & DEBUG_SEGMENT) { - wad_printf("wad_segment: %08x --> %08x-%08x in %s\n", vaddr, s->vaddr, ((char *) s->vaddr) + s->size, s->mappath); - } - return ls; - } - s = s->next; - } - return 0; -} - -/* ----------------------------------------------------------------------------- - * wad_segment_valid() - * - * Checks to see if a memory address is valid or not based on data in the - * segment map - * ----------------------------------------------------------------------------- */ - -int wad_segment_valid(void *vaddr) { - return wad_segment_find(vaddr) ? 1 : 0; -} - - - - diff --git a/Tools/WAD/Wad/signal.c b/Tools/WAD/Wad/signal.c deleted file mode 100644 index 36f89c3c7..000000000 --- a/Tools/WAD/Wad/signal.c +++ /dev/null @@ -1,520 +0,0 @@ -/* ----------------------------------------------------------------------------- - * signal.c - * - * WAD signal handler. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -extern void wad_stab_debug(); - -/* For some odd reason, certain linux distributions do not seem to define the - register constants in a way that is easily accessible to us. This is a hack */ - -#ifdef WAD_LINUX -#ifndef ESP -#define ESP 7 -#endif -#ifndef EBP -#define EBP 6 -#endif -#ifndef EIP -#define EIP 14 -#endif -#ifndef ESI -#define ESI 5 -#endif -#ifndef EDI -#define EDI 4 -#endif -#ifndef EBX -#define EBX 8 -#endif - -#endif - -/* Signal handling stack */ -#define STACK_SIZE 4*SIGSTKSZ -char wad_sig_stack[STACK_SIZE]; - -/* This variable is set if the signal handler thinks that the - heap has overflowed */ - -int wad_heap_overflow = 0; - -static void (*sig_callback)(int signo, WadFrame *data, char *ret) = 0; - -void wad_set_callback(void (*s)(int,WadFrame *,char *ret)) { - sig_callback = s; -} - -/* This bit of nastiness is used to make a non-local return from the - signal handler to a configurable location on the call stack. In a nutshell, - this works by repeatedly calling "restore" to roll back the - register windows and stack pointer. Then we fake a return value and - return to the caller as if the function had actually completed - normally. */ - -int wad_nlr_levels = 0; -static volatile int *volatile nlr_p = &wad_nlr_levels; -long wad_nlr_value = 0; -void (*wad_nlr_func)(void) = 0; - -/* Set the return value from another module */ -void wad_set_return_value(long value) { - wad_nlr_value = value; -} - -/* Set the return function */ -void wad_set_return_func(void(*f)(void)) { - wad_nlr_func = f; -} - -#ifdef WAD_SOLARIS -static void nonlocalret() { - long a; - - a = wad_nlr_value; - /* We never call this procedure as a function. This code - causes an immediate return if someone does this */ - - asm("jmp %i7 + 8"); - asm("restore"); - - /* This is the real entry point */ - /* asm(".globl _returnsignal");*/ - asm(".type _returnsignal,2"); - asm("_returnsignal:"); - - while (*nlr_p > 0) { - (*nlr_p)--; - asm("restore"); - } - - asm("sethi %hi(wad_nlr_value), %o0"); - asm("or %o0, %lo(wad_nlr_value), %o0"); - asm("ld [%o0], %i0"); - - /* If there is a non-local return function. We're going to go ahead - and transfer control to it */ - - if (wad_nlr_func) - (*wad_nlr_func)(); - - asm("jmp %i7 + 8"); - asm("restore"); - asm(".size _returnsignal,(.-_returnsignal)"); -} -#endif - -#ifdef WAD_LINUX - -/* Saved values of the machine registers */ - -long wad_saved_esi = 0; -long wad_saved_edi = 0; -long wad_saved_ebx = 0; - -static void nonlocalret() { - asm("_returnsignal:"); - while (*nlr_p > 0) { - (*nlr_p)--; - asm("leave"); - } - - if (wad_nlr_func) - (*wad_nlr_func)(); - - /* Restore the registers */ - asm("movl wad_saved_esi, %esi"); - asm("movl wad_saved_edi, %edi"); - asm("movl wad_saved_ebx, %ebx"); - asm("movl wad_nlr_value, %eax"); - asm("leave"); - asm("ret"); -} - -/* This function uses a heuristic to restore the callee-save registers on i386. - According to the Linux Assembly HOWTO, the %esi, %edi, %ebx, and %ebp registers - are callee-saved. All others are caller saved. To restore the callee-save - registers, we use the fact that the C compiler saves the callee-save registers - (if any) at the beginning of function execution. Therefore, we can scan the - instructions at the start of each function in the stack trace to try and find - where they are. - - The following heuristic is used: - - 1. Each function starts with a preamble like this which saves the %ebp - register: - - 55 89 e5 ---> push %ebp - mov %esp, %ebp - - 2. Next, space is allocated for local variables, using one of two schemes: - - 83 ec xx ---> Less than 256 bytes of local storage - ^^^ - length - - 81 ec xx xx xx xx --> More than 256 bytes of local storage - ^^^^^^^^^^^ - length - - 3. After this, a collection of 1-byte stack push op codes might appear - - 56 = pushl %esi - 57 = pushl %edi - 53 = pushl %ebx - - - Based on the size of local variable storage and the order in which - the %esi, %edi, and %ebx registers are pushed on the stack, we can - determine where in memory the registers are saved and restore them to - their proper values. -*/ - -void wad_restore_i386_registers(WadFrame *f, int nlevels) { - WadFrame *lastf = f; - int localsize = 0; - unsigned char *pc; - unsigned long *saved; - int i, j; - int pci; - for (i = 0; i <= nlevels; i++, f=f->next) { - - /* This gets the starting instruction for the stack frame */ - pc = (unsigned char *) f->sym_base; - /* printf("pc = %x, base = %x, %s\n", f->pc, f->sym_base, SYMBOL(f)); */ - if (!pc) continue; - - /* Look for the standard prologue 0x55 0x89 0xe5 */ - if ((pc[0] == 0x55) && (pc[1] == 0x89) && (pc[2] == 0xe5)) { - /* Determine the size */ - pci = 3; - if ((pc[3] == 0x83) && (pc[4] == 0xec)) { - /* printf("8-bit size\n");*/ - localsize = (int) pc[5]; - pci = 6; - } - if ((pc[3] == 0x81) && (pc[4] == 0xec)) { - /* printf("32-bit size\n"); */ - localsize = (int) *((long *) (pc+5)); - pci = 10; - } - saved = (long *) (f->fp - localsize - sizeof(long)); - /* printf("saved = %x, fp = %x\n", saved, f->fp); - printf("localsize = %d\n", localsize); - */ - for (j = 0; j < 3; j++, saved--, pci++) { - if (pc[pci] == 0x57) { - wad_saved_edi = *saved; - /* printf("restored edi = %x\n", wad_saved_edi); */ - } - else if (pc[pci] == 0x56) { - wad_saved_esi = *saved; - /* printf("restored esi = %x\n", wad_saved_esi); */ - } - else if (pc[pci] == 0x53) { - wad_saved_ebx = *saved; - /* printf("restored ebx = %x\n", wad_saved_ebx); */ - } - else break; - } - } - } -} - -#endif - -void wad_signalhandler(int sig, siginfo_t *si, void *vcontext) { - greg_t *pc; - greg_t *npc; - greg_t *sp; - greg_t *fp; -#ifdef WAD_LINUX - greg_t *esi; - greg_t *edi; - greg_t *ebx; -#endif - - unsigned long addr; - ucontext_t *context; - unsigned long p_sp; /* process stack pointer */ - unsigned long p_pc; /* Process program counter */ - unsigned long p_fp; /* Process frame pointer */ - int nlevels = 0; - int found = 0; - void _returnsignal(); - WadFrame *frame, *origframe; - char *framedata; - char *retname = 0; - unsigned long current_brk; - - /* Reset all of the signals while running WAD */ - wad_signal_clear(); - - wad_nlr_func = 0; - - context = (ucontext_t *) vcontext; - - wad_printf("WAD: Collecting debugging information...\n"); - - /* Read the segments */ - if (wad_segment_read() < 0) { - wad_printf("WAD: Unable to read segment map\n"); - return; - } - - if (wad_debug_mode & DEBUG_SIGNAL) { - wad_printf("WAD: siginfo = %x, context = %x\n", si, vcontext); - } - - current_brk = (long) sbrk(0); - - /* Get some information about the current context */ - -#ifdef WAD_SOLARIS - pc = &((context->uc_mcontext).gregs[REG_PC]); - npc = &((context->uc_mcontext).gregs[REG_nPC]); - sp = &((context->uc_mcontext).gregs[REG_SP]); -#endif - -#ifdef WAD_LINUX - sp = &((context->uc_mcontext).gregs[ESP]); /* Top of stack */ - fp = &((context->uc_mcontext).gregs[EBP]); /* Stack base - frame pointer */ - pc = &((context->uc_mcontext).gregs[EIP]); /* Current instruction */ - esi = &((context->uc_mcontext).gregs[ESI]); - edi = &((context->uc_mcontext).gregs[EDI]); - ebx = &((context->uc_mcontext).gregs[EBX]); - - wad_saved_esi = (unsigned long) (*esi); - wad_saved_edi = (unsigned long) (*edi); - wad_saved_ebx = (unsigned long) (*ebx); - - /* printf("esi = %x, edi = %x, ebx = %x\n", wad_saved_esi, wad_saved_edi, wad_saved_ebx); */ - - /* printf("&sp = %x, &pc = %x\n", sp, pc); */ -#endif - - /* Get some information out of the signal handler stack */ - addr = (unsigned long) si->si_addr; - - /* See if this might be a stack overflow */ - - p_pc = (unsigned long) (*pc); - p_sp = (unsigned long) (*sp); -#ifdef WAD_LINUX - p_fp = (unsigned long) (*fp); -#endif -#ifdef WAD_SOLARIS - p_fp = (unsigned long) *(((long *) p_sp) + 14); -#endif - - if (wad_debug_mode & DEBUG_SIGNAL) { - wad_printf("fault at address %x, pc = %x, sp = %x, fp = %x\n", addr, p_pc, p_sp, p_fp); - } - frame = wad_stack_trace(p_pc, p_sp, p_fp); - - if (!frame) { - /* We're really hosed. Not possible to generate a stack trace */ - wad_printf("WAD: Unable to generate stack trace.\n"); - wad_printf("WAD: Maybe the call stack has been corrupted by buffer overflow.\n"); - wad_signal_clear(); - return; - } - - { - WadFrame *f = frame; - while (f) { - wad_find_object(f); - wad_find_symbol(f); - f = f->next; - } - f = frame; - while (f) { - wad_find_debug(f); - wad_build_vars(f); - f = f->next; - } - } - wad_heap_overflow = 0; - if (sig == SIGSEGV) { - if (addr >= current_brk) wad_heap_overflow = 1; - } - - wad_stack_debug(frame); - - /* Generate debugging strings */ - wad_debug_make_strings(frame); - - wad_stab_debug(); - - /* Walk the exception frames and try to find a return point */ - origframe = frame; - while (frame) { - WadReturnFunc *wr = wad_check_return(frame->sym_name); - if (wr) { - found = 1; - wad_nlr_value = wr->value; - retname = wr->name; - } - if (found) { - frame->last = 1; /* Cut off top of the stack trace */ - break; - } - frame = frame->next; - nlevels++; - } - - - if (found) { - wad_nlr_levels = nlevels - 1; -#ifdef WAD_LINUX - wad_restore_i386_registers(origframe, wad_nlr_levels); -#endif - } else { - wad_nlr_levels = -1; - } - - wad_string_debug(); - wad_memory_debug(); - - /* Before we do anything with callbacks, we are going - to attempt to dump a wad-core */ - - { - int fd; - static int already = 0; - fd = open("wadtrace",O_WRONLY | O_CREAT | (already*O_APPEND) | ((already==0)*O_TRUNC),0666); - if (fd > 0) { - wad_dump_trace(fd,sig,origframe,retname); - close(fd); - already=1; - } - } - - if (sig_callback) { - (*sig_callback)(sig,origframe,retname); - } else { - /* No signal handler defined. Go invoke the default */ - - wad_default_callback(sig, origframe,retname); - } - - if (wad_debug_mode & DEBUG_HOLD) while(1); - - /* If we found a function to which we should return, we jump to - an alternative piece of code that unwinds the stack and - initiates a non-local return. */ - - if (wad_nlr_levels >= 0) { - *(pc) = (greg_t) _returnsignal; -#ifdef WAD_SOLARIS - *(npc) = *(pc) + 4; -#endif - if (!(wad_debug_mode & DEBUG_ONESHOT)) { - wad_signal_init(); - } - return; - } - exit(1); -} - - -/* ----------------------------------------------------------------------------- - * wad_signal_init() - * - * Resets the signal handler. - * ----------------------------------------------------------------------------- */ - -void wad_signal_init() { - struct sigaction newvec; - static stack_t sigstk; - static int initstack = 0; - - if (wad_debug_mode & DEBUG_INIT) { - wad_printf("WAD: Initializing signal handler.\n"); - } - /* This is buggy in Linux and threads. disabled by default */ - -#ifndef WAD_LINUX - - if (!initstack) { - /* Set up an alternative stack */ - - sigstk.ss_sp = (char *) wad_sig_stack; - sigstk.ss_size = STACK_SIZE; - sigstk.ss_flags = 0; - if (!(wad_debug_mode & DEBUG_NOSTACK)) { - if (sigaltstack(&sigstk, (stack_t*)0) < 0) { - perror("sigaltstack"); - } - } - initstack=1; - } -#endif - - sigemptyset(&newvec.sa_mask); - sigaddset(&newvec.sa_mask, SIGSEGV); - sigaddset(&newvec.sa_mask, SIGBUS); - sigaddset(&newvec.sa_mask, SIGABRT); - sigaddset(&newvec.sa_mask, SIGILL); - sigaddset(&newvec.sa_mask, SIGFPE); - newvec.sa_flags = SA_SIGINFO; - - if (wad_debug_mode & DEBUG_ONESHOT) { - newvec.sa_flags |= SA_RESETHAND; - } -#ifndef WAD_LINUX - if (!(wad_debug_mode & DEBUG_NOSTACK)) { - newvec.sa_flags |= SA_ONSTACK; - } -#endif - newvec.sa_sigaction = ((void (*)(int,siginfo_t *, void *)) wad_signalhandler); - if (sigaction(SIGSEGV, &newvec, NULL) < 0) goto werror; - if (sigaction(SIGBUS, &newvec, NULL) < 0) goto werror; - if (sigaction(SIGABRT, &newvec, NULL) < 0) goto werror; - if (sigaction(SIGFPE, &newvec, NULL) < 0) goto werror; - if (sigaction(SIGILL, &newvec, NULL) < 0) goto werror; - - return; - werror: - wad_printf("WAD: Couldn't install signal handler!\n"); -} - -/* ----------------------------------------------------------------------------- - * clear signals - * ----------------------------------------------------------------------------- */ - -void wad_signal_clear() { - signal(SIGSEGV, SIG_DFL); - signal(SIGBUS, SIG_DFL); - signal(SIGILL, SIG_DFL); - signal(SIGFPE, SIG_DFL); - signal(SIGABRT, SIG_DFL); -} - - - diff --git a/Tools/WAD/Wad/stab.c b/Tools/WAD/Wad/stab.c deleted file mode 100644 index 29626ae99..000000000 --- a/Tools/WAD/Wad/stab.c +++ /dev/null @@ -1,682 +0,0 @@ -/* ----------------------------------------------------------------------------- - * stab.c - * - * This file reads stabs data and looks for various properties of a - * given symbol. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -/* stabs data structure. This appears to be somewhat universal. */ -typedef struct Stab { - unsigned n_strx; /* index into file string table */ - unsigned char n_type; /* type flag (N_TEXT,..) */ - char n_other; /* used by N_SLINE stab */ - unsigned short n_desc; /* see stabs documentation */ - unsigned n_value; /* value of symbol (or sdb offset) */ -} Stab; - -/* stabs data types used by this module */ - -#define N_UNDF 0x0 /* undefined */ -#define N_FUN 0x24 /* function */ -#define N_OBJ 0x38 /* object file path */ -#define N_RSYM 0x40 /* Register symbol */ -#define N_SLINE 0x44 /* Source line */ -#define N_SO 0x64 /* Source file name */ -#define N_LSYM 0x80 /* Local symbol */ -#define N_PSYM 0xa0 /* Parameter */ -#define N_LBRAC 0xc0 /* Left brace */ -#define N_RBRAC 0xe0 /* Right brace */ - -/* ----------------------------------------------------------------------------- - * stabs type handler - * - * Type names are defined as N_LSYM types. We need to keep a hash table of - * logical type names and stabs type names. - * - * We also need to keep a hash table of stabs types. - * ----------------------------------------------------------------------------- */ - -typedef struct stabtype { - char *name; - char *value; - struct stabtype *next; - int visit; -} stabtype; - -#define HASH_SIZE 113 - -static int stab_type_init = 0; -static stabtype *lnames[HASH_SIZE]; /* Hash of local names */ -static stabtype *deadnames[HASH_SIZE]; /* Hash of dead names */ - -/* Initialize the hash table */ - -static void init_hash() { - int i; - stabtype *s, *sp = 0; - - for (i = 0; i < HASH_SIZE; i++) { - if (stab_type_init) { - /* Add stabs to dead list */ - s = lnames[i]; - sp = 0; - while (s) { - sp = s; - s = s->next; - } - if (sp) { - sp->next = deadnames[i]; - deadnames[i] = lnames[i]; - } - } - lnames[i] = 0; - } - stab_type_init = 1; -} - -static int thash(char *name) { - unsigned int h = 0; - int i; - for (i = 0; i < 8 && (*name); i++, name++) { - h = ((h << 7) + *name); - } - return (h % HASH_SIZE); -} - -/* Add a symbol to the hash */ - -static void type_add(char *name, char *value) { - int h; - stabtype *s; - char sc =0; - char *v; - char *vr; - char *split; - - if (!stab_type_init) { - init_hash(); - stab_type_init = 1; - } - - /* Split the "value" up into a type name and a value */ - - split = strchr(value,'='); - if (value[0] != '(') split = 0; - if (split) { - sc = *split; - v = value; - *split = 0; - vr = split+1; - } else { - v = value; - sc = 0; - vr = 0; - } - - h = thash(name); - s = lnames[h]; - while (s) { - if (strcmp(s->name,name) == 0) { - if (strcmp(s->value,v)) { - s->value = wad_string_lookup(v); - } - goto add_more; - } - s = s->next; - } - s = deadnames[h]; - if (!s) { - s = (stabtype *) wad_malloc(sizeof(stabtype)); - } else { - deadnames[h] = s->next; - } - s->name = wad_string_lookup(name); - s->value = wad_string_lookup(v); - s->next = lnames[h]; - s->visit = 0; - lnames[h] = s; - - /* Now take a look at the value. If it is contains other types, we might be able to define more stuff */ - add_more: - if (vr) { - /* There is a mapping to another type */ - type_add(v,vr); - } -} - -static -char *type_resolve(char *name) { - int h; - stabtype *s; - h = thash(name); - s = lnames[h]; - while(s) { - if (strcmp(s->name,name) == 0) { - if (!s->visit) { - char *c; - /* The visit flag is set so that we don't get in infinite loops */ - s->visit = 1; - c = type_resolve(s->value); - s->visit = 0; - return c; - } else { - return name; - } - } - s = s->next; - } - return name; -} - -/* This function tries to resolve base stabs types into a machine equivalent */ -static -int type_typecode(char *name) { - char *range; - - if (name[0] == '*') { - return WAD_TYPE_POINTER; - } - - range = strchr(name,';'); - if (!range) return WAD_TYPE_UNKNOWN; - range++; - - if (name[0] == 'r') { - /* GNU-style range specifiers */ - if ( - (strcmp(range,"0000000000000;0037777777777;") == 0) - ) { - return WAD_TYPE_UINT32; - } - if ( - (strcmp(range,"0020000000000;0017777777777;") == 0) - ) { - return WAD_TYPE_INT32; - } - if ( - (strcmp(range,"-32768;32767;") == 0) - ) { - return WAD_TYPE_INT16; - } - if ( - (strcmp(range,"0;65535;") == 0) - ) { - return WAD_TYPE_UINT16; - } - if ( - (strcmp(range,"0;127;") == 0) - ) { - return WAD_TYPE_CHAR; - } - if ( - (strcmp(range,"-128;127;") == 0) - ) { - return WAD_TYPE_INT8; - } - if ( - (strcmp(range,"0;255;") == 0) - ) { - return WAD_TYPE_UINT8; - } - if ( - (strcmp(range,"4;0;") == 0) - ) { - return WAD_TYPE_FLOAT; - } - if ( - (strcmp(range,"8;0;") == 0) - ) { - return WAD_TYPE_DOUBLE; - } - } - /* Traditional built-in types */ - if (strcmp(name,"bs4;0;32;") == 0) { - return WAD_TYPE_INT32; - } - if (strcmp(name,"bs2;0;16;") == 0) { - return WAD_TYPE_INT16; - } - if (strcmp(name,"bs1;0;8;") == 0) { - return WAD_TYPE_INT8; - } - if (strcmp(name,"bsc1;0;8;") == 0) { - return WAD_TYPE_CHAR; - } - if (strcmp(name,"bu4;0;32;") == 0) { - return WAD_TYPE_UINT32; - } - if (strcmp(name,"bu2;0;16;") == 0) { - return WAD_TYPE_UINT16; - } - if (strcmp(name,"bu1;0;8;") == 0) { - return WAD_TYPE_UINT8; - } - if (strcmp(name,"R1;4;") == 0) { - return WAD_TYPE_FLOAT; - } - if (strcmp(name,"R2;8;") == 0) { - return WAD_TYPE_DOUBLE; - } - return WAD_TYPE_UNKNOWN; -} - -static void types_print() { - stabtype *s; - int i; - for (i = 0; i < HASH_SIZE; i++) { - s = lnames[i]; - while (s) { - wad_printf("%20s %s\n", s->name, s->value); - s = s->next; - } - } -} - -void wad_stab_debug() { - /* types_print();*/ -} - -/* ----------------------------------------------------------------------------- - * match_stab_symbol() - * - * Match a stabs symbol name against a stab string. The stab string may contain - * extra information delimited by a colon which is not used in the comparsion. - * Returns 1 on match, 0 on mismatch. - * ----------------------------------------------------------------------------- */ - -static int -match_stab_symbol(char *symbol, char *stabtext, int slen) { - if (strcmp(symbol,stabtext) == 0) { - return 1; - } - if ((strncmp(symbol, stabtext, slen) == 0) && (*(stabtext+slen) == ':')) return 1; - return 0; -} - -static char * -stab_string_parm(char *str) { - return strchr(str,':'); -} - -/* ----------------------------------------------------------------------------- - * stab_symbol(Stab *s, char *stabstr) - * - * Process stab symbol specifier N_LSYM - * ----------------------------------------------------------------------------- */ - -static void -stab_symbol(Stab *s, char *stabstr) { - char *str; - char *pstr; - char name[1024]; - char value[65536]; - - str = stabstr+s->n_strx; - pstr = stab_string_parm(str); - if (!pstr) return; - - strncpy(name,str, pstr-str); - name[(int)(pstr-str)] = 0; - if ((pstr[1] == 't') || (pstr[1] == 'p') || (pstr[1] == 'r')) { - /* A stabs type definition */ - /* printf("stab lsym: other=%d, desc=%d, value=%d, str='%s'\n", s->n_other,s->n_desc,s->n_value, - stabstr+s->n_strx); */ - /* wad_printf("name = '%s', pstr='%s'\n", name, pstr+2); */ - wad_strcpy(value,pstr+2); - type_add(name,value); - } -} - - -/* ----------------------------------------------------------------------------- - * scan_function() - * - * Collect stabs data for a function definition. - * ----------------------------------------------------------------------------- */ - -static int -scan_function(Stab *s, char *stabstr, int ns, WadFrame *f) { - int i; - unsigned long offset; - int get_parms = 1; - int nbrace = 0; - - offset = f->pc - f->sym_base; - if (wad_debug_mode & DEBUG_STABS) { - wad_printf("---[ %s ] --------------\n", f->sym_name); - } - - for (i = 0; i < ns; i++,s++) { - if (wad_debug_mode & DEBUG_STABS) { - wad_printf(" %10d %10x %10d %10d %10d: '%s'\n", s->n_strx, s->n_type, s->n_other, s->n_desc, s->n_value, - stabstr+s->n_strx); - - } - - if ((s->n_type == N_UNDF) || (s->n_type == N_SO) || /* (s->n_type == N_FUN) || */ - (s->n_type == N_OBJ)) return i; - - if ((s->n_type == N_FUN) && !(strlen(stabstr+s->n_strx))) return 1; - - if (s->n_type == N_LBRAC) { - nbrace++; - get_parms = 0; - } - if (s->n_type == N_RBRAC) { - nbrace--; - if (nbrace <= 0) return i; - } - /* Local variable declaration */ - - if (s->n_type == N_LSYM) { - /* This might be a local variable definition */ - /* wad_printf("local: n_value = %d, offset = %d\n", s->n_value, offset);*/ - if (s->n_desc <= f->loc_line) - { - /* Okay. We can pay attention to it */ - char *pname; - char *c; - int len; - WadLocal *arg, *a; - pname = stabstr+s->n_strx; - c = strchr(pname,':'); - if (*(c+1) != '(') continue; - if (c) { - len = (c-pname); - } else { - len = strlen(pname); - } - /* printf("local\n"); */ - stab_symbol(s,stabstr); - a = f->debug_locals; - while (a) { - if ((strncmp(a->name,pname,len) == 0) && (strlen(a->name) == len)) { - /* We already saw this argument. Given a choice between a register and a stack - argument. We will choose the stack version */ - a->loc = PARM_STACK; - a->stack = s->n_value; - break; - } - a = a->next; - } - if (a) continue; /* We got an argument match. Just skip to the next stab */ - arg = (WadLocal *) wad_malloc(sizeof(WadLocal)); - { - char t = pname[len]; - pname[len] = 0; - arg->name = wad_string_lookup(pname); - pname[len] = t; - } - arg->loc = PARM_STACK; - arg->line = s->n_desc; - arg->stack = s->n_value; - arg->type = 0; - arg->next = 0; - { - char tname[128]; - char *t = tname; - - c+=1; - while ((*c) && (*c != '=')) { - *t++ = *c++; - } - *t = 0; - t = type_resolve(tname); - arg->type = type_typecode(t); - if (wad_debug_mode & DEBUG_STABS) { - wad_printf("type_resolve '%s' -> '%s' (%d)\n", tname, t, arg->type); - } - } - if (f->debug_locals) { - f->debug_lastlocal->next = arg; - f->debug_lastlocal = arg; - } else { - f->debug_locals = arg; - f->debug_lastlocal = arg; - f->debug_nlocals= 0; - } - f->debug_nlocals++; - } - } - - if (s->n_type == N_SLINE) { - get_parms = 0; - if (s->n_value <= offset) { - f->loc_line = s->n_desc; - } - } else if (((s->n_type == N_PSYM) || (s->n_type == N_RSYM)) && get_parms) { - /* Parameter counting */ - char *pname; - char *c; - int len; - WadLocal *arg; - pname = stabstr+s->n_strx; - c = strchr(pname,':'); - if (c) { - len = (c-pname); - } else { - len = strlen(pname); - } - /* Get type information */ - - stab_symbol(s,stabstr); - - /* Check if the argument was already used */ - /* In this case, the first stab simply identifies an argument. The second - one identifies its location for the debugger */ - - { - /* Need to do some fix up for linux here */ - WadLocal *a = f->debug_args; - while (a) { - if ((strncmp(a->name,pname,len) == 0) && (strlen(a->name) == len)) { - /* We already saw this argument. Given a choice between a register and a stack - argument. We will choose the stack version */ - - if (a->loc == PARM_STACK) { - break; - } - /* Go ahead and use the new argument */ - if (s->n_type == N_RSYM) { - a->loc = PARM_REGISTER; - a->reg = s->n_value; - } else { - a->loc = PARM_STACK; - a->stack = s->n_value; - } - break; - } - a = a->next; - } - if (a) continue; /* We got an argument match. Just skip to the next stab */ - } - - arg = (WadLocal *) wad_malloc(sizeof(WadLocal)); - { - char t = pname[len]; - pname[len] = 0; - arg->name = wad_string_lookup(pname); - pname[len] = t; - } - if (s->n_type == N_RSYM) { - arg->loc = PARM_REGISTER; - arg->reg = s->n_value; - arg->stack = 0; - } else { - arg->loc = PARM_STACK; - arg->line = s->n_desc; - arg->stack = s->n_value; - } - arg->type = 0; - arg->next = 0; - { - char tname[128]; - char *t = tname; - - c+=2; - while ((*c) && (*c != '=')) { - *t++ = *c++; - } - *t = 0; - t = type_resolve(tname); - arg->type = type_typecode(t); - if (wad_debug_mode & DEBUG_STABS) { - wad_printf("type_resolve '%s' -> '%s' (%d)\n", tname, t, arg->type); - } - } - if (f->debug_args) { - f->debug_lastarg->next = arg; - f->debug_lastarg = arg; - } else { - f->debug_args = arg; - f->debug_lastarg = arg; - f->debug_nargs= 0; - } - f->debug_nargs++; - } - } - return i; -} - -/* Given a stabs data segment (obtained somehow), this function tries to - collect as much information as it can about a given symbol. - - s points to the stab data. stabstr points to the stab string section, - ns is the size of the stab section, symbol is the item of interest, - and offset is the offset in the object file of the symbol - - Note: this function may recurse upon itself if there are multiple - stabs sections. - - Note: If a symbol corresponds to a local symbol, it's entirely possible - that the only stabs data we will find is a file specifier. In this case, - */ - -int -wad_search_stab(void *sp, int size, char *stabstr, WadFrame *f) { - Stab *s; - int ns; - int i; - int found = 0; - - char *file, *lastfile = 0; - - char srcfile[MAX_PATH]; - char objfile[MAX_PATH]; - - /* It appears to be necessary to clear the types table on each new stabs section */ - - init_hash(); - - if (!f->sym_name) return 0; - - s = (Stab *) sp; /* Stabs data */ - ns = size/sizeof(Stab); /* number of stabs */ - - srcfile[0] = 0; - objfile[0] = 0; - - for (i = 0; i < ns; i++, s++) { - if (wad_debug_mode & DEBUG_STABS) { - /* wad_printf(" %10d %10x %10d %10d %10d: '%s'\n", s->n_strx, s->n_type, s->n_other, s->n_desc, s->n_value, - stabstr+s->n_strx); */ - - } - if (s->n_type == N_LSYM) { - stab_symbol(s,stabstr); - continue; - } - if ((s->n_type == N_UNDF)) { /* && (s->n_desc >= 0)) { */ - /* New stabs section. We need to be a little careful here. Do a recursive - search of the subsection. */ - - if (wad_search_stab(s+1,s->n_desc*sizeof(Stab), stabstr, f)) { - return 1; - } - - /* On solaris, each stabs section seems to increment the stab string pointer. On Linux, - the linker seems to do a certain amount of optimization that results in a single - string table. */ - -#ifdef WAD_SOLARIS - stabstr += s->n_value; /* Update the string table location*/ -#endif - i += s->n_desc; - s += s->n_desc; - objfile[0] = 0; - srcfile[0] = 0; - continue; - } else if (s->n_type == N_SO) { - /* Source file specification */ - /* Look for directory */ - file = stabstr+s->n_strx; - if (strlen(file) && (file[strlen(file)-1] == '/')) { - wad_strcpy(srcfile,file); - } else { - wad_strcat(srcfile,file); - } - objfile[0] = 0; - /* If we have a file match, we might be looking for a local symbol. If so, - we'll go ahead and set the srcfile field of the frame */ - - /* We're going to check for a file match. Maybe we're looking for a local symbol */ - if (f->sym_file && strcmp(f->sym_file,file) == 0) { - found = 1; - } - lastfile = file; - } else if (s->n_type == N_OBJ) { - /* Object file specifier */ - if (objfile[0]) { - wad_strcat(objfile,"/"); - } - wad_strcat(objfile,stabstr+s->n_strx); - } else if (s->n_type == N_FUN) { - if (match_stab_symbol(f->sym_name, stabstr+s->n_strx, f->sym_nlen)) { - if (!f->sym_file || (strcmp(f->sym_file,lastfile) == 0)) { - int n; - /* Go find debugging information for the function */ - n = scan_function(s+1, stabstr, ns -i - 1, f); - f->loc_srcfile = wad_string_lookup(srcfile); - f->loc_objfile = wad_string_lookup(objfile); - return 1; - } - } - } - } - /* If found, but no other debugging information was filled in, go ahead and copy the - source and objfile information */ - - if ((found) && (!f->debug_check)) { - f->loc_srcfile = wad_string_lookup(srcfile); - f->loc_objfile = wad_string_lookup(objfile); - } - return found; -} - - - - diff --git a/Tools/WAD/Wad/stack.c b/Tools/WAD/Wad/stack.c deleted file mode 100644 index 68a55a77f..000000000 --- a/Tools/WAD/Wad/stack.c +++ /dev/null @@ -1,309 +0,0 @@ -/* ----------------------------------------------------------------------------- - * stack.c - * - * This file unwinds the C call stack and creates a list of stack frames. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -/* ----------------------------------------------------------------------------- - * new_frame() - * - * Create a new stack frame object and initialize all of the fields. - * ----------------------------------------------------------------------------- */ - -static WadFrame * -new_frame() { - WadFrame *f; - f = (WadFrame *) wad_malloc(sizeof(WadFrame)); - f->frameno = 0; - f->segment = 0; - f->object = 0; - f->pc = 0; - f->sp = 0; - f->sp = 0; - f->stack = 0; - f->stack_size = 0; - - f->sym_name = 0; - f->sym_nlen = 0; - f->sym_file = 0; - f->sym_base = 0; - f->sym_size = 0; - f->sym_type = 0; - f->sym_bind = 0; - - f->loc_objfile = 0; - f->loc_srcfile = 0; - f->loc_line = 0; - - f->debug_check = 0; - f->debug_nargs = -1; - f->debug_args = 0; - f->debug_lastarg = 0; - f->debug_nlocals = 0; - f->debug_locals = 0; - f->debug_lastlocal = 0; - f->debug_str = 0; - f->debug_srcstr = 0; - - f->last = 0; - f->next = 0; - f->prev = 0; - return f; -} - -/* ----------------------------------------------------------------------------- - * stack_unwind() - * - * This function performs a single level of stack unwinding given the stack pointer - * frame pointer and program counter. Validations are made to make sure the stack - * and frame pointers are in valid memory. Updates the values of the sp, pc, and fp - * in-place. Returns a stack frame object on success, 0 if memory is invalid - * or the end of the stack has been reached. - * ----------------------------------------------------------------------------- */ - -static WadFrame * -stack_unwind(unsigned long *pc, unsigned long *sp, unsigned long *fp) { - WadSegment *sp_seg, *fp_seg; - WadFrame *f; - unsigned long fake_fp; - - if (wad_debug_mode & DEBUG_UNWIND) { - wad_printf("::: stack unwind : pc = %x, sp = %x, fp = %x\n", *pc, *sp, *fp); - } - - /* Verify that the sp and fp are in mapped memory */ - sp_seg = wad_segment_find((void *) *sp); - fp_seg = wad_segment_find((void *) *fp); - - /* Make sure the stack pointer is in memory */ - if (!sp_seg) { - return 0; - } - - if (!fp_seg) { - /* Hmmm. If no frame pointer, we must be off the top of the call stack */ - fake_fp = (unsigned long) (sp_seg->vaddr + sp_seg->size); - fp_seg = sp_seg; - } else { - fake_fp = *fp; - } - if (sp_seg != fp_seg) { - /* Whoa. Stack pointer and frame pointer are in different memory segments. */ - wad_printf("WAD: Warning. Stack pointer and frame pointer are in different regions.\n"); - return 0; - } - - /* Check to see if the PC is valid */ - if (!wad_segment_valid((void *) *pc)) { - return 0; - } - - f = new_frame(); - f->pc = *pc; - f->sp = *sp; - f->fp = fake_fp; - f->segment = wad_segment_find((void *) *pc); - f->stack_size = fake_fp - *sp; - /* Make a copy of the call stack */ - f->stack = (char *) wad_malloc(f->stack_size); - wad_memcpy(f->stack,(void *) *sp, f->stack_size); - - /* Update the sp, fp, and pc */ - -#ifdef WAD_SOLARIS - *pc = *((unsigned long *) *sp+15); /* %i7 - Return address */ - *sp = *((unsigned long *) *sp+14); /* %i6 - frame pointer */ - if (wad_segment_valid((void *) *sp)) { - *fp = *((unsigned long *) *sp+14); - } else { - *fp = 0; - } -#endif - -#ifdef WAD_LINUX - if (wad_segment_valid((void *) ((unsigned long *) *fp+1))) { - *pc = *((unsigned long *) *fp+1); - *sp = *fp; - } else { - *sp = 0; - } - if (wad_segment_valid((void *) ((unsigned long *) *fp))) { - *fp = *((unsigned long *) *fp); - } else { - *fp = 0; - } -#endif - return f; -} - -/* ----------------------------------------------------------------------------- - * wad_stack_trace() - * - * Create a stack trace of the process. Returns a linked list of stack frames - * with a limited about debugging information and other details. - * ----------------------------------------------------------------------------- */ - -WadFrame * -wad_stack_trace(unsigned long pc, unsigned long sp, unsigned long fp) { - WadFrame *firstframe=0, *lastframe=0, *frame=0; - unsigned long p_pc; - unsigned long p_sp; - unsigned long p_fp; - int n = 0; - - /* Try to do a stack traceback */ - - p_pc = pc; - p_sp = sp; - p_fp = fp; - - while ((frame = stack_unwind(&p_pc, &p_sp, &p_fp))) { - /* Got a frame successfully */ - frame->frameno = n; - if (lastframe) { - lastframe->next = frame; - frame->prev = lastframe; - lastframe = frame; - } else { - firstframe = frame; - lastframe = frame; - } - n++; - } - if (lastframe) - lastframe->last = 1; - return firstframe; -} - -/* ----------------------------------------------------------------------------- - * wad_stack_debug() - * - * Make a dump of a stack trace - * ----------------------------------------------------------------------------- */ - -void wad_stack_debug(WadFrame *frame) { - if (wad_debug_mode & DEBUG_STACK) { - /* Walk the exception frames and try to find a return point */ - while (frame) { - /* Print out detailed stack trace information */ - wad_printf("::: Stack frame - 0x%08x :::\n", frame); - wad_printf(" pc = %x\n", frame->pc); - wad_printf(" sp = %x\n", frame->sp); - wad_printf(" fp = %x\n", frame->fp); - wad_printf(" stack = %x\n", frame->stack); - wad_printf(" size = %x\n", frame->stack_size); - wad_printf(" segment = %x (%s)\n", frame->segment, frame->segment ? frame->segment->mappath : "?"); - wad_printf(" object = %x (%s)\n", frame->object, frame->object ? frame->object->path : "?"); - - if (frame->sym_name) { - wad_printf(" sym_name = %s\n", frame->sym_name); - wad_printf(" sym_base = %x\n", frame->sym_base); - wad_printf(" sym_size = %x\n", frame->sym_size); - wad_printf(" sym_bind = %x\n", frame->sym_bind); - wad_printf(" sym_file = %s\n", frame->sym_file ? frame->sym_file : ""); - } - - if (frame->loc_srcfile) { - wad_printf(" loc_srcfile = %s\n", frame->loc_srcfile); - } - - if (frame->loc_objfile) { - wad_printf(" loc_objfile = %s\n", frame->loc_objfile); - } - wad_printf(" loc_line = %d\n", frame->loc_line); - - - wad_printf(" debug_nargs = %d\n", frame->debug_nargs); - if (frame->debug_args) { - int i = 0; - WadLocal *p = frame->debug_args; - wad_printf(" debug_args = [ \n"); - while (p) { - wad_printf(" arg[%d] : name = '%s', loc = %d, type = %d, stack = %d, reg = %d, line=%d, ptr=%x(%d)\n", i, p->name, p->loc, p->type, p->stack,p->reg,p->line,p->ptr,p->size); - p = p->next; - } - } - wad_printf(" ]\n"); - - wad_printf(" debug_nlocal = %d\n", frame->debug_nlocals); - if (frame->debug_locals) { - int i = 0; - WadLocal *p = frame->debug_locals; - wad_printf(" debug_locals = [ \n"); - while (p) { - wad_printf(" loc[%d] : name = '%s', loc = %d, type = %d, stack = %d, reg = %d, line=%d, ptr=%x(%d)\n", i, p->name, p->loc, p->type, p->stack,p->reg,p->line,p->ptr,p->size); - p = p->next; - } - } - wad_printf(" ]\n"); - - frame = frame->next; - } - } -} - - -/* ----------------------------------------------------------------------------- - * wad_steal_outarg() - * - * Steal an output argument - * ----------------------------------------------------------------------------- */ - -long -wad_steal_outarg(WadFrame *f, char *symbol, int argno, int *error) { - long *regs; - WadFrame *lastf = 0; - - *error = 0; - /* Start searching */ - while (f) { - if (f->sym_name && (strcmp(f->sym_name,symbol) == 0)) { - /* Got a match */ - if (lastf) { -#ifdef WAD_SOLARIS - regs = (long *) lastf->stack; - return regs[8+argno]; -#endif -#ifdef WAD_LINUX - regs = (long *) f->stack; - return regs[argno+2]; -#endif - } - } - lastf = f; - f = f->next; - } - *error = -1; - return 0; -} - - - - - - - diff --git a/Tools/WAD/Wad/string.c b/Tools/WAD/Wad/string.c deleted file mode 100644 index 1a15878ee..000000000 --- a/Tools/WAD/Wad/string.c +++ /dev/null @@ -1,131 +0,0 @@ -/* ----------------------------------------------------------------------------- - * string.c - * - * This file provides support for string storage in WAD. Since strings are - * used frequently in WAD, this file implements string interning and - * some lookup functions that can be used to return a previously stored - * string rather than making a new copy. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -/* Hash table containing stab strings and such */ -typedef struct stringtype { - char *str; - struct stringtype *next; -} stringtype; - -#define STRING_HASH_SIZE 1013 - -static stringtype *strings[STRING_HASH_SIZE]; -static int strings_init = 0; - -static int shash(char *name) { - unsigned int h = 0; - char *c; - int i; - c = name; - for (i = 0; (i < 16) && (*c); i++, c++) { - h = ((h^~i) << 6) + *c; - } - return h % STRING_HASH_SIZE; -} - -char * -wad_string_lookup(char *s) { - int h; - int i; - stringtype *st; - - if (!strings_init) { - for (i = 0; i < STRING_HASH_SIZE; i++) { - strings[i] = 0; - } - strings_init = 1; - } - - h = shash(s); - st = strings[h]; - while (st) { - if (strcmp(st->str,s) == 0) return st->str; - st = st->next; - } - - /* Not found. Add the string to the hash table */ - st = (stringtype *) wad_malloc(sizeof(stringtype)); - st->str = wad_strdup(s); - st->next = strings[h]; - strings[h] = st; - return st->str; -} - -void wad_string_debug() { - if (wad_debug_mode & DEBUG_STRING) { - int maxdepth = 0; - int total = 0; - int stringlen = 0; - int i; - - for (i = 0; i < STRING_HASH_SIZE; i++) { - stringtype *s; - int c = 0; - s = strings[i]; - while (s) { - c++; - stringlen += strlen(s->str); - s = s->next; - } - /* wad_printf("WAD: stringhash[%d] = %d\n", i, c);*/ - if (c > maxdepth) maxdepth = c; - total += c; - } - wad_printf("WAD: nstrings = %d (%d bytes)\n", total, stringlen + total*sizeof(stringtype)); - wad_printf("WAD: maxdepth = %d\n", maxdepth); - } -} - -/* Our own string copy */ -char *wad_strcpy(char *t, const char *s) { - if (s) - for (; *s; s++, t++) *t = *s; - *t = 0; - return t; -} - -char * -wad_strcat(char *t, const char *s) { - while (*t) t++; - return wad_strcpy(t,s); -} - -int -wad_strlen(const char *s) { - int count = 0; - while (*(s++)) count++; - return count; -} - - - diff --git a/Tools/WAD/Wad/vars.c b/Tools/WAD/Wad/vars.c deleted file mode 100644 index b22f71758..000000000 --- a/Tools/WAD/Wad/vars.c +++ /dev/null @@ -1,271 +0,0 @@ -/* ----------------------------------------------------------------------------- - * vars.c - * - * This file examines the stack trace and tries to make some sense out of - * collected debugging information. This includes locating the data on - * the stack and/or registers. - * - * This feature is detached from the debugging info collector to make - * it independent of debugging formats. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * See the file COPYING for a complete copy of the LGPL. - * ----------------------------------------------------------------------------- */ - -#include "wad.h" - -static char cvs[] = "$Id$"; - -/* ----------------------------------------------------------------------------- - * wad_build_vars() - * - * Build variable information for a single stack frame - * ----------------------------------------------------------------------------- */ - -void wad_build_vars(WadFrame *f) { - char *stack = 0; - char *nstack = 0; - char *pstack = 0; - WadLocal *loc; - int n; - - stack = (char *) f->stack; - if (f->next) { - nstack = (char *) f->next->stack; - } - if (f->prev) { - pstack = (char *) f->prev->stack; - } - - for (n = 0; n < 2; n++) { - if (n == 0) loc = f->debug_args; - else loc = f->debug_locals; - - while (loc) { - loc->ptr = 0; - if (loc->loc == PARM_STACK) { - if ((loc->stack >= 0) && (nstack)) { - loc->ptr = (void *) (nstack + loc->stack); - } else if (loc->stack < 0) { - loc->ptr = (void *) (stack + f->stack_size + loc->stack); - } - loc->size = sizeof(long); - } - if (loc->loc == PARM_REGISTER) { - /* Parameter is located in a register */ -#ifdef WAD_SOLARIS - if ((loc->reg >= 24) && (loc->reg < 32)) { - /* Value is located in the %in registers. */ - loc->ptr = (void *) (stack + (loc->reg - 16)*sizeof(int)); - loc->size = sizeof(int); - } else if ((loc->reg >= 8) && (loc->reg < 16)) { - - /* Value is located in the %on registers */ - if (nstack) { - loc->ptr = (void *) (stack + (loc->reg)*sizeof(int)); - loc->size = sizeof(int); - } - } else if ((loc->reg >= 16) && (loc->reg < 24)) { - /* Value has been placed in the %ln registers */ - loc->ptr = (void *) (stack + (loc->reg - 16)*sizeof(int)); - loc->size = sizeof(int); - } -#endif - } - loc = loc->next; - } - } -} - -/* This function creates a formatted integer given a pointer, size, and sign flag */ -static -char *wad_format_int(char *ptr, int nbytes, int sgn) { - static char fmt[128]; - unsigned char *s; - int incr; - unsigned long value = 0; - int i; - -#ifdef WAD_LITTLE_ENDIAN - s = (unsigned char *) (ptr + nbytes - 1); - incr = -1; -#else - s = (unsigned char *) (ptr); - incr = +1; -#endif - for (i = 0; i < nbytes; i++, s += incr) { - value = (value << 8) + *s; - } - if (sgn) { - return wad_format_signed((long) value,-1); - } else { - return wad_format_unsigned((unsigned long) value, -1); - } - return fmt; -} - -/* Try to make a formatted version of a local */ -char *wad_format_var(WadLocal *l) { - static char hexdigits[] = "0123456789abcdef"; - static char buffer[1024]; - double dval; - float fval; - - buffer[0] = 0; - - switch(l->type) { - case WAD_TYPE_INT32: - wad_strcpy(buffer,wad_format_int(l->ptr,4,1)); - break; - case WAD_TYPE_UINT32: - wad_strcpy(buffer,wad_format_int(l->ptr,4,0)); - break; - case WAD_TYPE_INT16: - wad_strcpy(buffer,wad_format_int(l->ptr,2,1)); - break; - case WAD_TYPE_UINT16: - wad_strcpy(buffer,wad_format_int(l->ptr,2,0)); - break; - case WAD_TYPE_INT8: - wad_strcpy(buffer,wad_format_int(l->ptr,1,1)); - break; - case WAD_TYPE_UINT8: - wad_strcpy(buffer,wad_format_int(l->ptr,1,0)); - break; - case WAD_TYPE_CHAR: - buffer[0] = '\''; - buffer[1] = *((char *) l->ptr); - buffer[2] = '\''; - buffer[3] = 0; - break; - case WAD_TYPE_FLOAT: - wad_memcpy(&fval,l->ptr,sizeof(float)); - sprintf(buffer,"%g",fval); - break; - case WAD_TYPE_DOUBLE: - wad_memcpy(&dval,l->ptr,sizeof(double)); - sprintf(buffer,"%g",dval); - break; - case WAD_TYPE_UNKNOWN: - case WAD_TYPE_POINTER: - default: - /* Hmmm. Unknown data type. We'll just treat it as a word */ - if (l->ptr) { - int incr,i; - int b; - int leading = 1; - char *c; - char *ptr; - -#ifdef WAD_LITTLE_ENDIAN - ptr = ((char *) l->ptr) + 3; - incr = -1; -#else - ptr = (char *) l->ptr; - incr =1 ; -#endif - wad_strcat(buffer,"0x"); - c = buffer+2; - for (i = 0; i < sizeof(void *); i++) { - b = (int) *ptr; - if (!leading || (b)) { - if (!leading || (b & 0xf0)) - *(c++) = hexdigits[(b & 0xf0) >> 4]; - *(c++) = hexdigits[(b & 0xf)]; - leading = 0; - } - ptr += incr; - } - if (leading) - *(c++) = '0'; - - *c = 0; - } - } - return buffer; -} - -/* Convert a wad local variable to a long */ -long wad_local_as_long(WadLocal *loc) { - long value = 0; - int32 i32; - int16 i16; - int8 i8; - uint32 u32; - uint16 u16; - uint8 u8; - - switch(loc->type) { - case WAD_TYPE_INT32: - wad_memcpy(&i32,loc->ptr,4); - value = (long) i32; - break; - case WAD_TYPE_UINT32: - wad_memcpy(&u32,loc->ptr,4); - value = (long) u32; - break; - case WAD_TYPE_INT16: - wad_memcpy(&i16,loc->ptr,2); - value = (long) i16; - break; - case WAD_TYPE_UINT16: - wad_memcpy(&u16,loc->ptr,2); - value = (long) u16; - break; - case WAD_TYPE_INT8: - case WAD_TYPE_CHAR: - wad_memcpy(&i8, loc->ptr,1); - value = (long) i8; - break; - case WAD_TYPE_UINT8: - wad_memcpy(&u8, loc->ptr,1); - value = (long) u8; - break; - default: - wad_memcpy(&u32,loc->ptr,4); - value = (long) u32; - } - return value; -} - -/* Convert a wad local variable to a long */ -double wad_local_as_double(WadLocal *loc) { - double value = 0; - float fval; - - switch(loc->type) { - case WAD_TYPE_DOUBLE: - wad_memcpy(&value,loc->ptr,8); - break; - case WAD_TYPE_FLOAT: - wad_memcpy(&fval,loc->ptr,4); - value = (double) fval; - break; - default: - value = 0; - } - return value; -} - - - - - - diff --git a/Tools/WAD/Wad/wadhandler.pl b/Tools/WAD/Wad/wadhandler.pl deleted file mode 100644 index e29240b69..000000000 --- a/Tools/WAD/Wad/wadhandler.pl +++ /dev/null @@ -1,36 +0,0 @@ -package libwadpl; -sub wad_handler_traceback { - package DB; - my $es = ""; - ($pack,$file,$line) = caller(1); - - for ($i = 2; ($p,$f,$l,$s,$h,$w,$e,$r) = caller($i); $i++) { - @a = (); - for $arg (@args) { - $_ = "$arg"; - s/([\'\\])/\\$1/g; - s/([^\0]*)/'$1'/ - unless /^(?: -?[\d.]+ | \*[\w:]* )$/x; - s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg; - s/([\0-\37\177])/sprintf("^%c",ord($1)^64)/eg; - push(@a, $_); - } - $w = $w ? '@ = ' : '$ = '; - $a = $h ? '(' . join(', ', @a) . ')' : ''; - $e =~ s/\n\s*\;\s*\Z// if $e; - $e =~ s/[\\\']/\\$1/g if $e; - if ($r) { - $s = "require '$e'"; - } elsif (defined $r) { - $s = "eval '$e'"; - } elsif ($s eq '(eval)') { - $s = "eval {...}"; - } - $f = "file `$f'" unless $f eq '-e'; - $mess = "$w$s$a called from $f line $l\n"; - $es = $mess . $es; - - } - $es = "Signal at $file line $line\n" . $es; - return $es; -} diff --git a/Tools/WAD/Wad/wadpl.cxx b/Tools/WAD/Wad/wadpl.cxx deleted file mode 100644 index 25ca5bb74..000000000 --- a/Tools/WAD/Wad/wadpl.cxx +++ /dev/null @@ -1,176 +0,0 @@ -/* ----------------------------------------------------------------------------- - * wadpl.cxx - * - * Dynamically loadable module for Perl. - * - * Author(s) : David Beazley (beazley@cs.uchicago.edu) - * - * Copyright (C) 2000. The University of Chicago - * See the file LICENSE for information on usage and redistribution. - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#endif -#include "EXTERN.h" -#include "perl.h" -#include "XSUB.h" - -#include "wad.h" -#ifdef __cplusplus -} -#endif - -#include - -#include "wad_perl_handler.c" - -/* Error message returned to perl */ - -static char message[65536]; -static int global_signo = 0; - -static void returnfunc(void) { - SV *s; - s = perl_eval_pv((char*)"libwadpl::wad_handler_traceback(0)", 0); - croak("%s\n%s",SvPV(s,PL_na),message); - return; -} - -/* Handler function */ -static void handler(int signo, WadFrame *frame, char *ret) { - - static char temp[1024]; - int len = 0; - char *name; - char *fd; - WadFrame *f; - WadFrame *fline = 0; - int err; - char *type; - - if (!ret) { - wad_default_callback(signo, frame, ret); - return; - } - - - switch(signo) { - case SIGSEGV: - type = (char*)"Segmentation fault."; - break; - case SIGBUS: - type = (char*)"Bus error."; - break; - case SIGABRT: - type = (char*)"Abort."; - break; - case SIGFPE: - type = (char*)"Math."; - default: - break; - } - strcpy(message,type); - strcat(message,"\n[ C stack trace ]\n\n"); - fd = (char *) frame; - f = (WadFrame *) fd; - - /* Find the last exception frame */ - while (!f->last) { - fd = fd + f->size; - f = (WadFrame *) fd; - } - /* Now work backwards */ - fd = fd - f->lastsize; - f = (WadFrame *) fd; - while (1) { - sprintf(temp,"#%-3d 0x%08x in ", f->frameno, f->pc); - strcat(message,temp); - strcat(message,*(fd + f->sym_off) ? fd+f->sym_off : "?"); - strcat(message,"()"); - if (strlen(SRCFILE(f))) { - strcat(message," in '"); - strcat(message, wad_strip_dir(SRCFILE(f))); - strcat(message,"'"); - if (f->line_number > 0) { - sprintf(temp,", line %d", f->line_number); - strcat(message,temp); - fline = f; - } - } else { - if (strlen(fd+f->obj_off)) { - strcat(message," from '"); - strcat(message, wad_strip_dir(OBJFILE(f))); - strcat(message,"'"); - } - } - strcat(message,"\n"); - if (!f->lastsize) break; - fd = fd - f->lastsize; - f = (WadFrame *) fd; - } - if (fline) { - int first; - int last; - char *line, *c; - int i; - first = fline->line_number - 2; - last = fline->line_number + 2; - if (first < 1) first = 1; - - line = wad_load_source(SRCFILE(fline),first); - if (line) { - strcat(message,"\n"); - strcat(message, SRCFILE(fline)); - sprintf(temp,", line %d\n\n", fline->line_number); - strcat(message, temp); - for (i = first; i <= last; i++) { - if (i == fline->line_number) strcat(message," => "); - else strcat(message," "); - c = strchr(line,'\n'); - if (c) { - *c = 0; - strcat(message,line); - strcat(message,"\n"); - *c = '\n'; - } else { - strcat(message,line); - strcat(message,"\n"); - break; - } - line = c+1; - } - wad_release_source(); - strcat(message,"\n"); - } - } - wad_set_return_func(returnfunc); - wad_release_trace(); -} - -static void perlwadinit() { - printf("WAD Enabled\n"); - wad_init(); - wad_set_callback(handler); - wad_set_return("Perl_pp_entersub", 0); - perl_eval_pv(wad_perl_handler, 0); -} - -/* This hack is used to auto-initialize wad regardless of whether we are - used as an imported module or as a link-library for another module */ - -class wadinitializer { -public: - wadinitializer() { - perlwadinit(); - } -}; - -static wadinitializer wi; - -extern "C" -XS(boot_libwadpl) { - dXSARGS; - ST(0) = &PL_sv_yes; - XSRETURN(1); -} diff --git a/Tools/WAD/configure.in b/Tools/WAD/configure.in deleted file mode 100644 index 1a8dcdbed..000000000 --- a/Tools/WAD/configure.in +++ /dev/null @@ -1,365 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. - -dnl NOTES: -dnl * As of 1.34, we no longer use and test for "nope" to indicate -dnl an empty variable. Instead, we use `VAR=' (set the variable -dnl to nothing) and `test -z "$VAR"' or `test -n "$VAR"' as the -dnl case may be. --ttn, 2000/08/04 12:11:26 - -AC_INIT -AC_CONFIG_SRCDIR([Include/wad.h]) -AC_PREREQ(2.53) - -# Set name for machine-dependent library files -AC_SUBST(MACHDEP) -AC_MSG_CHECKING(MACHDEP) -if test -z "$MACHDEP" -then - if test -f /usr/lib/NextStep/software_version; then - set X `hostinfo | grep 'NeXT Mach.*:' | \ - sed -e 's/://' -e 's/\./_/'` && \ - ac_sys_system=next && ac_sys_release=$4 - MACHDEP="$ac_sys_system$ac_sys_release$ac_sys_cpu" - else - ac_sys_system=`uname -s` - if test "$ac_sys_system" = "AIX" ; then - ac_sys_release=`uname -v` - else - ac_sys_release=`uname -r` - fi - ac_md_system=`echo $ac_sys_system | - tr -d '[/ ]' | tr '[[A-Z]]' '[[a-z]]'` - ac_md_release=`echo $ac_sys_release | - tr -d '[/ ]' | sed 's/\..*//'` - MACHDEP="$ac_md_system$ac_md_release" - fi - case MACHDEP in - '') MACHDEP=unknown;; - esac -fi -AC_MSG_RESULT($MACHDEP) - -AC_PROG_CC -AC_PROG_CXX -AC_PROG_RANLIB - -dnl Checks for programs. - -AC_SUBST(AR) -AC_CHECK_PROGS(AR, ar aal, ar) - -dnl Checks for header files. -AC_HEADER_STDC -dnl Checks for library functions. - -# Set info about shared libraries. -AC_SUBST(SO) -AC_SUBST(LDSHARED) -AC_SUBST(CCSHARED) - -# SO is the extension of shared libraries `(including the dot!) -# -- usually .so, .sl on HP-UX -AC_MSG_CHECKING(SO) -if test -z "$SO" -then - case $ac_sys_system in - hp*|HP*) SO=.sl;; - *) SO=.so;; - esac -fi -AC_MSG_RESULT($SO) - -# WAD Options -AC_SUBST(WADOPT) -AC_MSG_CHECKING(WADOPT) -if test -z "$WADOPT" -then - case $ac_sys_system/$ac_sys_release in - SunOS/5*) WADOPT="-DWAD_SOLARIS";; - Linux*) WADOPT="-DWAD_LINUX";; - *) WADOPT="-DWAD_UNKWOWN";; - esac -fi -AC_MSG_RESULT($WADOPT) - - -# LDSHARED is the ld *command* used to create shared library -# -- "ld" on SunOS 4.x.x, "ld -G" on SunOS 5.x, "ld -shared" on IRIX 5 -# (Shared libraries in this instance are shared modules to be loaded into -# Python, as opposed to building Python itself as a shared library.) -AC_MSG_CHECKING(LDSHARED) -if test -z "$LDSHARED" -then - case $ac_sys_system/$ac_sys_release in - AIX*) LDSHARED="\$(srcdir)/ld_so_aix \$(CC)";; - IRIX/5*) LDSHARED="ld -shared";; - IRIX*/6*) LDSHARED="ld ${SGI_ABI} -shared -all";; - SunOS/4*) LDSHARED="ld";; - SunOS/5*) LDSHARED="ld -G";; - hp*|HP*) LDSHARED="ld -b";; - OSF*) LDSHARED="ld -shared -expect_unresolved \"*\"";; - DYNIX/ptx*) LDSHARED="ld -G";; - next/*) - if test "$ns_dyld" - then LDSHARED='$(CC) $(LDFLAGS) -bundle -prebind' - else LDSHARED='$(CC) $(CFLAGS) -nostdlib -r'; - fi - if test "$with_next_framework" ; then - LDSHARED="$LDSHARED \$(LDLIBRARY)" - fi ;; - Linux*) LDSHARED="gcc -shared";; - dgux*) LDSHARED="ld -G";; - FreeBSD*/3*) LDSHARED="gcc -shared";; - FreeBSD*|OpenBSD*) LDSHARED="ld -Bshareable";; - NetBSD*) - if [[ "`$CC -dM -E - ], , TCLINCLUDE="") -if test -z "$TCLINCLUDE"; then - dirs="$prefix/include /usr/local/include /usr/include /opt/local/include /home/sci/local/include" - for i in $dirs ; do - if test -r $i/tcl.h; then - AC_MSG_RESULT($i) - TCLINCLUDE="-I$i" - MAKETCL="tcl" - break - fi - done -fi -if test -z "$TCLINCLUDE"; then - TCLINCLUDE="" - MAKETCL="" - AC_MSG_RESULT(not found) -fi -else - AC_MSG_RESULT($TCLINCLUDE) -fi - -AC_SUBST(TCLINCLUDE) -AC_SUBST(MAKETCL) - -#---------------------------------------------------------------- -# Look for Python -#---------------------------------------------------------------- - -PYINCLUDE= -MAKEPYTHON= -PYLIB= -PYPACKAGE= - -AC_ARG_WITH(py,[ --with-py=path Set location of Python],[ - PYPACKAGE="$withval"], [PYPACKAGE=]) -AC_ARG_WITH(pyincl,[ --with-pyincl=path Set location of Python include directory],[ - PYINCLUDE="$withval"], [PYINCLUDE=]) -AC_ARG_WITH(pylib,[ --with-pylib=path Set location of Python library directory],[ - PYLIB="$withval"], [PYLIB=]) - -if test -z "$PYINCLUDE"; then - if test -n "$PYPACKAGE"; then - PYINCLUDE="$PYPACKAGE/include" - fi -fi - -if test -z "$PYLIB"; then - if test -n "$PYPACKAGE"; then - PYLIB="$PYPACKAGE/lib" - fi -fi - - -AC_MSG_CHECKING(for Python header files) - -dirs="$PYINCLUDE $PYINCLUDE/python2.0 $PYINCLUDE/python1.6 $PYINCLUDE/python1.5 $prefix/include/python2.0 $prefix/include/python1.6 $prefix/include/python1.5 /usr/local/include/python2.0 /usr/local/include/python1.6 /usr/local/include/python1.5 /usr/include/python1.5" -for i in $dirs ; do - if test -r $i/Python.h; then - AC_MSG_RESULT($i) - PYINCLUDE="-I$i" - MAKEPYTHON="python" - break - fi -done -if test -z "$PYINCLUDE"; then - PYINCLUDE="" - MAKEPYTHON="" - AC_MSG_RESULT(not found) -fi - -AC_SUBST(PYINCLUDE) -AC_SUBST(PYLINK) -AC_SUBST(MAKEPYTHON) - -#---------------------------------------------------------------- -# Look for Perl5 -#---------------------------------------------------------------- - -PERLBIN= -MAKEPERL= - -AC_ARG_WITH(perl5,[ --with-perl5=path Set location of Perl5 executable],[ PERLBIN="$withval"], [PERLBIN=]) - -# First figure out what the name of Perl5 is - -if test -z "$PERLBIN"; then -AC_CHECK_PROGS(PERL, perl5.004 perl5.003 perl5.002 perl5.001 perl5 perl) -else -PERL="$PERLBIN" -fi -AC_MSG_CHECKING(for Perl5 header files) -if test -n "$PERL"; then - PERL5DIR=`($PERL -e 'use Config; print $Config{archlib};') 2>/dev/null` - if test "$PERL5DIR" != ""; then - dirs="$PERL5DIR $PERL5DIR/CORE" - PERL5EXT=none - for i in $dirs; do - if test -r $i/perl.h; then - AC_MSG_RESULT($i) - PERL5EXT="-I$i" - MAKEPERL="perl" - break; - fi - done - if test "$PERL5EXT" = none; then - PERL5EXT="" - MAKEPERL="" - AC_MSG_RESULT(could not locate perl.h...using $PERL5EXT) - fi - else - AC_MSG_RESULT(unable to determine perl5 configuration) - PERL5EXT="" - MAKEPERL="" - fi - else - AC_MSG_RESULT(could not figure out how to run perl5) - PERL5EXT="" - MAKEPERL="" - fi - -AC_SUBST(PERL5EXT) -AC_SUBST(MAKEPERL) - -dnl We use the following in `AC_CONFIG_FILES' and "make distclean". -configure_substituted_files=`echo \ - Wad/Makefile \ - Python/Makefile \ - Tcl/Makefile \ - Test/Makefile \ - Prebuilt/linux/Makefile \ - Prebuilt/solaris/Makefile \ - Makefile \ -` -AC_SUBST(configure_substituted_files) - -AC_CONFIG_FILES([$configure_substituted_files]) -AC_OUTPUT - -dnl configure.in ends here - diff --git a/Tools/mkdist.py b/Tools/mkdist.py index 0e2eafa79..f2a04542c 100755 --- a/Tools/mkdist.py +++ b/Tools/mkdist.py @@ -1,7 +1,7 @@ #!/usr/bin/env python -# This script builds a swig-1.3 distribution. -# Usage : mkdist.py version, where version should be 1.3.x +# This script builds a swig-x.y.z distribution. +# Usage : mkdist.py version, where version should be x.y.z import sys import string @@ -16,7 +16,7 @@ try: version = sys.argv[1] dirname = "swig-" + version except: - print "Usage: mkdist.py version, where version should be 1.3.x" + print "Usage: mkdist.py version, where version should be x.y.z" sys.exit(1) # Check name matches normal unix conventions @@ -46,20 +46,22 @@ os.system("rm -Rf "+dirname+"/debian") == 0 or failed() # Go build the system print "Building system" -os.system("cd "+dirname+"; ./autogen.sh") == 0 or failed() -os.system("cd "+dirname+"/Tools/WAD; autoconf") == 0 or failed() -os.system("cd "+dirname+"/Source/CParse; bison -y -d parser.y; mv y.tab.c parser.c; mv y.tab.h parser.h") == 0 or failed() -os.system("cd "+dirname+"; make -f Makefile.in libfiles srcdir=./") == 0 or failed() +os.system("cd "+dirname+" && ./autogen.sh") == 0 or failed() +os.system("cd "+dirname+"/Source/CParse && bison -y -d parser.y && mv y.tab.c parser.c && mv y.tab.h parser.h") == 0 or failed() +os.system("cd "+dirname+" && make -f Makefile.in libfiles srcdir=./") == 0 or failed() # Remove autoconf files os.system("find "+dirname+" -name autom4te.cache -exec rm -rf {} \\;") # Build documentation -print "Building documentation" +print "Building html documentation" os.system("cd "+dirname+"/Doc/Manual && make all clean-baks") == 0 or failed() +print "Building man pages" os.system("cd "+dirname+"/CCache && yodl2man -o ccache-swig.1 ccache.yo") == 0 or failed() # Build the tar-ball os.system("tar -cf "+dirname+".tar "+dirname) == 0 or failed() os.system("gzip "+dirname+".tar") == 0 or failed() +print "Finished building "+dirname+".tar.gz" + diff --git a/Tools/mkrelease.py b/Tools/mkrelease.py index b719c470e..fc404d43f 100755 --- a/Tools/mkrelease.py +++ b/Tools/mkrelease.py @@ -18,7 +18,7 @@ try: username = sys.argv[2] except: print "Usage: python mkrelease.py version username" - print "where version should be 1.3.x and username is your SF username" + print "where version should be x.y.z and username is your SF username" sys.exit(1) print "Looking for rsync" @@ -37,11 +37,12 @@ swigwin_dir_sf = username + ",swig@frs.sourceforge.net:/home/frs/project/s/sw/sw release_notes_file = "release-notes-" + version + ".txt" os.system("rm -f " + release_notes_file) -os.system("cat swig-" + version + "/README " + "swig-" + version + "/CHANGES.current > " + release_notes_file) +os.system("cat swig-" + version + "/README " + "swig-" + version + "/CHANGES.current " + "swig-" + version + "/RELEASENOTES " + "> " + release_notes_file) os.system("rsync --archive --verbose -P --times -e ssh " + "swig-" + version + ".tar.gz " + release_notes_file + " " + swig_dir_sf) and failed("") os.system("rsync --archive --verbose -P --times -e ssh " + "swigwin-" + version + ".zip " + swigwin_dir_sf) and failed("") +print "Tagging release" os.system("svn copy -m \"rel-" + version + "\" https://swig.svn.sourceforge.net/svnroot/swig/trunk https://swig.svn.sourceforge.net/svnroot/swig/tags/rel-" + version + "/") print "Finished" diff --git a/Tools/mkwindows.sh b/Tools/mkwindows.sh index fb2547e14..869fce01a 100755 --- a/Tools/mkwindows.sh +++ b/Tools/mkwindows.sh @@ -1,6 +1,7 @@ #!/bin/sh -# Build Windows distribution (swigwin-1.3.x.zip) -- requires running in either: +# Build Windows distribution (swigwin-2.0.x.zip) from source tarball (swig-2.0.x.tar.gz) +# Requires running in either: # - MinGW environment # - Linux using MinGW cross compiler # - Cygwin using MinGW compiler @@ -21,8 +22,8 @@ if test x$1 != x; then fi else echo "Usage: mkwindows.sh version [zip]" - echo " Build Windows distribution. Works on Cygwin, MinGW or Linux" - echo " version should be 1.3.x" + echo " Build SWIG Windows distribution from source tarball. Works on Cygwin, MinGW or Linux" + echo " version should be 2.0.x" echo " zip is full path to zip program - default is /c/cygwin/bin/zip on MinGW, zip on Linux and Cygwin" exit 1 fi diff --git a/Tools/swig.spec.1 b/Tools/swig.spec.1 deleted file mode 100644 index 7af0440cd..000000000 --- a/Tools/swig.spec.1 +++ /dev/null @@ -1,42 +0,0 @@ -%define version 1.3.7 -%define release 1 - -# Preamble -Summary: Simplified Wrapper and Interface Generator -Name: swig -Version: %{version} -Release: %{release} -Copyright: BSD -URL: http://www.swig.org -Group: System Environment/Daemons -Source0: http://download.sourceforge.net/swig/swig-%{version}.tar.gz -Packager: Dustin Mitchell -BuildRoot: /var/tmp/rpm/swig-root -Prefix: /usr - -%description -SWIG is an interface compiler that connects programs written in C, -C++, and Objective-C with scripting languages including Perl, Python, -and Tcl/Tk. It works by taking the declarations commonly found in -C/C++ header files and using them to generate the glue code (wrappers) -that scripting languages need to access the underlying C/C++ code - -# PREP -%prep -%setup -n SWIG-%{version} - -# BUILD -%build -./configure --prefix=%prefix -make - -# INSTALL -%install -rm -rf ${RPM_BUILD_ROOT} -install -d -m 755 ${RPM_BUILD_ROOT} -make prefix=${RPM_BUILD_ROOT}%prefix install - -# FILES -%files -%prefix/lib/* -%prefix/bin/swig diff --git a/configure.in b/configure.in index 7e8b280cc..3e2f2beae 100644 --- a/configure.in +++ b/configure.in @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. dnl The macros which aren't shipped with the autotools are stored in the dnl Tools/config directory in .m4 files. -AC_INIT([swig],[2.0.0],[http://www.swig.org]) +AC_INIT([swig],[2.0.1],[http://www.swig.org]) AC_PREREQ(2.58) AC_CONFIG_SRCDIR([Source/Swig/swig.h]) AC_CONFIG_AUX_DIR([Tools/config]) @@ -1958,6 +1958,35 @@ fi AC_SUBST(RBIN) +#---------------------------------------------------------------- +# Look for Go compilers +#---------------------------------------------------------------- + +AC_ARG_WITH(go, AS_HELP_STRING([--without-go], [Disable Go]) +AS_HELP_STRING([--with-go=path], [Set location of Go compiler]),[GOBIN="$withval"], [GOBIN=yes]) + +if test x"${GOBIN}" = xno -o x"${with_alllang}" = xno ; then +AC_MSG_NOTICE([Disabling Go]) +GO= +GOGCC=false +else + + if test "x$GOBIN" = xyes; then + AC_CHECK_PROGS(GO, 6g 8g gccgo) + else + GO="$GOBIN" + fi + + GOGCC=false + if $GO --help 2>/dev/null | grep gccgo >/dev/null 2>&1 ; then + GOGCC=true + fi + +fi + +AC_SUBST(GOGCC) +AC_SUBST(GO) + #---------------------------------------------------------------- # Determine which languages to use for examples/test-suite #---------------------------------------------------------------- @@ -2108,6 +2137,12 @@ SKIP_UFFI= #fi AC_SUBST(SKIP_UFFI) +SKIP_GO= +if test -z "$GO" ; then + SKIP_GO="1" +fi +AC_SUBST(SKIP_GO) + #---------------------------------------------------------------- # Additional language dependencies #---------------------------------------------------------------- @@ -2186,6 +2221,7 @@ AC_CONFIG_FILES([ \ Examples/test-suite/cffi/Makefile \ Examples/test-suite/uffi/Makefile \ Examples/test-suite/r/Makefile \ + Examples/test-suite/go/Makefile \ Lib/ocaml/swigp4.ml ]) AC_CONFIG_FILES([preinst-swig], [chmod +x preinst-swig]) diff --git a/swig.spec.in b/swig.spec.in index 14d95d22f..0f64235fb 100644 --- a/swig.spec.in +++ b/swig.spec.in @@ -50,7 +50,7 @@ rm -rf ${RPM_BUILD_ROOT} %files %defattr(-,root,root) -%doc ANNOUNCE CHANGES FUTURE INSTALL LICENSE NEW README TODO +%doc ANNOUNCE CHANGES INSTALL LICENSE LICENSE-GPL LICENSE-UNIVERSITIES README RELEASENOTES %doc Doc/* %{_bindir}/* %{prefix}/share/*